xref: /haiku/src/system/boot/platform/efi/video.cpp (revision 7bdeef54a24d3417300f251af891df962b638b9b)
1 /*
2  * Copyright 2016, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <boot/kernel_args.h>
8 #include <boot/platform.h>
9 #include <boot/platform/generic/video.h>
10 #include <boot/stage2.h>
11 
12 #include "efi_platform.h"
13 
14 
15 static EFI_GUID sGraphicsOutputGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
16 static EFI_GRAPHICS_OUTPUT_PROTOCOL *sGraphicsOutput;
17 static UINTN sGraphicsMode;
18 
19 
20 extern "C" status_t
21 platform_init_video(void)
22 {
23 	EFI_STATUS status = kBootServices->LocateProtocol(&sGraphicsOutputGuid,
24 		NULL, (void **)&sGraphicsOutput);
25 	if (sGraphicsOutput == NULL || status != EFI_SUCCESS) {
26 		gKernelArgs.frame_buffer.enabled = false;
27 		sGraphicsOutput = NULL;
28 		return B_ERROR;
29 	}
30 
31 	UINTN bestArea = 0;
32 	UINTN bestDepth = 0;
33 
34 	for (UINTN mode = 0; mode < sGraphicsOutput->Mode->MaxMode; ++mode) {
35 		EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
36 		UINTN size, depth;
37 		sGraphicsOutput->QueryMode(sGraphicsOutput, mode, &size, &info);
38 		UINTN area = info->HorizontalResolution * info->VerticalResolution;
39 		if (info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor)
40 			depth = 32;
41 		else if (info->PixelFormat == PixelBitMask
42 			&& info->PixelInformation.RedMask == 0xFF0000
43 			&& info->PixelInformation.GreenMask == 0x00FF00
44 			&& info->PixelInformation.BlueMask == 0x0000FF
45 			&& info->PixelInformation.ReservedMask == 0)
46 			depth = 24;
47 		else
48 			continue;
49 
50 		area *= depth;
51 		if (area >= bestArea) {
52 			bestArea = area;
53 			bestDepth = depth;
54 			sGraphicsMode = mode;
55 		}
56 	}
57 
58 	if (bestArea == 0 || bestDepth == 0) {
59 		sGraphicsOutput = NULL;
60 		return B_ERROR;
61 	}
62 
63 	return B_OK;
64 }
65 
66 
67 extern "C" void
68 platform_switch_to_logo(void)
69 {
70 	if (sGraphicsOutput == NULL || gKernelArgs.frame_buffer.enabled)
71 		return;
72 
73 	sGraphicsOutput->SetMode(sGraphicsOutput, sGraphicsMode);
74 	gKernelArgs.frame_buffer.enabled = true;
75 	gKernelArgs.frame_buffer.physical_buffer.start =
76 		sGraphicsOutput->Mode->FrameBufferBase;
77 	gKernelArgs.frame_buffer.physical_buffer.size =
78 		sGraphicsOutput->Mode->FrameBufferSize;
79 	gKernelArgs.frame_buffer.width =
80 		sGraphicsOutput->Mode->Info->HorizontalResolution;
81 	gKernelArgs.frame_buffer.height =
82 		sGraphicsOutput->Mode->Info->VerticalResolution;
83 	gKernelArgs.frame_buffer.depth =
84 		sGraphicsOutput->Mode->Info->PixelFormat == PixelBitMask ? 24 : 32;
85 	gKernelArgs.frame_buffer.bytes_per_row =
86 		sGraphicsOutput->Mode->Info->PixelsPerScanLine
87 			* gKernelArgs.frame_buffer.depth / 8;
88 
89 	video_display_splash(gKernelArgs.frame_buffer.physical_buffer.start);
90 }
91 
92 
93 extern "C" void
94 platform_blit4(addr_t frameBuffer, const uint8 *data,
95 	uint16 width, uint16 height, uint16 imageWidth,
96 	uint16 left, uint16 top)
97 {
98 	panic("platform_blit4 unsupported");
99 	return;
100 }
101 
102 
103 extern "C" void
104 platform_set_palette(const uint8 *palette)
105 {
106 	panic("platform_set_palette unsupported");
107 	return;
108 }
109