bltgrid.c revision 1.1.1.2 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