Home | History | Annotate | Line # | Download | only in apps
      1 /*	$NetBSD: bltgrid.c,v 1.1.1.2 2021/09/30 18:50:09 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 (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 		FreePool(PixelBuffer);
     90 		return;
     91 	}
     92 	Print(L"Never found the active video mode?\n");
     93 }
     94 
     95 static EFI_STATUS
     96 SetWatchdog(UINTN seconds)
     97 {
     98 	EFI_STATUS rc;
     99 	rc = uefi_call_wrapper(BS->SetWatchdogTimer, 4, seconds, 0x1ffff,
    100 				0, NULL);
    101 	if (EFI_ERROR(rc)) {
    102 		CHAR16 Buffer[64];
    103 		StatusToString(Buffer, rc);
    104 		Print(L"Bad response from QueryMode: %s (%d)\n", Buffer, rc);
    105 	}
    106 	return rc;
    107 }
    108 
    109 EFI_STATUS
    110 efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
    111 {
    112 	EFI_STATUS rc;
    113 	EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
    114 
    115 	InitializeLib(image_handle, systab);
    116 
    117 	SetWatchdog(10);
    118 
    119 	rc = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&gop);
    120 	if (EFI_ERROR(rc)) {
    121 		Print(L"Could not locate GOP: %r\n", rc);
    122 		return rc;
    123 	}
    124 
    125 	if (!gop) {
    126 		Print(L"LocateProtocol(GOP, &gop) returned %r but GOP is NULL\n", rc);
    127 		return EFI_UNSUPPORTED;
    128 	}
    129 
    130 	draw_boxes(gop);
    131 
    132 	SetWatchdog(0);
    133 	return EFI_SUCCESS;
    134 }
    135