1 #include <syslinux/linux.h>
5 extern EFI_GUID GraphicsOutputProtocol
;
7 static uint32_t console_default_attribute
;
8 static bool console_default_cursor
;
11 * We want to restore the console state when we boot a kernel or return
14 void efi_console_save(void)
16 SIMPLE_TEXT_OUTPUT_INTERFACE
*out
= ST
->ConOut
;
17 SIMPLE_TEXT_OUTPUT_MODE
*mode
= out
->Mode
;
19 console_default_attribute
= mode
->Attribute
;
20 console_default_cursor
= mode
->CursorVisible
;
23 void efi_console_restore(void)
25 SIMPLE_TEXT_OUTPUT_INTERFACE
*out
= ST
->ConOut
;
27 uefi_call_wrapper(out
->SetAttribute
, 2, out
, console_default_attribute
);
28 uefi_call_wrapper(out
->EnableCursor
, 2, out
, console_default_cursor
);
31 __export
void writechr(char data
)
33 efi_write_char(data
, 0);
36 static inline EFI_STATUS
open_protocol(EFI_HANDLE handle
, EFI_GUID
*protocol
,
37 void **interface
, EFI_HANDLE agent
,
38 EFI_HANDLE controller
, UINT32 attributes
)
40 return uefi_call_wrapper(BS
->OpenProtocol
, 6, handle
, protocol
,
41 interface
, agent
, controller
, attributes
);
44 static inline EFI_STATUS
45 gop_query_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL
*gop
, UINTN
*size
,
46 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**info
)
48 return uefi_call_wrapper(gop
->QueryMode
, 4, gop
,
49 gop
->Mode
->Mode
, size
, info
);
52 static inline void bit_mask(uint32_t mask
, uint8_t *pos
, uint8_t *size
)
58 while (!(mask
& 0x1)) {
70 static int setup_gop(struct screen_info
*si
)
72 EFI_HANDLE
*handles
= NULL
;
74 EFI_GRAPHICS_OUTPUT_PROTOCOL
*gop
, *found
;
75 EFI_GRAPHICS_PIXEL_FORMAT pixel_fmt
;
76 EFI_PIXEL_BITMASK pixel_info
;
77 uint32_t pixel_scanline
;
80 uint16_t lfb_width
, lfb_height
;
81 uint32_t lfb_base
, lfb_size
;
83 void **gop_handle
= NULL
;
86 status
= uefi_call_wrapper(BS
->LocateHandle
, 5, ByProtocol
, &GraphicsOutputProtocol
,
87 NULL
, &size
, gop_handle
);
88 /* LibLocateHandle handle already returns the number of handles.
89 * There is no need to divide by sizeof(EFI_HANDLE)
91 status
= LibLocateHandle(ByProtocol
, &GraphicsOutputProtocol
,
92 NULL
, &nr_handles
, &handles
);
93 if (status
== EFI_BUFFER_TOO_SMALL
) {
95 handles
= AllocatePool(nr_handles
);
99 status
= LibLocateHandle(ByProtocol
, &GraphicsOutputProtocol
,
100 NULL
, &nr_handles
, &handles
);
102 if (status
!= EFI_SUCCESS
)
106 for (i
= 0; i
< nr_handles
; i
++) {
107 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*info
;
108 EFI_PCI_IO
*pciio
= NULL
;
109 EFI_HANDLE
*h
= handles
[i
];
111 status
= uefi_call_wrapper(BS
->HandleProtocol
, 3, h
,
112 &GraphicsOutputProtocol
, (void **)&gop
);
113 if (status
!= EFI_SUCCESS
)
115 uefi_call_wrapper(BS
->HandleProtocol
, 3, h
,
116 &PciIoProtocol
, (void **)&pciio
);
117 status
= gop_query_mode(gop
, &size
, &info
);
118 if (status
== EFI_SUCCESS
&& (!found
|| pciio
)) {
119 lfb_width
= info
->HorizontalResolution
;
120 lfb_height
= info
->VerticalResolution
;
121 lfb_base
= gop
->Mode
->FrameBufferBase
;
122 lfb_size
= gop
->Mode
->FrameBufferSize
;
123 pixel_fmt
= info
->PixelFormat
;
124 pixel_info
= info
->PixelInformation
;
125 pixel_scanline
= info
->PixelsPerScanLine
;
137 dprintf("setup_screen: set up screen parameters for EFI GOP\n");
138 si
->orig_video_isVGA
= 0x70; /* EFI framebuffer */
140 si
->lfb_base
= lfb_base
;
141 si
->lfb_size
= lfb_size
;
142 si
->lfb_width
= lfb_width
;
143 si
->lfb_height
= lfb_height
;
146 dprintf("setup_screen: lfb_base 0x%x lfb_size %d lfb_width %d lfb_height %d\n", lfb_base
, lfb_size
, lfb_width
, lfb_height
);
148 case PixelRedGreenBlueReserved8BitPerColor
:
150 si
->lfb_linelength
= pixel_scanline
* 4;
160 case PixelBlueGreenRedReserved8BitPerColor
:
162 si
->lfb_linelength
= pixel_scanline
* 4;
173 bit_mask(pixel_info
.RedMask
, &si
->red_pos
,
175 bit_mask(pixel_info
.GreenMask
, &si
->green_pos
,
177 bit_mask(pixel_info
.BlueMask
, &si
->blue_pos
,
179 bit_mask(pixel_info
.ReservedMask
, &si
->rsvd_pos
,
181 si
->lfb_depth
= si
->red_size
+ si
->green_size
+
182 si
->blue_size
+ si
->rsvd_size
;
183 si
->lfb_linelength
= (pixel_scanline
* si
->lfb_depth
) / 8;
187 si
->lfb_linelength
= si
->lfb_width
/ 2;
198 dprintf("setup_screen: depth %d line %d rpos %d rsize %d gpos %d gsize %d bpos %d bsize %d rsvpos %d rsvsize %d\n",
199 si
->lfb_depth
, si
->lfb_linelength
,
200 si
->red_pos
, si
->red_size
,
201 si
->green_pos
, si
->green_size
,
202 si
->blue_pos
, si
->blue_size
,
203 si
->blue_pos
, si
->blue_size
,
204 si
->rsvd_pos
, si
->rsvd_size
);
207 if (handles
) FreePool(handles
);
212 #define EFI_UGA_PROTOCOL_GUID \
214 0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \
217 typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL
;
221 (EFIAPI
*EFI_UGA_DRAW_PROTOCOL_GET_MODE
) (
222 IN EFI_UGA_DRAW_PROTOCOL
*This
,
230 struct _EFI_UGA_DRAW_PROTOCOL
{
231 EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode
;
236 static int setup_uga(struct screen_info
*si
)
238 EFI_UGA_DRAW_PROTOCOL
*uga
, *first
;
239 EFI_GUID UgaProtocol
= EFI_UGA_PROTOCOL_GUID
;
240 UINT32 width
, height
;
246 status
= LibLocateHandle(ByProtocol
, &UgaProtocol
,
247 NULL
, &nr_handles
, &handles
);
248 if (status
!= EFI_SUCCESS
)
251 for (i
= 0; i
< nr_handles
; i
++) {
252 EFI_PCI_IO
*pciio
= NULL
;
253 EFI_HANDLE
*handle
= handles
[i
];
254 UINT32 w
, h
, depth
, refresh
;
256 status
= uefi_call_wrapper(BS
->HandleProtocol
, 3, handle
,
257 &UgaProtocol
, (void **)&uga
);
258 if (status
!= EFI_SUCCESS
)
261 uefi_call_wrapper(BS
->HandleProtocol
, 3, handle
,
262 &PciIoProtocol
, (void **)&pciio
);
264 status
= uefi_call_wrapper(uga
->GetMode
, 5, uga
, &w
, &h
,
267 if (status
== EFI_SUCCESS
&& (!first
|| pciio
)) {
282 si
->orig_video_isVGA
= 0x70; /* EFI framebuffer */
285 si
->lfb_width
= width
;
286 si
->lfb_height
= height
;
302 void setup_screen(struct screen_info
*si
)
304 memset(si
, 0, sizeof(*si
));