1 #include <efi.h>
2 #include <efilib.h>
3 
4 extern EFI_GUID GraphicsOutputProtocol;
5 
memcmp(const void * s1,const void * s2,UINTN n)6 static int memcmp(const void *s1, const void *s2, UINTN n)
7 {
8 	const unsigned char *c1 = s1, *c2 = s2;
9 	int d = 0;
10 
11 	if (!s1 && !s2)
12 		return 0;
13 	if (s1 && !s2)
14 		return 1;
15 	if (!s1 && s2)
16 		return -1;
17 
18 	while (n--) {
19 		d = (int)*c1++ - (int)*c2++;
20 		if (d)
21 			break;
22 	}
23 	return d;
24 }
25 
26 static void
print_modes(EFI_GRAPHICS_OUTPUT_PROTOCOL * gop)27 print_modes(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop)
28 {
29 	int i, imax;
30 	EFI_STATUS rc;
31 
32 	imax = gop->Mode->MaxMode;
33 
34 	Print(L"GOP reports MaxMode %d\n", imax);
35 	for (i = 0; i < imax; i++) {
36 		EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
37 		UINTN SizeOfInfo;
38 		rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i, &SizeOfInfo,
39 					&info);
40 		if (EFI_ERROR(rc) && rc == EFI_NOT_STARTED) {
41 			rc = uefi_call_wrapper(gop->SetMode, 2, gop,
42 				gop->Mode->Mode);
43 			rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i,
44 				&SizeOfInfo, &info);
45 		}
46 
47 		if (EFI_ERROR(rc)) {
48 			CHAR16 Buffer[64];
49 			StatusToString(Buffer, rc);
50 			Print(L"%d: Bad response from QueryMode: %s (%d)\n",
51 				i, Buffer, rc);
52 			continue;
53 		}
54 		Print(L"%c%d: %dx%d ", memcmp(info,gop->Mode->Info,sizeof(*info)) == 0 ? '*' : ' ', i,
55 			info->HorizontalResolution,
56 			info->VerticalResolution);
57 		switch(info->PixelFormat) {
58 			case PixelRedGreenBlueReserved8BitPerColor:
59 				Print(L"RGBR");
60 				break;
61 			case PixelBlueGreenRedReserved8BitPerColor:
62 				Print(L"BGRR");
63 				break;
64 			case PixelBitMask:
65 				Print(L"R:%08x G:%08x B:%08x X:%08x",
66 					info->PixelInformation.RedMask,
67 					info->PixelInformation.GreenMask,
68 					info->PixelInformation.BlueMask,
69 					info->PixelInformation.ReservedMask);
70 				break;
71 			case PixelBltOnly:
72 				Print(L"(blt only)");
73 				break;
74 			default:
75 				Print(L"(Invalid pixel format)");
76 				break;
77 		}
78 		Print(L" pitch %d\n", info->PixelsPerScanLine);
79 	}
80 }
81 
82 static EFI_STATUS
SetWatchdog(UINTN seconds)83 SetWatchdog(UINTN seconds)
84 {
85 	EFI_STATUS rc;
86 	rc = uefi_call_wrapper(BS->SetWatchdogTimer, 4, seconds, 0x1ffff,
87 				0, NULL);
88 	if (EFI_ERROR(rc)) {
89 		CHAR16 Buffer[64];
90 		StatusToString(Buffer, rc);
91 		Print(L"Bad response from QueryMode: %s (%d)\n", Buffer, rc);
92 	}
93 	return rc;
94 }
95 
96 EFI_STATUS
efi_main(EFI_HANDLE image_handle,EFI_SYSTEM_TABLE * systab)97 efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
98 {
99 	EFI_STATUS rc;
100 	EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
101 
102 	InitializeLib(image_handle, systab);
103 
104 	SetWatchdog(10);
105 
106 	rc = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&gop);
107 	if (EFI_ERROR(rc))
108 		return rc;
109 
110 	print_modes(gop);
111 
112 	SetWatchdog(0);
113 	return EFI_SUCCESS;
114 }
115