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