Home | History | Annotate | Line # | Download | only in apps
bltgrid.c revision 1.1
      1 /*	$NetBSD: bltgrid.c,v 1.1 2018/08/16 18:17:47 jmcneill Exp $	*/
      2 
      3 #include <efi.h>
      4 #include <efilib.h>
      5 
      6 extern EFI_GUID GraphicsOutputProtocol;
      7 
      8 static void
      9 fill_boxes(UINT32 *PixelBuffer, UINT32 Width, UINT32 Height)
     10 {
     11 	UINT32 y, x = 0;
     12 	/*
     13 	 * This assums BGRR, but it doesn't really matter; we pick red and
     14 	 * green so it'll just be blue/green if the pixel format is backwards.
     15 	 */
     16 	EFI_GRAPHICS_OUTPUT_BLT_PIXEL Red = {0, 0, 0xff, 0},
     17 				      Green = {0, 0xff, 0, 0},
     18 				      *Color;
     19 
     20 	for (y = 0; y < Height; y++) {
     21 		Color = ((y / 32) % 2 == 0) ? &Red : &Green;
     22 		for (x = 0; x < Width; x++) {
     23 			if (x % 32 == 0 && x != 0)
     24 				Color = (Color == &Red) ? &Green : &Red;
     25 			PixelBuffer[y * Width + x] = *(UINT32 *)Color;
     26 		}
     27 	}
     28 }
     29 
     30 static void
     31 draw_boxes(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop)
     32 {
     33 	int i, imax;
     34 	EFI_STATUS rc;
     35 	EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
     36 	UINTN NumPixels;
     37 	UINT32 *PixelBuffer;
     38 	UINT32 BufferSize;
     39 
     40 	if (gop->Mode) {
     41 		imax = gop->Mode->MaxMode;
     42 	} else {
     43 		Print(L"gop->Mode is NULL\n");
     44 		return;
     45 	}
     46 
     47 	for (i = 0; i < imax; i++) {
     48 		UINTN SizeOfInfo;
     49 		rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i, &SizeOfInfo,
     50 					&info);
     51 		if (EFI_ERROR(rc) && rc == EFI_NOT_STARTED) {
     52 			Print(L"gop->QueryMode() returned %r\n", rc);
     53 			Print(L"Trying to start GOP with SetMode().\n");
     54 			rc = uefi_call_wrapper(gop->SetMode, 2, gop,
     55 				gop->Mode ? gop->Mode->Mode : 0);
     56 			rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i,
     57 				&SizeOfInfo, &info);
     58 		}
     59 
     60 		if (EFI_ERROR(rc)) {
     61 			Print(L"%d: Bad response from QueryMode: %r (%d)\n",
     62 			      i, rc, rc);
     63 			continue;
     64 		}
     65 
     66 		if (CompareMem(info, gop->Mode->Info, sizeof (*info)))
     67 			continue;
     68 
     69 		NumPixels = info->VerticalResolution * info->HorizontalResolution;
     70 		BufferSize = NumPixels * sizeof(UINT32);
     71 
     72 		PixelBuffer = AllocatePool(BufferSize);
     73 		if (!PixelBuffer) {
     74 			Print(L"Allocation of 0x%08lx bytes failed.\n",
     75 			      sizeof(UINT32) * NumPixels);
     76 			return;
     77 		}
     78 
     79 		fill_boxes(PixelBuffer,
     80 			   info->HorizontalResolution, info->VerticalResolution);
     81 
     82 		uefi_call_wrapper(gop->Blt, 10, gop,
     83 				  (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)PixelBuffer,
     84 				  EfiBltBufferToVideo,
     85 				  0, 0, 0, 0,
     86 				  info->HorizontalResolution,
     87 				  info->VerticalResolution,
     88 				  0);
     89 		return;
     90 	}
     91 	Print(L"Never found the active video mode?\n");
     92 }
     93 
     94 static EFI_STATUS
     95 SetWatchdog(UINTN seconds)
     96 {
     97 	EFI_STATUS rc;
     98 	rc = uefi_call_wrapper(BS->SetWatchdogTimer, 4, seconds, 0x1ffff,
     99 				0, NULL);
    100 	if (EFI_ERROR(rc)) {
    101 		CHAR16 Buffer[64];
    102 		StatusToString(Buffer, rc);
    103 		Print(L"Bad response from QueryMode: %s (%d)\n", Buffer, rc);
    104 	}
    105 	return rc;
    106 }
    107 
    108 EFI_STATUS
    109 efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
    110 {
    111 	EFI_STATUS rc;
    112 	EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
    113 
    114 	InitializeLib(image_handle, systab);
    115 
    116 	SetWatchdog(10);
    117 
    118 	rc = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&gop);
    119 	if (EFI_ERROR(rc)) {
    120 		Print(L"Could not locate GOP: %r\n", rc);
    121 		return rc;
    122 	}
    123 
    124 	if (!gop) {
    125 		Print(L"LocateProtocol(GOP, &gop) returned %r but GOP is NULL\n", rc);
    126 		return EFI_UNSUPPORTED;
    127 	}
    128 
    129 	draw_boxes(gop);
    130 
    131 	SetWatchdog(0);
    132 	return EFI_SUCCESS;
    133 }
    134