5 int find_best_video_mode(void);
6 int find_video_mode(int xres, int yres, int bpp);
7 int set_video_mode(int mode);
8 int cur_video_mode(void);
9 void draw_box(int x, int y, int w, int h, int r, int g, int b);
10 int mask_to_shift(unsigned int mask);
11 int mask_to_bpp(unsigned int mask);
12 int mode_bpp(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *minf);
15 int fb_width, fb_height;
17 int rshift, bshift, gshift;
18 unsigned int rmask, bmask, gmask;
19 EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
21 EFI_STATUS EFIAPI efi_main(EFI_HANDLE img, EFI_SYSTEM_TABLE *systab)
25 unsigned long nhandles = 0;
27 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mi;
28 SIMPLE_TEXT_OUTPUT_INTERFACE *sout;
30 InitializeLib(img, systab);
32 sout = systab->ConOut;
33 uefi_call_wrapper(sout->ClearScreen, 1, sout);
34 Print(L"hello world\n");
36 LibLocateHandle(ByProtocol, &GraphicsOutputProtocol, 0, &nhandles, 0);
38 Print(L"Failed to locate any graphics output devices\n");
41 if(!(handles = AllocatePool(nhandles))) {
42 Print(L"Failed to allocate memory for %lu handles\n", nhandles);
45 Print(L"Found %lu graphics output devices\n", nhandles);
46 if(LibLocateHandle(ByProtocol, &GraphicsOutputProtocol, 0, &nhandles, &handles) != 0) {
47 Print(L"Failed to retreive graphics output device handles\n");
50 if(uefi_call_wrapper(BS->HandleProtocol, 3, handles[0], &GraphicsOutputProtocol, &gop) != 0) {
51 Print(L"Failed to retreive graphics output protocol structure\n");
56 if((mode = find_best_video_mode()) == -1) {
57 Print(L"Failed to find best video mode, leaving as is\n");
59 if(set_video_mode(mode) == -1) {
60 Print(L"Failed to change video mode, leaving as is\n");
63 uefi_call_wrapper(gop->QueryMode, 4, gop, gop->Mode->Mode, &misize, &mi);
65 fb_width = mi->HorizontalResolution;
66 fb_height = mi->VerticalResolution;
67 scanwidth = mi->PixelsPerScanLine;
69 switch(mi->PixelFormat) {
70 case PixelRedGreenBlueReserved8BitPerColor:
79 case PixelBlueGreenRedReserved8BitPerColor:
89 rmask = mi->PixelInformation.RedMask;
90 gmask = mi->PixelInformation.GreenMask;
91 bmask = mi->PixelInformation.BlueMask;
92 rshift = mask_to_shift(rmask);
93 gshift = mask_to_shift(gmask);
94 bshift = mask_to_shift(bmask);
98 Print(L"Unsupported pixel format\n");
101 fb = (uint32_t*)gop->Mode->FrameBufferBase;
103 Print(L"Video mode %ux%u %dbpp (fmt id: %u)\n", mi->HorizontalResolution,
104 mi->VerticalResolution, mask_to_bpp(rmask | gmask | bmask), (unsigned int)mi->PixelFormat);
106 draw_box(100, 100, 200, 200, 255, 128, 64);
117 static uint32_t calc_score(int x, int y, int bpp)
122 if(a > 0xfff) a = 0xfff;
123 if(b > 0xfff) b = 0xfff;
125 return (a << 20) | (b << 8) | (bpp & 0xff);
128 int find_best_video_mode(void)
131 int score, best_score = 0, best_mode = -1;
132 unsigned long misize;
133 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mi;
135 nmodes = gop->Mode->MaxMode;
136 for(i=0; i<nmodes; i++) {
137 uefi_call_wrapper(gop->QueryMode, 4, gop, i, &misize, &mi);
138 w = mi->HorizontalResolution;
139 h = mi->VerticalResolution;
141 score = calc_score(w, h, mode_bpp(mi));
142 if(score > best_score) {
150 int find_video_mode(int xres, int yres, int bpp)
153 unsigned long misize;
154 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mi;
156 nmodes = gop->Mode->MaxMode;
157 for(i=0; i<nmodes; i++) {
158 uefi_call_wrapper(gop->QueryMode, 4, gop, i, &misize, &mi);
159 w = mi->HorizontalResolution;
160 h = mi->VerticalResolution;
161 if(w == xres && h == yres && mode_bpp(mi) >= bpp) {
168 int set_video_mode(int mode)
170 if(uefi_call_wrapper(gop->SetMode, 2, gop, mode) != 0) {
176 int cur_video_mode(void)
178 return gop->Mode->Mode;
181 void draw_box(int x, int y, int w, int h, int r, int g, int b)
185 uint32_t *pptr = fb + y * scanwidth + x;
187 pixcol = (((uint32_t)r << rshift) & rmask) |
188 (((uint32_t)g << gshift) & gmask) |
189 (((uint32_t)b << bshift) & bmask);
195 pptr += scanwidth - w;
199 int mask_to_shift(unsigned int mask)
202 while((mask & 1) == 0) {
209 int mask_to_bpp(unsigned int mask)
220 int mode_bpp(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *minf)
222 switch(minf->PixelFormat) {
223 case PixelRedGreenBlueReserved8BitPerColor:
224 case PixelBlueGreenRedReserved8BitPerColor:
228 return mask_to_bpp(minf->PixelInformation.RedMask | minf->PixelInformation.GreenMask |
229 minf->PixelInformation.BlueMask);