From 93cc3735b50cfa8d0f9a47fa1e2e0a06adea9d9b Mon Sep 17 00:00:00 2001 From: Regina König Date: Mon, 3 Aug 2020 15:26:17 +0200 Subject: application to test EFI_GRAPHICS_OUTPUT_PROTOCOL --- memtestEDK/MdeModulePkg.dsc | 1 + .../GraphicsOutput/GraphicsOutputProtocol.c | 160 +++++++++ .../GraphicsOutput/GraphicsOutputProtocol.inf | 32 ++ memtestEDK/Memtest/GraphicsOutput/screenmodes.c | 395 +++++++++++++++++++++ memtestEDK/Memtest/GraphicsOutput/screenmodes.inf | 32 ++ memtestEDK/Memtest/Template/Template.c | 18 + memtestEDK/Memtest/Template/Template.inf | 32 ++ memtestEDK/Memtest/run.sh | 2 +- 8 files changed, 671 insertions(+), 1 deletion(-) create mode 100644 memtestEDK/Memtest/GraphicsOutput/GraphicsOutputProtocol.c create mode 100644 memtestEDK/Memtest/GraphicsOutput/GraphicsOutputProtocol.inf create mode 100644 memtestEDK/Memtest/GraphicsOutput/screenmodes.c create mode 100644 memtestEDK/Memtest/GraphicsOutput/screenmodes.inf create mode 100644 memtestEDK/Memtest/Template/Template.c create mode 100644 memtestEDK/Memtest/Template/Template.inf (limited to 'memtestEDK') diff --git a/memtestEDK/MdeModulePkg.dsc b/memtestEDK/MdeModulePkg.dsc index c56162f..4f2e097 100644 --- a/memtestEDK/MdeModulePkg.dsc +++ b/memtestEDK/MdeModulePkg.dsc @@ -211,6 +211,7 @@ Memtest/SingleComponents/TestConfig.inf Memtest/SingleComponents/TestSmp.inf Memtest/GetRootSystemDescriptionPointer/GetRootSystemDescriptionPointer.inf + Memtest/GraphicsOutput/GraphicsOutputProtocol.inf # MdeModulePkg/Application/HelloWorld/HelloWorld.inf # MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf diff --git a/memtestEDK/Memtest/GraphicsOutput/GraphicsOutputProtocol.c b/memtestEDK/Memtest/GraphicsOutput/GraphicsOutputProtocol.c new file mode 100644 index 0000000..e2e661b --- /dev/null +++ b/memtestEDK/Memtest/GraphicsOutput/GraphicsOutputProtocol.c @@ -0,0 +1,160 @@ +#include + +#include +#include +#include +#include + + + +static int +memcmp(const void *s1, const void *s2, UINTN n) +{ + const unsigned char *c1 = s1, *c2 = s2; + int d = 0; + + if (!s1 && !s2) + return 0; + if (s1 && !s2) + return 1; + if (!s1 && s2) + return -1; + + while (n--) { + d = (int)*c1++ - (int)*c2++; + if (d) + break; + } + + return d; +} + +EFI_STATUS +PrintGOP(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) +{ + int i, imax; + EFI_STATUS Status; + + imax = gop->Mode->MaxMode; + + Print(L"GOP reports MaxMode %d\n", imax); + + for (i = 0; i < imax; i++) { + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + UINTN SizeOfInfo; + + Status = gop->QueryMode(gop, i, &SizeOfInfo, &Info); + if (EFI_ERROR(Status) && Status == EFI_NOT_STARTED) { + gop->SetMode(gop, gop->Mode->Mode); + Status = gop->QueryMode(gop, i, &SizeOfInfo, &Info); + } + + if (EFI_ERROR(Status)) { + Print(L"ERROR: Bad response from QueryMode: %d\n", Status); + continue; + } + Print(L"%c%d: %dx%d ", memcmp(Info,gop->Mode->Info,sizeof(*Info)) == 0 ? '*' : ' ', i, + Info->HorizontalResolution, + Info->VerticalResolution); + switch(Info->PixelFormat) { + case PixelRedGreenBlueReserved8BitPerColor: + Print(L"RGBRerserved"); + break; + case PixelBlueGreenRedReserved8BitPerColor: + Print(L"BGRReserved"); + break; + case PixelBitMask: + Print(L"Red:%08x Green:%08x Blue:%08x Reserved:%08x", + Info->PixelInformation.RedMask, + Info->PixelInformation.GreenMask, + Info->PixelInformation.BlueMask, + Info->PixelInformation.ReservedMask); + break; + case PixelBltOnly: + Print(L"(blt only)"); + break; + default: + Print(L"(Invalid pixel format)"); + break; + } + Print(L" Pixels %d\n", Info->PixelsPerScanLine); + } + Print(L"\n"); + + return EFI_SUCCESS; +} + + +EFI_STATUS +CheckGOP(BOOLEAN Verbose, IN EFI_SYSTEM_TABLE *gST, IN EFI_BOOT_SERVICES *gBS) +{ + EFI_HANDLE *HandleBuffer = NULL; + UINTN HandleCount = 0; + EFI_STATUS Status = EFI_SUCCESS; + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; + + + // get from ConsoleOutHandle? + Status = gBS->HandleProtocol( gST->ConsoleOutHandle, + &gEfiGraphicsOutputProtocolGuid, + (VOID **) &Gop); + if (EFI_ERROR (Status)) { + Print(L"No GOP handle found via HandleProtocol\n"); + } else { + Print(L"GOP handle found via HandleProtocol\n"); + if (Verbose) + PrintGOP(Gop); + } + + // try locating directly + Status = gBS->LocateProtocol( &gEfiGraphicsOutputProtocolGuid, + NULL, + (VOID **) &Gop); + if (EFI_ERROR(Status) || Gop == NULL) { + Print(L"No GOP handle found via LocateProtocol\n"); + } else { + Print(L"Found GOP handle via LocateProtocol\n"); + if (Verbose) + PrintGOP(Gop); + } + + // try locating by handle + Status = gBS->LocateHandleBuffer( ByProtocol, + &gEfiGraphicsOutputProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer); + if (EFI_ERROR (Status)) { + Print(L"No GOP handles found via LocateHandleBuffer\n"); + } else { + Print(L"Found %d GOP handles via LocateHandleBuffer\n", HandleCount); + for (int i = 0; i < HandleCount; i++) { + Status = gBS->HandleProtocol( HandleBuffer[i], + &gEfiGraphicsOutputProtocolGuid, + (VOID*) &Gop); + if (!EFI_ERROR (Status)) { + if (Verbose) + PrintGOP(Gop); + } + } + gBS->FreePool(HandleBuffer); + } + + Print(L"\n"); + + return Status; +} + +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + + CheckGOP(TRUE, SystemTable, SystemTable->BootServices); + + return EFI_SUCCESS; + +} \ No newline at end of file diff --git a/memtestEDK/Memtest/GraphicsOutput/GraphicsOutputProtocol.inf b/memtestEDK/Memtest/GraphicsOutput/GraphicsOutputProtocol.inf new file mode 100644 index 0000000..9824678 --- /dev/null +++ b/memtestEDK/Memtest/GraphicsOutput/GraphicsOutputProtocol.inf @@ -0,0 +1,32 @@ +[Defines] + INF_VERSION = 1.25 + BASE_NAME = GraphicsOutputProtocol + FILE_GUID = d57abf7c-b511-4aaa-ab9e-2720fca82934 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = UefiMain +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC Etc... +# + +[Sources] + GraphicsOutputProtocol.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + +[Guids] + +[Ppis] + +[Protocols] + +[FeaturePcd] + +[Pcd] \ No newline at end of file diff --git a/memtestEDK/Memtest/GraphicsOutput/screenmodes.c b/memtestEDK/Memtest/GraphicsOutput/screenmodes.c new file mode 100644 index 0000000..c329c8f --- /dev/null +++ b/memtestEDK/Memtest/GraphicsOutput/screenmodes.c @@ -0,0 +1,395 @@ +// +// Copyright (c) 2015 Finnbarr P. Murphy. All rights reserved. +// +// Display TEXT and GRAPHIC screen mode information +// +// License: BSD License +// + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "ConsoleControl.h" +#include "UgaDraw.h" + + +static int +memcmp(const void *s1, const void *s2, UINTN n) +{ + const unsigned char *c1 = s1, *c2 = s2; + int d = 0; + + if (!s1 && !s2) + return 0; + if (s1 && !s2) + return 1; + if (!s1 && s2) + return -1; + + while (n--) { + d = (int)*c1++ - (int)*c2++; + if (d) + break; + } + + return d; +} + + +EFI_STATUS +PrintUGA(EFI_UGA_DRAW_PROTOCOL *Uga) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 HorzResolution = 0; + UINT32 VertResolution = 0; + UINT32 ColorDepth = 0; + UINT32 RefreshRate = 0; + + + Status = Uga->GetMode( Uga, &HorzResolution, &VertResolution, + &ColorDepth, &RefreshRate); + + if (EFI_ERROR (Status)) { + Print(L"ERROR: UGA GetMode failed [%d]\n", Status ); + } else { + Print(L"Horizontal Resolution: %d\n", HorzResolution); + Print(L"Vertical Resolution: %d\n", VertResolution); + Print(L"Color Depth: %d\n", ColorDepth); + Print(L"Refresh Rate: %d\n", RefreshRate); + Print(L"\n"); + } + + return Status; +} + + +EFI_STATUS +CheckUGA(BOOLEAN Verbose) +{ + EFI_HANDLE *HandleBuffer = NULL; + UINTN HandleCount = 0; + EFI_STATUS Status = EFI_SUCCESS; + EFI_UGA_DRAW_PROTOCOL *Uga; + + + // get from ConsoleOutHandle? + Status = gBS->HandleProtocol( gST->ConsoleOutHandle, + &gEfiUgaDrawProtocolGuid, + (VOID **) &Uga); + if (EFI_ERROR (Status)) { + Print(L"No UGA handle found via HandleProtocol\n"); + } else { + Print(L"UGA handle found via HandleProtocol\n"); + if (Verbose) + PrintUGA(Uga); + } + + // try locating directly + Status = gBS->LocateProtocol( &gEfiUgaDrawProtocolGuid, + NULL, + (VOID **) &Uga); + if (EFI_ERROR(Status) || Uga == NULL) { + Print(L"No UGA handle found via LocateProtocol\n"); + } else { + Print(L"Found UGA handle via LocateProtocol\n"); + if (Verbose) + PrintUGA(Uga); + } + + // try locating by handle + Status = gBS->LocateHandleBuffer( ByProtocol, + &gEfiUgaDrawProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer); + if (EFI_ERROR (Status)) { + Print(L"No UGA handles found via LocateHandleBuffer\n"); + } else { + Print(L"Found %d UGA handles via LocateHandleBuffer\n", HandleCount); + for (int i = 0; i < HandleCount; i++) { + Status = gBS->HandleProtocol( HandleBuffer[i], + &gEfiUgaDrawProtocolGuid, + (VOID*) &Uga); + if (!EFI_ERROR (Status)) { + if (Verbose) + PrintUGA(Uga); + } + } + FreePool(HandleBuffer); + } + + Print(L"\n"); + + return Status; +} + + +EFI_STATUS +PrintGOP(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) +{ + int i, imax; + EFI_STATUS Status; + + imax = gop->Mode->MaxMode; + + Print(L"GOP reports MaxMode %d\n", imax); + + for (i = 0; i < imax; i++) { + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + UINTN SizeOfInfo; + + Status = gop->QueryMode(gop, i, &SizeOfInfo, &Info); + if (EFI_ERROR(Status) && Status == EFI_NOT_STARTED) { + gop->SetMode(gop, gop->Mode->Mode); + Status = gop->QueryMode(gop, i, &SizeOfInfo, &Info); + } + + if (EFI_ERROR(Status)) { + Print(L"ERROR: Bad response from QueryMode: %d\n", Status); + continue; + } + Print(L"%c%d: %dx%d ", memcmp(Info,gop->Mode->Info,sizeof(*Info)) == 0 ? '*' : ' ', i, + Info->HorizontalResolution, + Info->VerticalResolution); + switch(Info->PixelFormat) { + case PixelRedGreenBlueReserved8BitPerColor: + Print(L"RGBRerserved"); + break; + case PixelBlueGreenRedReserved8BitPerColor: + Print(L"BGRReserved"); + break; + case PixelBitMask: + Print(L"Red:%08x Green:%08x Blue:%08x Reserved:%08x", + Info->PixelInformation.RedMask, + Info->PixelInformation.GreenMask, + Info->PixelInformation.BlueMask, + Info->PixelInformation.ReservedMask); + break; + case PixelBltOnly: + Print(L"(blt only)"); + break; + default: + Print(L"(Invalid pixel format)"); + break; + } + Print(L" Pixels %d\n", Info->PixelsPerScanLine); + } + Print(L"\n"); + + return EFI_SUCCESS; +} + + +EFI_STATUS +CheckGOP(BOOLEAN Verbose) +{ + EFI_HANDLE *HandleBuffer = NULL; + UINTN HandleCount = 0; + EFI_STATUS Status = EFI_SUCCESS; + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; + + + // get from ConsoleOutHandle? + Status = gBS->HandleProtocol( gST->ConsoleOutHandle, + &gEfiGraphicsOutputProtocolGuid, + (VOID **) &Gop); + if (EFI_ERROR (Status)) { + Print(L"No GOP handle found via HandleProtocol\n"); + } else { + Print(L"GOP handle found via HandleProtocol\n"); + if (Verbose) + PrintGOP(Gop); + } + + // try locating directly + Status = gBS->LocateProtocol( &gEfiGraphicsOutputProtocolGuid, + NULL, + (VOID **) &Gop); + if (EFI_ERROR(Status) || Gop == NULL) { + Print(L"No GOP handle found via LocateProtocol\n"); + } else { + Print(L"Found GOP handle via LocateProtocol\n"); + if (Verbose) + PrintGOP(Gop); + } + + // try locating by handle + Status = gBS->LocateHandleBuffer( ByProtocol, + &gEfiGraphicsOutputProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer); + if (EFI_ERROR (Status)) { + Print(L"No GOP handles found via LocateHandleBuffer\n"); + } else { + Print(L"Found %d GOP handles via LocateHandleBuffer\n", HandleCount); + for (int i = 0; i < HandleCount; i++) { + Status = gBS->HandleProtocol( HandleBuffer[i], + &gEfiGraphicsOutputProtocolGuid, + (VOID*) &Gop); + if (!EFI_ERROR (Status)) { + if (Verbose) + PrintGOP(Gop); + } + } + FreePool(HandleBuffer); + } + + Print(L"\n"); + + return Status; +} + + +EFI_STATUS +PrintCCP(EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_CONSOLE_CONTROL_SCREEN_MODE Mode; + BOOLEAN GopUgaExists; + BOOLEAN StdInLocked; + + Status = ConsoleControl->GetMode(ConsoleControl, &Mode, &GopUgaExists, &StdInLocked); + if (EFI_ERROR (Status)) { + Print(L"ERROR: ConsoleControl GetMode failed [%d]\n", Status ); + return Status; + } + + Print(L"Screen mode: "); + switch (Mode) { + case EfiConsoleControlScreenText: + Print(L"Text"); + break; + case EfiConsoleControlScreenGraphics: + Print(L"Graphics"); + break; + case EfiConsoleControlScreenMaxValue: + Print(L"MaxValue"); + break; + } + Print(L"\n"); + Print(L"Graphics Support Avalaiable: "); + if (GopUgaExists) + Print(L"Yes"); + else + Print(L"No"); + Print(L"\n"); + + Print(L"\n"); + + return EFI_SUCCESS; +} + + +EFI_STATUS +CheckCCP(BOOLEAN Verbose) +{ + EFI_GUID gEfiConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; + EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; + EFI_HANDLE *HandleBuffer = NULL; + UINTN HandleCount = 0; + EFI_STATUS Status = EFI_SUCCESS; + + // get from ConsoleOutHandle? + Status = gBS->HandleProtocol( gST->ConsoleOutHandle, + &gEfiConsoleControlProtocolGuid, + (VOID **) &ConsoleControl); + if (EFI_ERROR (Status)) { + Print(L"No ConsoleControl handle found via HandleProtocol\n"); + } else { + Print(L"ConsoleControl handle found via HandleProtocol\n"); + if (Verbose) + PrintCCP(ConsoleControl); + } + + // try locating directly + Status = gBS->LocateProtocol( &gEfiConsoleControlProtocolGuid, + NULL, + (VOID **) &ConsoleControl); + if (EFI_ERROR(Status) || ConsoleControl == NULL) { + Print(L"No ConsoleControl handle found via LocateProtocol\n"); + } else { + Print(L"Found ConsoleControl handle via LocateProtocol\n"); + if (Verbose) + PrintCCP(ConsoleControl); + } + + // try locating by handle + Status = gBS->LocateHandleBuffer( ByProtocol, + &gEfiConsoleControlProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer); + if (EFI_ERROR (Status)) { + Print(L"No ConsoleControl handles found via LocateHandleBuffer\n"); + } else { + Print(L"Found %d ConsoleControl handles via LocateHandleBuffer\n", HandleCount); + for (int i = 0; i < HandleCount; i++) { + Status = gBS->HandleProtocol( HandleBuffer[i], + &gEfiConsoleControlProtocolGuid, + (VOID*) &ConsoleControl); + if (!EFI_ERROR (Status)) + if (Verbose) + PrintCCP(ConsoleControl); + } + FreePool(HandleBuffer); + } + + Print(L"\n"); + + return Status; +} + + + +static void +Usage(void) +{ + Print(L"Usage: screenmodes [-v|--verbose]\n"); +} + + +INTN +EFIAPI +ShellAppMain(UINTN Argc, CHAR16 **Argv) +{ + EFI_STATUS Status = EFI_SUCCESS; + BOOLEAN Verbose = FALSE; + + if (Argc == 2) { + if (!StrCmp(Argv[1], L"--verbose") || + !StrCmp(Argv[1], L"-v")) { + Verbose = TRUE; + } + if (!StrCmp(Argv[1], L"--help") || + !StrCmp(Argv[1], L"-h") || + !StrCmp(Argv[1], L"-?")) { + Usage(); + return Status; + } + } + + + // First check for older EDK ConsoleControl protocol support + CheckCCP(Verbose); + + // Next check for UGA support (probably none) + CheckUGA(Verbose); + + // Finally check for GOP support + CheckGOP(Verbose); + + return Status; +} \ No newline at end of file diff --git a/memtestEDK/Memtest/GraphicsOutput/screenmodes.inf b/memtestEDK/Memtest/GraphicsOutput/screenmodes.inf new file mode 100644 index 0000000..2085e51 --- /dev/null +++ b/memtestEDK/Memtest/GraphicsOutput/screenmodes.inf @@ -0,0 +1,32 @@ +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = screenmodes + FILE_GUID = 4ea87c51-7795-4dcd-0055-747010f3ce51 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 0.1 + ENTRY_POINT = ShellCEntryLib + VALID_ARCHITECTURES = X64 + +[Sources] + screenmodes.c + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + + +[LibraryClasses] + ShellCEntryLib + ShellLib + BaseLib + BaseMemoryLib + UefiLib + +[Protocols] + +[BuildOptions] + +[Pcd] + + +# Read more: https://blog.fpmurphy.com/2015/05/check-available-text-and-graphics-modes-from-uefi-shell.html#ixzz6U2wHFOfc diff --git a/memtestEDK/Memtest/Template/Template.c b/memtestEDK/Memtest/Template/Template.c new file mode 100644 index 0000000..723d7d9 --- /dev/null +++ b/memtestEDK/Memtest/Template/Template.c @@ -0,0 +1,18 @@ +#include + +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + + return EFI_SUCCESS; + +} \ No newline at end of file diff --git a/memtestEDK/Memtest/Template/Template.inf b/memtestEDK/Memtest/Template/Template.inf new file mode 100644 index 0000000..0d31854 --- /dev/null +++ b/memtestEDK/Memtest/Template/Template.inf @@ -0,0 +1,32 @@ +[Defines] + INF_VERSION = 1.25 + BASE_NAME = Template + FILE_GUID = https://www.guidgenerator.com/online-guid-generator.aspx + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = UefiMain +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC Etc... +# + +[Sources] + Template.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + +[Guids] + +[Ppis] + +[Protocols] + +[FeaturePcd] + +[Pcd] diff --git a/memtestEDK/Memtest/run.sh b/memtestEDK/Memtest/run.sh index 6d98a65..fb605af 100755 --- a/memtestEDK/Memtest/run.sh +++ b/memtestEDK/Memtest/run.sh @@ -3,7 +3,7 @@ (cd ..;. edksetup.sh BaseTools; build -a X64 -p MdeModulePkg/MdeModulePkg.dsc) if [ $? -ne 0 ]; then exit 1; fi -(cd ..; cp Build/MdeModule/DEBUG_GCC5/X64/ProtocolInformation.efi ../../git/working_dir/memtest86/test_code/hda-contents/) +(cd ..; cp Build/MdeModule/DEBUG_GCC5/X64/GraphicsOutputProtocol.efi ../../git/working_dir/memtest86/test_code/hda-contents/) if [ $? -ne 0 ]; then exit 1; fi (cd ../../../git/working_dir/memtest86/test_code; sudo ./run.sh ) -- cgit v1.2.3-55-g7522