2 * Copyright 2011-2014 Intel Corporation - All Rights Reserved
5 #include <syslinux/linux.h>
9 extern EFI_GUID GraphicsOutputProtocol
;
11 static uint32_t console_default_attribute
;
12 static bool console_default_cursor
;
15 * We want to restore the console state when we boot a kernel or return
18 void efi_console_save(void)
20 SIMPLE_TEXT_OUTPUT_INTERFACE
*out
= ST
->ConOut
;
21 SIMPLE_TEXT_OUTPUT_MODE
*mode
= out
->Mode
;
23 console_default_attribute
= mode
->Attribute
;
24 console_default_cursor
= mode
->CursorVisible
;
27 void efi_console_restore(void)
29 SIMPLE_TEXT_OUTPUT_INTERFACE
*out
= ST
->ConOut
;
31 uefi_call_wrapper(out
->SetAttribute
, 2, out
, console_default_attribute
);
32 uefi_call_wrapper(out
->EnableCursor
, 2, out
, console_default_cursor
);
35 __export
void writechr(char data
)
37 efi_write_char(data
, 0);
40 static inline EFI_STATUS
open_protocol(EFI_HANDLE handle
, EFI_GUID
*protocol
,
41 void **interface
, EFI_HANDLE agent
,
42 EFI_HANDLE controller
, UINT32 attributes
)
44 return uefi_call_wrapper(BS
->OpenProtocol
, 6, handle
, protocol
,
45 interface
, agent
, controller
, attributes
);
48 static inline EFI_STATUS
49 gop_query_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL
*gop
, UINTN
*size
,
50 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**info
)
52 return uefi_call_wrapper(gop
->QueryMode
, 4, gop
,
53 gop
->Mode
->Mode
, size
, info
);
56 static inline void bit_mask(uint32_t mask
, uint8_t *pos
, uint8_t *size
)
62 while (!(mask
& 0x1)) {
74 static int setup_gop(struct screen_info
*si
)
76 EFI_HANDLE
*handles
= NULL
;
78 EFI_GRAPHICS_OUTPUT_PROTOCOL
*gop
, *found
;
79 EFI_GRAPHICS_PIXEL_FORMAT pixel_fmt
;
80 EFI_PIXEL_BITMASK pixel_info
;
81 uint32_t pixel_scanline
;
84 uint16_t lfb_width
, lfb_height
;
85 uint32_t lfb_base
, lfb_size
;
87 void **gop_handle
= NULL
;
90 status
= uefi_call_wrapper(BS
->LocateHandle
, 5, ByProtocol
, &GraphicsOutputProtocol
,
91 NULL
, &size
, gop_handle
);
92 /* LibLocateHandle handle already returns the number of handles.
93 * There is no need to divide by sizeof(EFI_HANDLE)
95 status
= LibLocateHandle(ByProtocol
, &GraphicsOutputProtocol
,
96 NULL
, &nr_handles
, &handles
);
97 if (status
== EFI_BUFFER_TOO_SMALL
) {
99 handles
= AllocatePool(nr_handles
);
103 status
= LibLocateHandle(ByProtocol
, &GraphicsOutputProtocol
,
104 NULL
, &nr_handles
, &handles
);
106 if (status
!= EFI_SUCCESS
)
110 for (i
= 0; i
< nr_handles
; i
++) {
111 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*info
;
112 EFI_PCI_IO
*pciio
= NULL
;
113 EFI_HANDLE
*h
= handles
[i
];
115 status
= uefi_call_wrapper(BS
->HandleProtocol
, 3, h
,
116 &GraphicsOutputProtocol
, (void **)&gop
);
117 if (status
!= EFI_SUCCESS
)
119 uefi_call_wrapper(BS
->HandleProtocol
, 3, h
,
120 &PciIoProtocol
, (void **)&pciio
);
121 status
= gop_query_mode(gop
, &size
, &info
);
122 if (status
== EFI_SUCCESS
&& (!found
|| pciio
)) {
123 lfb_width
= info
->HorizontalResolution
;
124 lfb_height
= info
->VerticalResolution
;
125 lfb_base
= gop
->Mode
->FrameBufferBase
;
126 lfb_size
= gop
->Mode
->FrameBufferSize
;
127 pixel_fmt
= info
->PixelFormat
;
128 pixel_info
= info
->PixelInformation
;
129 pixel_scanline
= info
->PixelsPerScanLine
;
141 dprintf("setup_screen: set up screen parameters for EFI GOP\n");
142 si
->orig_video_isVGA
= 0x70; /* EFI framebuffer */
144 si
->lfb_base
= lfb_base
;
145 si
->lfb_size
= lfb_size
;
146 si
->lfb_width
= lfb_width
;
147 si
->lfb_height
= lfb_height
;
150 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
);
152 case PixelRedGreenBlueReserved8BitPerColor
:
154 si
->lfb_linelength
= pixel_scanline
* 4;
164 case PixelBlueGreenRedReserved8BitPerColor
:
166 si
->lfb_linelength
= pixel_scanline
* 4;
177 bit_mask(pixel_info
.RedMask
, &si
->red_pos
,
179 bit_mask(pixel_info
.GreenMask
, &si
->green_pos
,
181 bit_mask(pixel_info
.BlueMask
, &si
->blue_pos
,
183 bit_mask(pixel_info
.ReservedMask
, &si
->rsvd_pos
,
185 si
->lfb_depth
= si
->red_size
+ si
->green_size
+
186 si
->blue_size
+ si
->rsvd_size
;
187 si
->lfb_linelength
= (pixel_scanline
* si
->lfb_depth
) / 8;
191 si
->lfb_linelength
= si
->lfb_width
/ 2;
202 dprintf("setup_screen: depth %d line %d rpos %d rsize %d gpos %d gsize %d bpos %d bsize %d rsvpos %d rsvsize %d\n",
203 si
->lfb_depth
, si
->lfb_linelength
,
204 si
->red_pos
, si
->red_size
,
205 si
->green_pos
, si
->green_size
,
206 si
->blue_pos
, si
->blue_size
,
207 si
->blue_pos
, si
->blue_size
,
208 si
->rsvd_pos
, si
->rsvd_size
);
211 if (handles
) FreePool(handles
);
216 #define EFI_UGA_PROTOCOL_GUID \
218 0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \
221 typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL
;
225 (EFIAPI
*EFI_UGA_DRAW_PROTOCOL_GET_MODE
) (
226 IN EFI_UGA_DRAW_PROTOCOL
*This
,
234 struct _EFI_UGA_DRAW_PROTOCOL
{
235 EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode
;
240 static int setup_uga(struct screen_info
*si
)
242 EFI_UGA_DRAW_PROTOCOL
*uga
, *first
;
243 EFI_GUID UgaProtocol
= EFI_UGA_PROTOCOL_GUID
;
244 UINT32 width
, height
;
250 status
= LibLocateHandle(ByProtocol
, &UgaProtocol
,
251 NULL
, &nr_handles
, &handles
);
252 if (status
!= EFI_SUCCESS
)
255 for (i
= 0; i
< nr_handles
; i
++) {
256 EFI_PCI_IO
*pciio
= NULL
;
257 EFI_HANDLE
*handle
= handles
[i
];
258 UINT32 w
, h
, depth
, refresh
;
260 status
= uefi_call_wrapper(BS
->HandleProtocol
, 3, handle
,
261 &UgaProtocol
, (void **)&uga
);
262 if (status
!= EFI_SUCCESS
)
265 uefi_call_wrapper(BS
->HandleProtocol
, 3, handle
,
266 &PciIoProtocol
, (void **)&pciio
);
268 status
= uefi_call_wrapper(uga
->GetMode
, 5, uga
, &w
, &h
,
271 if (status
== EFI_SUCCESS
&& (!first
|| pciio
)) {
286 si
->orig_video_isVGA
= 0x70; /* EFI framebuffer */
289 si
->lfb_width
= width
;
290 si
->lfb_height
= height
;
306 void setup_screen(struct screen_info
*si
)
308 memset(si
, 0, sizeof(*si
));