]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / Console / GraphicsConsoleDxe / GraphicsConsole.c
... / ...
CommitLineData
1/** @file\r
2 This is the main routine for initializing the Graphics Console support routines.\r
3\r
4Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "GraphicsConsole.h"\r
10\r
11//\r
12// Graphics Console Device Private Data template\r
13//\r
14GRAPHICS_CONSOLE_DEV mGraphicsConsoleDevTemplate = {\r
15 GRAPHICS_CONSOLE_DEV_SIGNATURE,\r
16 (EFI_GRAPHICS_OUTPUT_PROTOCOL *)NULL,\r
17 (EFI_UGA_DRAW_PROTOCOL *)NULL,\r
18 {\r
19 GraphicsConsoleConOutReset,\r
20 GraphicsConsoleConOutOutputString,\r
21 GraphicsConsoleConOutTestString,\r
22 GraphicsConsoleConOutQueryMode,\r
23 GraphicsConsoleConOutSetMode,\r
24 GraphicsConsoleConOutSetAttribute,\r
25 GraphicsConsoleConOutClearScreen,\r
26 GraphicsConsoleConOutSetCursorPosition,\r
27 GraphicsConsoleConOutEnableCursor,\r
28 (EFI_SIMPLE_TEXT_OUTPUT_MODE *)NULL\r
29 },\r
30 {\r
31 0,\r
32 -1,\r
33 EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK),\r
34 0,\r
35 0,\r
36 FALSE\r
37 },\r
38 (GRAPHICS_CONSOLE_MODE_DATA *)NULL,\r
39 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)NULL\r
40};\r
41\r
42GRAPHICS_CONSOLE_MODE_DATA mGraphicsConsoleModeData[] = {\r
43 { 100, 31 }, // 800 x 600\r
44 { 128, 40 }, // 1024 x 768\r
45 { 160, 42 }, // 1280 x 800\r
46 { 240, 56 }, // 1920 x 1080\r
47 //\r
48 // New modes can be added here.\r
49 // The last entry is specific for full screen mode.\r
50 //\r
51 { 0, 0 }\r
52};\r
53\r
54EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
55EFI_HII_FONT_PROTOCOL *mHiiFont;\r
56EFI_HII_HANDLE mHiiHandle;\r
57VOID *mHiiRegistration;\r
58\r
59EFI_GUID mFontPackageListGuid = {\r
60 0xf5f219d3, 0x7006, 0x4648, { 0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad }\r
61};\r
62\r
63CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };\r
64\r
65EFI_GRAPHICS_OUTPUT_BLT_PIXEL mGraphicsEfiColors[16] = {\r
66 //\r
67 // B G R reserved\r
68 //\r
69 { 0x00, 0x00, 0x00, 0x00 }, // BLACK\r
70 { 0x98, 0x00, 0x00, 0x00 }, // LIGHTBLUE\r
71 { 0x00, 0x98, 0x00, 0x00 }, // LIGHGREEN\r
72 { 0x98, 0x98, 0x00, 0x00 }, // LIGHCYAN\r
73 { 0x00, 0x00, 0x98, 0x00 }, // LIGHRED\r
74 { 0x98, 0x00, 0x98, 0x00 }, // MAGENTA\r
75 { 0x00, 0x98, 0x98, 0x00 }, // BROWN\r
76 { 0x98, 0x98, 0x98, 0x00 }, // LIGHTGRAY\r
77 { 0x30, 0x30, 0x30, 0x00 }, // DARKGRAY - BRIGHT BLACK\r
78 { 0xff, 0x00, 0x00, 0x00 }, // BLUE\r
79 { 0x00, 0xff, 0x00, 0x00 }, // LIME\r
80 { 0xff, 0xff, 0x00, 0x00 }, // CYAN\r
81 { 0x00, 0x00, 0xff, 0x00 }, // RED\r
82 { 0xff, 0x00, 0xff, 0x00 }, // FUCHSIA\r
83 { 0x00, 0xff, 0xff, 0x00 }, // YELLOW\r
84 { 0xff, 0xff, 0xff, 0x00 } // WHITE\r
85};\r
86\r
87EFI_NARROW_GLYPH mCursorGlyph = {\r
88 0x0000,\r
89 0x00,\r
90 { 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }\r
91};\r
92\r
93CHAR16 SpaceStr[] = { NARROW_CHAR, ' ', 0 };\r
94\r
95EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {\r
96 GraphicsConsoleControllerDriverSupported,\r
97 GraphicsConsoleControllerDriverStart,\r
98 GraphicsConsoleControllerDriverStop,\r
99 0xa,\r
100 NULL,\r
101 NULL\r
102};\r
103\r
104/**\r
105 Test to see if Graphics Console could be supported on the Controller.\r
106\r
107 Graphics Console could be supported if Graphics Output Protocol or UGA Draw\r
108 Protocol exists on the Controller. (UGA Draw Protocol could be skipped\r
109 if PcdUgaConsumeSupport is set to FALSE.)\r
110\r
111 @param This Protocol instance pointer.\r
112 @param Controller Handle of device to test.\r
113 @param RemainingDevicePath Optional parameter use to pick a specific child\r
114 device to start.\r
115\r
116 @retval EFI_SUCCESS This driver supports this device.\r
117 @retval other This driver does not support this device.\r
118\r
119**/\r
120EFI_STATUS\r
121EFIAPI\r
122GraphicsConsoleControllerDriverSupported (\r
123 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
124 IN EFI_HANDLE Controller,\r
125 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
126 )\r
127{\r
128 EFI_STATUS Status;\r
129 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
130 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
131 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
132\r
133 GraphicsOutput = NULL;\r
134 UgaDraw = NULL;\r
135 //\r
136 // Open the IO Abstraction(s) needed to perform the supported test\r
137 //\r
138 Status = gBS->OpenProtocol (\r
139 Controller,\r
140 &gEfiGraphicsOutputProtocolGuid,\r
141 (VOID **)&GraphicsOutput,\r
142 This->DriverBindingHandle,\r
143 Controller,\r
144 EFI_OPEN_PROTOCOL_BY_DRIVER\r
145 );\r
146\r
147 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
148 //\r
149 // Open Graphics Output Protocol failed, try to open UGA Draw Protocol\r
150 //\r
151 Status = gBS->OpenProtocol (\r
152 Controller,\r
153 &gEfiUgaDrawProtocolGuid,\r
154 (VOID **)&UgaDraw,\r
155 This->DriverBindingHandle,\r
156 Controller,\r
157 EFI_OPEN_PROTOCOL_BY_DRIVER\r
158 );\r
159 }\r
160\r
161 if (EFI_ERROR (Status)) {\r
162 return Status;\r
163 }\r
164\r
165 //\r
166 // We need to ensure that we do not layer on top of a virtual handle.\r
167 // We need to ensure that the handles produced by the conspliter do not\r
168 // get used.\r
169 //\r
170 Status = gBS->OpenProtocol (\r
171 Controller,\r
172 &gEfiDevicePathProtocolGuid,\r
173 (VOID **)&DevicePath,\r
174 This->DriverBindingHandle,\r
175 Controller,\r
176 EFI_OPEN_PROTOCOL_BY_DRIVER\r
177 );\r
178 if (!EFI_ERROR (Status)) {\r
179 gBS->CloseProtocol (\r
180 Controller,\r
181 &gEfiDevicePathProtocolGuid,\r
182 This->DriverBindingHandle,\r
183 Controller\r
184 );\r
185 } else {\r
186 goto Error;\r
187 }\r
188\r
189 //\r
190 // Does Hii Exist? If not, we aren't ready to run\r
191 //\r
192 Status = EfiLocateHiiProtocol ();\r
193\r
194 //\r
195 // Close the I/O Abstraction(s) used to perform the supported test\r
196 //\r
197Error:\r
198 if (GraphicsOutput != NULL) {\r
199 gBS->CloseProtocol (\r
200 Controller,\r
201 &gEfiGraphicsOutputProtocolGuid,\r
202 This->DriverBindingHandle,\r
203 Controller\r
204 );\r
205 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
206 gBS->CloseProtocol (\r
207 Controller,\r
208 &gEfiUgaDrawProtocolGuid,\r
209 This->DriverBindingHandle,\r
210 Controller\r
211 );\r
212 }\r
213\r
214 return Status;\r
215}\r
216\r
217/**\r
218 Initialize all the text modes which the graphics console supports.\r
219\r
220 It returns information for available text modes that the graphics can support.\r
221\r
222 @param[in] HorizontalResolution The size of video screen in pixels in the X dimension.\r
223 @param[in] VerticalResolution The size of video screen in pixels in the Y dimension.\r
224 @param[in] GopModeNumber The graphics mode number which graphics console is based on.\r
225 @param[out] TextModeCount The total number of text modes that graphics console supports.\r
226 @param[out] TextModeData The buffer to the text modes column and row information.\r
227 Caller is responsible to free it when it's non-NULL.\r
228\r
229 @retval EFI_SUCCESS The supporting mode information is returned.\r
230 @retval EFI_INVALID_PARAMETER The parameters are invalid.\r
231\r
232**/\r
233EFI_STATUS\r
234InitializeGraphicsConsoleTextMode (\r
235 IN UINT32 HorizontalResolution,\r
236 IN UINT32 VerticalResolution,\r
237 IN UINT32 GopModeNumber,\r
238 OUT UINTN *TextModeCount,\r
239 OUT GRAPHICS_CONSOLE_MODE_DATA **TextModeData\r
240 )\r
241{\r
242 UINTN Index;\r
243 UINTN Count;\r
244 GRAPHICS_CONSOLE_MODE_DATA *ModeBuffer;\r
245 GRAPHICS_CONSOLE_MODE_DATA *NewModeBuffer;\r
246 UINTN ValidCount;\r
247 UINTN ValidIndex;\r
248 UINTN MaxColumns;\r
249 UINTN MaxRows;\r
250\r
251 if ((TextModeCount == NULL) || (TextModeData == NULL)) {\r
252 return EFI_INVALID_PARAMETER;\r
253 }\r
254\r
255 Count = sizeof (mGraphicsConsoleModeData) / sizeof (GRAPHICS_CONSOLE_MODE_DATA);\r
256\r
257 //\r
258 // Compute the maximum number of text Rows and Columns that this current graphics mode can support.\r
259 // To make graphics console work well, MaxColumns and MaxRows should not be zero.\r
260 //\r
261 MaxColumns = HorizontalResolution / EFI_GLYPH_WIDTH;\r
262 MaxRows = VerticalResolution / EFI_GLYPH_HEIGHT;\r
263\r
264 //\r
265 // According to UEFI spec, all output devices support at least 80x25 text mode.\r
266 //\r
267 ASSERT ((MaxColumns >= 80) && (MaxRows >= 25));\r
268\r
269 //\r
270 // Add full screen mode to the last entry.\r
271 //\r
272 mGraphicsConsoleModeData[Count - 1].Columns = MaxColumns;\r
273 mGraphicsConsoleModeData[Count - 1].Rows = MaxRows;\r
274\r
275 //\r
276 // Get defined mode buffer pointer.\r
277 //\r
278 ModeBuffer = mGraphicsConsoleModeData;\r
279\r
280 //\r
281 // Here we make sure that the final mode exposed does not include the duplicated modes,\r
282 // and does not include the invalid modes which exceed the max column and row.\r
283 // Reserve 2 modes for 80x25, 80x50 of graphics console.\r
284 //\r
285 NewModeBuffer = AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA) * (Count + 2));\r
286 ASSERT (NewModeBuffer != NULL);\r
287\r
288 //\r
289 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.\r
290 //\r
291 ValidCount = 0;\r
292\r
293 NewModeBuffer[ValidCount].Columns = 80;\r
294 NewModeBuffer[ValidCount].Rows = 25;\r
295 NewModeBuffer[ValidCount].GopWidth = HorizontalResolution;\r
296 NewModeBuffer[ValidCount].GopHeight = VerticalResolution;\r
297 NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;\r
298 NewModeBuffer[ValidCount].DeltaX = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;\r
299 NewModeBuffer[ValidCount].DeltaY = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;\r
300 ValidCount++;\r
301\r
302 if ((MaxColumns >= 80) && (MaxRows >= 50)) {\r
303 NewModeBuffer[ValidCount].Columns = 80;\r
304 NewModeBuffer[ValidCount].Rows = 50;\r
305 NewModeBuffer[ValidCount].DeltaX = (HorizontalResolution - (80 * EFI_GLYPH_WIDTH)) >> 1;\r
306 NewModeBuffer[ValidCount].DeltaY = (VerticalResolution - (50 * EFI_GLYPH_HEIGHT)) >> 1;\r
307 }\r
308\r
309 NewModeBuffer[ValidCount].GopWidth = HorizontalResolution;\r
310 NewModeBuffer[ValidCount].GopHeight = VerticalResolution;\r
311 NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;\r
312 ValidCount++;\r
313\r
314 //\r
315 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.\r
316 //\r
317 for (Index = 0; Index < Count; Index++) {\r
318 if ((ModeBuffer[Index].Columns == 0) || (ModeBuffer[Index].Rows == 0) ||\r
319 (ModeBuffer[Index].Columns > MaxColumns) || (ModeBuffer[Index].Rows > MaxRows))\r
320 {\r
321 //\r
322 // Skip the pre-defined mode which is invalid or exceeds the max column and row.\r
323 //\r
324 continue;\r
325 }\r
326\r
327 for (ValidIndex = 0; ValidIndex < ValidCount; ValidIndex++) {\r
328 if ((ModeBuffer[Index].Columns == NewModeBuffer[ValidIndex].Columns) &&\r
329 (ModeBuffer[Index].Rows == NewModeBuffer[ValidIndex].Rows))\r
330 {\r
331 //\r
332 // Skip the duplicated mode.\r
333 //\r
334 break;\r
335 }\r
336 }\r
337\r
338 if (ValidIndex == ValidCount) {\r
339 NewModeBuffer[ValidCount].Columns = ModeBuffer[Index].Columns;\r
340 NewModeBuffer[ValidCount].Rows = ModeBuffer[Index].Rows;\r
341 NewModeBuffer[ValidCount].GopWidth = HorizontalResolution;\r
342 NewModeBuffer[ValidCount].GopHeight = VerticalResolution;\r
343 NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;\r
344 NewModeBuffer[ValidCount].DeltaX = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;\r
345 NewModeBuffer[ValidCount].DeltaY = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;\r
346 ValidCount++;\r
347 }\r
348 }\r
349\r
350 DEBUG_CODE_BEGIN ();\r
351 for (Index = 0; Index < ValidCount; Index++) {\r
352 DEBUG ((\r
353 DEBUG_INFO,\r
354 "Graphics - Mode %d, Column = %d, Row = %d\n",\r
355 Index,\r
356 NewModeBuffer[Index].Columns,\r
357 NewModeBuffer[Index].Rows\r
358 ));\r
359 }\r
360\r
361 DEBUG_CODE_END ();\r
362\r
363 //\r
364 // Return valid mode count and mode information buffer.\r
365 //\r
366 *TextModeCount = ValidCount;\r
367 *TextModeData = NewModeBuffer;\r
368 return EFI_SUCCESS;\r
369}\r
370\r
371/**\r
372 Start this driver on Controller by opening Graphics Output protocol or\r
373 UGA Draw protocol, and installing Simple Text Out protocol on Controller.\r
374 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)\r
375\r
376 @param This Protocol instance pointer.\r
377 @param Controller Handle of device to bind driver to\r
378 @param RemainingDevicePath Optional parameter use to pick a specific child\r
379 device to start.\r
380\r
381 @retval EFI_SUCCESS This driver is added to Controller.\r
382 @retval other This driver does not support this device.\r
383\r
384**/\r
385EFI_STATUS\r
386EFIAPI\r
387GraphicsConsoleControllerDriverStart (\r
388 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
389 IN EFI_HANDLE Controller,\r
390 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
391 )\r
392{\r
393 EFI_STATUS Status;\r
394 GRAPHICS_CONSOLE_DEV *Private;\r
395 UINT32 HorizontalResolution;\r
396 UINT32 VerticalResolution;\r
397 UINT32 ColorDepth;\r
398 UINT32 RefreshRate;\r
399 UINT32 ModeIndex;\r
400 UINTN MaxMode;\r
401 UINT32 ModeNumber;\r
402 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;\r
403 UINTN SizeOfInfo;\r
404 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
405 INT32 PreferMode;\r
406 INT32 Index;\r
407 UINTN Column;\r
408 UINTN Row;\r
409 UINTN DefaultColumn;\r
410 UINTN DefaultRow;\r
411\r
412 ModeNumber = 0;\r
413\r
414 //\r
415 // Initialize the Graphics Console device instance\r
416 //\r
417 Private = AllocateCopyPool (\r
418 sizeof (GRAPHICS_CONSOLE_DEV),\r
419 &mGraphicsConsoleDevTemplate\r
420 );\r
421 if (Private == NULL) {\r
422 return EFI_OUT_OF_RESOURCES;\r
423 }\r
424\r
425 Private->SimpleTextOutput.Mode = &(Private->SimpleTextOutputMode);\r
426\r
427 Status = gBS->OpenProtocol (\r
428 Controller,\r
429 &gEfiGraphicsOutputProtocolGuid,\r
430 (VOID **)&Private->GraphicsOutput,\r
431 This->DriverBindingHandle,\r
432 Controller,\r
433 EFI_OPEN_PROTOCOL_BY_DRIVER\r
434 );\r
435\r
436 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
437 Status = gBS->OpenProtocol (\r
438 Controller,\r
439 &gEfiUgaDrawProtocolGuid,\r
440 (VOID **)&Private->UgaDraw,\r
441 This->DriverBindingHandle,\r
442 Controller,\r
443 EFI_OPEN_PROTOCOL_BY_DRIVER\r
444 );\r
445 }\r
446\r
447 if (EFI_ERROR (Status)) {\r
448 goto Error;\r
449 }\r
450\r
451 HorizontalResolution = PcdGet32 (PcdVideoHorizontalResolution);\r
452 VerticalResolution = PcdGet32 (PcdVideoVerticalResolution);\r
453\r
454 if (Private->GraphicsOutput != NULL) {\r
455 //\r
456 // The console is build on top of Graphics Output Protocol, find the mode number\r
457 // for the user-defined mode; if there are multiple video devices,\r
458 // graphic console driver will set all the video devices to the same mode.\r
459 //\r
460 if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {\r
461 //\r
462 // Find the highest resolution which GOP supports.\r
463 //\r
464 MaxMode = Private->GraphicsOutput->Mode->MaxMode;\r
465\r
466 for (ModeIndex = 0; ModeIndex < MaxMode; ModeIndex++) {\r
467 Status = Private->GraphicsOutput->QueryMode (\r
468 Private->GraphicsOutput,\r
469 ModeIndex,\r
470 &SizeOfInfo,\r
471 &Info\r
472 );\r
473 if (!EFI_ERROR (Status)) {\r
474 if ((Info->HorizontalResolution > HorizontalResolution) ||\r
475 ((Info->HorizontalResolution == HorizontalResolution) && (Info->VerticalResolution > VerticalResolution)))\r
476 {\r
477 HorizontalResolution = Info->HorizontalResolution;\r
478 VerticalResolution = Info->VerticalResolution;\r
479 ModeNumber = ModeIndex;\r
480 }\r
481\r
482 FreePool (Info);\r
483 }\r
484 }\r
485\r
486 if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {\r
487 Status = EFI_UNSUPPORTED;\r
488 goto Error;\r
489 }\r
490 } else {\r
491 //\r
492 // Use user-defined resolution\r
493 //\r
494 Status = CheckModeSupported (\r
495 Private->GraphicsOutput,\r
496 HorizontalResolution,\r
497 VerticalResolution,\r
498 &ModeNumber\r
499 );\r
500 if (EFI_ERROR (Status)) {\r
501 //\r
502 // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec\r
503 //\r
504 HorizontalResolution = 800;\r
505 VerticalResolution = 600;\r
506 Status = CheckModeSupported (\r
507 Private->GraphicsOutput,\r
508 HorizontalResolution,\r
509 VerticalResolution,\r
510 &ModeNumber\r
511 );\r
512 Mode = Private->GraphicsOutput->Mode;\r
513 if (EFI_ERROR (Status) && (Mode->MaxMode != 0)) {\r
514 //\r
515 // If set default mode failed or device doesn't support default mode, then get the current mode information\r
516 //\r
517 HorizontalResolution = Mode->Info->HorizontalResolution;\r
518 VerticalResolution = Mode->Info->VerticalResolution;\r
519 ModeNumber = Mode->Mode;\r
520 }\r
521 }\r
522 }\r
523\r
524 if (EFI_ERROR (Status) || (ModeNumber != Private->GraphicsOutput->Mode->Mode)) {\r
525 //\r
526 // Current graphics mode is not set or is not set to the mode which we have found,\r
527 // set the new graphic mode.\r
528 //\r
529 Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);\r
530 if (EFI_ERROR (Status)) {\r
531 //\r
532 // The mode set operation failed\r
533 //\r
534 goto Error;\r
535 }\r
536 }\r
537 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
538 //\r
539 // At first try to set user-defined resolution\r
540 //\r
541 ColorDepth = 32;\r
542 RefreshRate = 60;\r
543 Status = Private->UgaDraw->SetMode (\r
544 Private->UgaDraw,\r
545 HorizontalResolution,\r
546 VerticalResolution,\r
547 ColorDepth,\r
548 RefreshRate\r
549 );\r
550 if (EFI_ERROR (Status)) {\r
551 //\r
552 // Try to set 800*600 which is required by UEFI/EFI spec\r
553 //\r
554 Status = Private->UgaDraw->SetMode (\r
555 Private->UgaDraw,\r
556 800,\r
557 600,\r
558 ColorDepth,\r
559 RefreshRate\r
560 );\r
561 if (EFI_ERROR (Status)) {\r
562 Status = Private->UgaDraw->GetMode (\r
563 Private->UgaDraw,\r
564 &HorizontalResolution,\r
565 &VerticalResolution,\r
566 &ColorDepth,\r
567 &RefreshRate\r
568 );\r
569 if (EFI_ERROR (Status)) {\r
570 goto Error;\r
571 }\r
572 }\r
573 }\r
574 }\r
575\r
576 DEBUG ((DEBUG_INFO, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution, VerticalResolution));\r
577\r
578 //\r
579 // Initialize the mode which GraphicsConsole supports.\r
580 //\r
581 Status = InitializeGraphicsConsoleTextMode (\r
582 HorizontalResolution,\r
583 VerticalResolution,\r
584 ModeNumber,\r
585 &MaxMode,\r
586 &Private->ModeData\r
587 );\r
588\r
589 if (EFI_ERROR (Status)) {\r
590 goto Error;\r
591 }\r
592\r
593 //\r
594 // Update the maximum number of modes\r
595 //\r
596 Private->SimpleTextOutputMode.MaxMode = (INT32)MaxMode;\r
597\r
598 //\r
599 // Initialize the Mode of graphics console devices\r
600 //\r
601 PreferMode = -1;\r
602 DefaultColumn = PcdGet32 (PcdConOutColumn);\r
603 DefaultRow = PcdGet32 (PcdConOutRow);\r
604 Column = 0;\r
605 Row = 0;\r
606 for (Index = 0; Index < (INT32)MaxMode; Index++) {\r
607 if ((DefaultColumn != 0) && (DefaultRow != 0)) {\r
608 if ((Private->ModeData[Index].Columns == DefaultColumn) &&\r
609 (Private->ModeData[Index].Rows == DefaultRow))\r
610 {\r
611 PreferMode = Index;\r
612 break;\r
613 }\r
614 } else {\r
615 if ((Private->ModeData[Index].Columns > Column) &&\r
616 (Private->ModeData[Index].Rows > Row))\r
617 {\r
618 Column = Private->ModeData[Index].Columns;\r
619 Row = Private->ModeData[Index].Rows;\r
620 PreferMode = Index;\r
621 }\r
622 }\r
623 }\r
624\r
625 Private->SimpleTextOutput.Mode->Mode = (INT32)PreferMode;\r
626 DEBUG ((DEBUG_INFO, "Graphics Console Started, Mode: %d\n", PreferMode));\r
627\r
628 //\r
629 // Install protocol interfaces for the Graphics Console device.\r
630 //\r
631 Status = gBS->InstallMultipleProtocolInterfaces (\r
632 &Controller,\r
633 &gEfiSimpleTextOutProtocolGuid,\r
634 &Private->SimpleTextOutput,\r
635 NULL\r
636 );\r
637\r
638Error:\r
639 if (EFI_ERROR (Status)) {\r
640 //\r
641 // Close the GOP and UGA Draw Protocol\r
642 //\r
643 if (Private->GraphicsOutput != NULL) {\r
644 gBS->CloseProtocol (\r
645 Controller,\r
646 &gEfiGraphicsOutputProtocolGuid,\r
647 This->DriverBindingHandle,\r
648 Controller\r
649 );\r
650 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
651 gBS->CloseProtocol (\r
652 Controller,\r
653 &gEfiUgaDrawProtocolGuid,\r
654 This->DriverBindingHandle,\r
655 Controller\r
656 );\r
657 }\r
658\r
659 if (Private->LineBuffer != NULL) {\r
660 FreePool (Private->LineBuffer);\r
661 }\r
662\r
663 if (Private->ModeData != NULL) {\r
664 FreePool (Private->ModeData);\r
665 }\r
666\r
667 //\r
668 // Free private data\r
669 //\r
670 FreePool (Private);\r
671 }\r
672\r
673 return Status;\r
674}\r
675\r
676/**\r
677 Stop this driver on Controller by removing Simple Text Out protocol\r
678 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.\r
679 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)\r
680\r
681\r
682 @param This Protocol instance pointer.\r
683 @param Controller Handle of device to stop driver on\r
684 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
685 children is zero stop the entire bus driver.\r
686 @param ChildHandleBuffer List of Child Handles to Stop.\r
687\r
688 @retval EFI_SUCCESS This driver is removed Controller.\r
689 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the\r
690 Controller.\r
691 @retval other This driver was not removed from this device.\r
692\r
693**/\r
694EFI_STATUS\r
695EFIAPI\r
696GraphicsConsoleControllerDriverStop (\r
697 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
698 IN EFI_HANDLE Controller,\r
699 IN UINTN NumberOfChildren,\r
700 IN EFI_HANDLE *ChildHandleBuffer\r
701 )\r
702{\r
703 EFI_STATUS Status;\r
704 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;\r
705 GRAPHICS_CONSOLE_DEV *Private;\r
706\r
707 Status = gBS->OpenProtocol (\r
708 Controller,\r
709 &gEfiSimpleTextOutProtocolGuid,\r
710 (VOID **)&SimpleTextOutput,\r
711 This->DriverBindingHandle,\r
712 Controller,\r
713 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
714 );\r
715 if (EFI_ERROR (Status)) {\r
716 return EFI_NOT_STARTED;\r
717 }\r
718\r
719 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);\r
720\r
721 Status = gBS->UninstallProtocolInterface (\r
722 Controller,\r
723 &gEfiSimpleTextOutProtocolGuid,\r
724 &Private->SimpleTextOutput\r
725 );\r
726\r
727 if (!EFI_ERROR (Status)) {\r
728 //\r
729 // Close the GOP or UGA IO Protocol\r
730 //\r
731 if (Private->GraphicsOutput != NULL) {\r
732 gBS->CloseProtocol (\r
733 Controller,\r
734 &gEfiGraphicsOutputProtocolGuid,\r
735 This->DriverBindingHandle,\r
736 Controller\r
737 );\r
738 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
739 gBS->CloseProtocol (\r
740 Controller,\r
741 &gEfiUgaDrawProtocolGuid,\r
742 This->DriverBindingHandle,\r
743 Controller\r
744 );\r
745 }\r
746\r
747 if (Private->LineBuffer != NULL) {\r
748 FreePool (Private->LineBuffer);\r
749 }\r
750\r
751 if (Private->ModeData != NULL) {\r
752 FreePool (Private->ModeData);\r
753 }\r
754\r
755 //\r
756 // Free our instance data\r
757 //\r
758 FreePool (Private);\r
759 }\r
760\r
761 return Status;\r
762}\r
763\r
764/**\r
765 Check if the current specific mode supported the user defined resolution\r
766 for the Graphics Console device based on Graphics Output Protocol.\r
767\r
768 If yes, set the graphic device's current mode to this specific mode.\r
769\r
770 @param GraphicsOutput Graphics Output Protocol instance pointer.\r
771 @param HorizontalResolution User defined horizontal resolution\r
772 @param VerticalResolution User defined vertical resolution.\r
773 @param CurrentModeNumber Current specific mode to be check.\r
774\r
775 @retval EFI_SUCCESS The mode is supported.\r
776 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics\r
777 device supported.\r
778 @retval other The specific mode does not support user defined\r
779 resolution or failed to set the current mode to the\r
780 specific mode on graphics device.\r
781\r
782**/\r
783EFI_STATUS\r
784CheckModeSupported (\r
785 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
786 IN UINT32 HorizontalResolution,\r
787 IN UINT32 VerticalResolution,\r
788 OUT UINT32 *CurrentModeNumber\r
789 )\r
790{\r
791 UINT32 ModeNumber;\r
792 EFI_STATUS Status;\r
793 UINTN SizeOfInfo;\r
794 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
795 UINT32 MaxMode;\r
796\r
797 Status = EFI_SUCCESS;\r
798 MaxMode = GraphicsOutput->Mode->MaxMode;\r
799\r
800 for (ModeNumber = 0; ModeNumber < MaxMode; ModeNumber++) {\r
801 Status = GraphicsOutput->QueryMode (\r
802 GraphicsOutput,\r
803 ModeNumber,\r
804 &SizeOfInfo,\r
805 &Info\r
806 );\r
807 if (!EFI_ERROR (Status)) {\r
808 if ((Info->HorizontalResolution == HorizontalResolution) &&\r
809 (Info->VerticalResolution == VerticalResolution))\r
810 {\r
811 if ((GraphicsOutput->Mode->Info->HorizontalResolution == HorizontalResolution) &&\r
812 (GraphicsOutput->Mode->Info->VerticalResolution == VerticalResolution))\r
813 {\r
814 //\r
815 // If video device has been set to this mode, we do not need to SetMode again\r
816 //\r
817 FreePool (Info);\r
818 break;\r
819 } else {\r
820 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
821 if (!EFI_ERROR (Status)) {\r
822 FreePool (Info);\r
823 break;\r
824 }\r
825 }\r
826 }\r
827\r
828 FreePool (Info);\r
829 }\r
830 }\r
831\r
832 if (ModeNumber == GraphicsOutput->Mode->MaxMode) {\r
833 Status = EFI_UNSUPPORTED;\r
834 }\r
835\r
836 *CurrentModeNumber = ModeNumber;\r
837 return Status;\r
838}\r
839\r
840/**\r
841 Locate HII Database protocol and HII Font protocol.\r
842\r
843 @retval EFI_SUCCESS HII Database protocol and HII Font protocol\r
844 are located successfully.\r
845 @return other Failed to locate HII Database protocol or\r
846 HII Font protocol.\r
847\r
848**/\r
849EFI_STATUS\r
850EfiLocateHiiProtocol (\r
851 VOID\r
852 )\r
853{\r
854 EFI_STATUS Status;\r
855\r
856 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&mHiiDatabase);\r
857 if (EFI_ERROR (Status)) {\r
858 return Status;\r
859 }\r
860\r
861 Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **)&mHiiFont);\r
862 return Status;\r
863}\r
864\r
865//\r
866// Body of the STO functions\r
867//\r
868\r
869/**\r
870 Reset the text output device hardware and optionally run diagnostics.\r
871\r
872 Implements SIMPLE_TEXT_OUTPUT.Reset().\r
873 If ExtendedVerification is TRUE, then perform dependent Graphics Console\r
874 device reset, and set display mode to mode 0.\r
875 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
876\r
877 @param This Protocol instance pointer.\r
878 @param ExtendedVerification Indicates that the driver may perform a more\r
879 exhaustive verification operation of the device\r
880 during reset.\r
881\r
882 @retval EFI_SUCCESS The text output device was reset.\r
883 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and\r
884 could not be reset.\r
885\r
886**/\r
887EFI_STATUS\r
888EFIAPI\r
889GraphicsConsoleConOutReset (\r
890 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
891 IN BOOLEAN ExtendedVerification\r
892 )\r
893{\r
894 EFI_STATUS Status;\r
895\r
896 Status = This->SetMode (This, 0);\r
897 if (EFI_ERROR (Status)) {\r
898 return Status;\r
899 }\r
900\r
901 Status = This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
902 return Status;\r
903}\r
904\r
905/**\r
906 Write a Unicode string to the output device.\r
907\r
908 Implements SIMPLE_TEXT_OUTPUT.OutputString().\r
909 The Unicode string will be converted to Glyphs and will be\r
910 sent to the Graphics Console.\r
911\r
912 @param This Protocol instance pointer.\r
913 @param WString The NULL-terminated Unicode string to be displayed\r
914 on the output device(s). All output devices must\r
915 also support the Unicode drawing defined in this file.\r
916\r
917 @retval EFI_SUCCESS The string was output to the device.\r
918 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
919 the text.\r
920 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
921 defined text mode.\r
922 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
923 characters in the Unicode string could not be\r
924 rendered and were skipped.\r
925\r
926**/\r
927EFI_STATUS\r
928EFIAPI\r
929GraphicsConsoleConOutOutputString (\r
930 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
931 IN CHAR16 *WString\r
932 )\r
933{\r
934 GRAPHICS_CONSOLE_DEV *Private;\r
935 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
936 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
937 INTN Mode;\r
938 UINTN MaxColumn;\r
939 UINTN MaxRow;\r
940 UINTN Width;\r
941 UINTN Height;\r
942 UINTN Delta;\r
943 EFI_STATUS Status;\r
944 BOOLEAN Warning;\r
945 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
946 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
947 UINTN DeltaX;\r
948 UINTN DeltaY;\r
949 UINTN Count;\r
950 UINTN Index;\r
951 INT32 OriginAttribute;\r
952 EFI_TPL OldTpl;\r
953\r
954 if (This->Mode->Mode == -1) {\r
955 //\r
956 // If current mode is not valid, return error.\r
957 //\r
958 return EFI_UNSUPPORTED;\r
959 }\r
960\r
961 Status = EFI_SUCCESS;\r
962\r
963 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
964 //\r
965 // Current mode\r
966 //\r
967 Mode = This->Mode->Mode;\r
968 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
969 GraphicsOutput = Private->GraphicsOutput;\r
970 UgaDraw = Private->UgaDraw;\r
971\r
972 MaxColumn = Private->ModeData[Mode].Columns;\r
973 MaxRow = Private->ModeData[Mode].Rows;\r
974 DeltaX = (UINTN)Private->ModeData[Mode].DeltaX;\r
975 DeltaY = (UINTN)Private->ModeData[Mode].DeltaY;\r
976 Width = MaxColumn * EFI_GLYPH_WIDTH;\r
977 Height = (MaxRow - 1) * EFI_GLYPH_HEIGHT;\r
978 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
979\r
980 //\r
981 // The Attributes won't change when during the time OutputString is called\r
982 //\r
983 GetTextColors (This, &Foreground, &Background);\r
984\r
985 FlushCursor (This);\r
986\r
987 Warning = FALSE;\r
988\r
989 //\r
990 // Backup attribute\r
991 //\r
992 OriginAttribute = This->Mode->Attribute;\r
993\r
994 while (*WString != L'\0') {\r
995 if (*WString == CHAR_BACKSPACE) {\r
996 //\r
997 // If the cursor is at the left edge of the display, then move the cursor\r
998 // one row up.\r
999 //\r
1000 if ((This->Mode->CursorColumn == 0) && (This->Mode->CursorRow > 0)) {\r
1001 This->Mode->CursorRow--;\r
1002 This->Mode->CursorColumn = (INT32)(MaxColumn - 1);\r
1003 This->OutputString (This, SpaceStr);\r
1004 FlushCursor (This);\r
1005 This->Mode->CursorRow--;\r
1006 This->Mode->CursorColumn = (INT32)(MaxColumn - 1);\r
1007 } else if (This->Mode->CursorColumn > 0) {\r
1008 //\r
1009 // If the cursor is not at the left edge of the display, then move the cursor\r
1010 // left one column.\r
1011 //\r
1012 This->Mode->CursorColumn--;\r
1013 This->OutputString (This, SpaceStr);\r
1014 FlushCursor (This);\r
1015 This->Mode->CursorColumn--;\r
1016 }\r
1017\r
1018 WString++;\r
1019 } else if (*WString == CHAR_LINEFEED) {\r
1020 //\r
1021 // If the cursor is at the bottom of the display, then scroll the display one\r
1022 // row, and do not update the cursor position. Otherwise, move the cursor\r
1023 // down one row.\r
1024 //\r
1025 if (This->Mode->CursorRow == (INT32)(MaxRow - 1)) {\r
1026 if (GraphicsOutput != NULL) {\r
1027 //\r
1028 // Scroll Screen Up One Row\r
1029 //\r
1030 GraphicsOutput->Blt (\r
1031 GraphicsOutput,\r
1032 NULL,\r
1033 EfiBltVideoToVideo,\r
1034 DeltaX,\r
1035 DeltaY + EFI_GLYPH_HEIGHT,\r
1036 DeltaX,\r
1037 DeltaY,\r
1038 Width,\r
1039 Height,\r
1040 Delta\r
1041 );\r
1042\r
1043 //\r
1044 // Print Blank Line at last line\r
1045 //\r
1046 GraphicsOutput->Blt (\r
1047 GraphicsOutput,\r
1048 &Background,\r
1049 EfiBltVideoFill,\r
1050 0,\r
1051 0,\r
1052 DeltaX,\r
1053 DeltaY + Height,\r
1054 Width,\r
1055 EFI_GLYPH_HEIGHT,\r
1056 Delta\r
1057 );\r
1058 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
1059 //\r
1060 // Scroll Screen Up One Row\r
1061 //\r
1062 UgaDraw->Blt (\r
1063 UgaDraw,\r
1064 NULL,\r
1065 EfiUgaVideoToVideo,\r
1066 DeltaX,\r
1067 DeltaY + EFI_GLYPH_HEIGHT,\r
1068 DeltaX,\r
1069 DeltaY,\r
1070 Width,\r
1071 Height,\r
1072 Delta\r
1073 );\r
1074\r
1075 //\r
1076 // Print Blank Line at last line\r
1077 //\r
1078 UgaDraw->Blt (\r
1079 UgaDraw,\r
1080 (EFI_UGA_PIXEL *)(UINTN)&Background,\r
1081 EfiUgaVideoFill,\r
1082 0,\r
1083 0,\r
1084 DeltaX,\r
1085 DeltaY + Height,\r
1086 Width,\r
1087 EFI_GLYPH_HEIGHT,\r
1088 Delta\r
1089 );\r
1090 }\r
1091 } else {\r
1092 This->Mode->CursorRow++;\r
1093 }\r
1094\r
1095 WString++;\r
1096 } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
1097 //\r
1098 // Move the cursor to the beginning of the current row.\r
1099 //\r
1100 This->Mode->CursorColumn = 0;\r
1101 WString++;\r
1102 } else if (*WString == WIDE_CHAR) {\r
1103 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;\r
1104 WString++;\r
1105 } else if (*WString == NARROW_CHAR) {\r
1106 This->Mode->Attribute &= (~(UINT32)EFI_WIDE_ATTRIBUTE);\r
1107 WString++;\r
1108 } else {\r
1109 //\r
1110 // Print the character at the current cursor position and move the cursor\r
1111 // right one column. If this moves the cursor past the right edge of the\r
1112 // display, then the line should wrap to the beginning of the next line. This\r
1113 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the\r
1114 // bottom of the display, and the line wraps, then the display will be scrolled\r
1115 // one line.\r
1116 // If wide char is going to be displayed, need to display one character at a time\r
1117 // Or, need to know the display length of a certain string.\r
1118 //\r
1119 // Index is used to determine how many character width units (wide = 2, narrow = 1)\r
1120 // Count is used to determine how many characters are used regardless of their attributes\r
1121 //\r
1122 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {\r
1123 if ((WString[Count] == CHAR_NULL) ||\r
1124 (WString[Count] == CHAR_BACKSPACE) ||\r
1125 (WString[Count] == CHAR_LINEFEED) ||\r
1126 (WString[Count] == CHAR_CARRIAGE_RETURN) ||\r
1127 (WString[Count] == WIDE_CHAR) ||\r
1128 (WString[Count] == NARROW_CHAR))\r
1129 {\r
1130 break;\r
1131 }\r
1132\r
1133 //\r
1134 // Is the wide attribute on?\r
1135 //\r
1136 if ((This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {\r
1137 //\r
1138 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop\r
1139 //\r
1140 Index++;\r
1141 //\r
1142 // This is the end-case where if we are at column 79 and about to print a wide character\r
1143 // We should prevent this from happening because we will wrap inappropriately. We should\r
1144 // not print this character until the next line.\r
1145 //\r
1146 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {\r
1147 Index++;\r
1148 break;\r
1149 }\r
1150 }\r
1151 }\r
1152\r
1153 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);\r
1154 if (EFI_ERROR (Status)) {\r
1155 Warning = TRUE;\r
1156 }\r
1157\r
1158 //\r
1159 // At the end of line, output carriage return and line feed\r
1160 //\r
1161 WString += Count;\r
1162 This->Mode->CursorColumn += (INT32)Index;\r
1163 if (This->Mode->CursorColumn > (INT32)MaxColumn) {\r
1164 This->Mode->CursorColumn -= 2;\r
1165 This->OutputString (This, SpaceStr);\r
1166 }\r
1167\r
1168 if (This->Mode->CursorColumn >= (INT32)MaxColumn) {\r
1169 FlushCursor (This);\r
1170 This->OutputString (This, mCrLfString);\r
1171 FlushCursor (This);\r
1172 }\r
1173 }\r
1174 }\r
1175\r
1176 This->Mode->Attribute = OriginAttribute;\r
1177\r
1178 FlushCursor (This);\r
1179\r
1180 if (Warning) {\r
1181 Status = EFI_WARN_UNKNOWN_GLYPH;\r
1182 }\r
1183\r
1184 gBS->RestoreTPL (OldTpl);\r
1185 return Status;\r
1186}\r
1187\r
1188/**\r
1189 Verifies that all characters in a Unicode string can be output to the\r
1190 target device.\r
1191\r
1192 Implements SIMPLE_TEXT_OUTPUT.TestString().\r
1193 If one of the characters in the *Wstring is neither valid valid Unicode\r
1194 drawing characters, not ASCII code, then this function will return\r
1195 EFI_UNSUPPORTED\r
1196\r
1197 @param This Protocol instance pointer.\r
1198 @param WString The NULL-terminated Unicode string to be examined for the output\r
1199 device(s).\r
1200\r
1201 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.\r
1202 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be\r
1203 rendered by one or more of the output devices mapped\r
1204 by the EFI handle.\r
1205\r
1206**/\r
1207EFI_STATUS\r
1208EFIAPI\r
1209GraphicsConsoleConOutTestString (\r
1210 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1211 IN CHAR16 *WString\r
1212 )\r
1213{\r
1214 EFI_STATUS Status;\r
1215 UINT16 Count;\r
1216\r
1217 EFI_IMAGE_OUTPUT *Blt;\r
1218\r
1219 Blt = NULL;\r
1220 Count = 0;\r
1221\r
1222 while (WString[Count] != 0) {\r
1223 Status = mHiiFont->GetGlyph (\r
1224 mHiiFont,\r
1225 WString[Count],\r
1226 NULL,\r
1227 &Blt,\r
1228 NULL\r
1229 );\r
1230 if (Blt != NULL) {\r
1231 FreePool (Blt);\r
1232 Blt = NULL;\r
1233 }\r
1234\r
1235 Count++;\r
1236\r
1237 if (EFI_ERROR (Status)) {\r
1238 return EFI_UNSUPPORTED;\r
1239 }\r
1240 }\r
1241\r
1242 return EFI_SUCCESS;\r
1243}\r
1244\r
1245/**\r
1246 Returns information for an available text mode that the output device(s)\r
1247 supports\r
1248\r
1249 Implements SIMPLE_TEXT_OUTPUT.QueryMode().\r
1250 It returnes information for an available text mode that the Graphics Console supports.\r
1251 In this driver,we only support text mode 80x25, which is defined as mode 0.\r
1252\r
1253 @param This Protocol instance pointer.\r
1254 @param ModeNumber The mode number to return information on.\r
1255 @param Columns The returned columns of the requested mode.\r
1256 @param Rows The returned rows of the requested mode.\r
1257\r
1258 @retval EFI_SUCCESS The requested mode information is returned.\r
1259 @retval EFI_UNSUPPORTED The mode number is not valid.\r
1260\r
1261**/\r
1262EFI_STATUS\r
1263EFIAPI\r
1264GraphicsConsoleConOutQueryMode (\r
1265 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1266 IN UINTN ModeNumber,\r
1267 OUT UINTN *Columns,\r
1268 OUT UINTN *Rows\r
1269 )\r
1270{\r
1271 GRAPHICS_CONSOLE_DEV *Private;\r
1272 EFI_STATUS Status;\r
1273 EFI_TPL OldTpl;\r
1274\r
1275 if (ModeNumber >= (UINTN)This->Mode->MaxMode) {\r
1276 return EFI_UNSUPPORTED;\r
1277 }\r
1278\r
1279 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1280 Status = EFI_SUCCESS;\r
1281\r
1282 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1283\r
1284 *Columns = Private->ModeData[ModeNumber].Columns;\r
1285 *Rows = Private->ModeData[ModeNumber].Rows;\r
1286\r
1287 if ((*Columns <= 0) || (*Rows <= 0)) {\r
1288 Status = EFI_UNSUPPORTED;\r
1289 goto Done;\r
1290 }\r
1291\r
1292Done:\r
1293 gBS->RestoreTPL (OldTpl);\r
1294 return Status;\r
1295}\r
1296\r
1297/**\r
1298 Sets the output device(s) to a specified mode.\r
1299\r
1300 Implements SIMPLE_TEXT_OUTPUT.SetMode().\r
1301 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.\r
1302\r
1303 @param This Protocol instance pointer.\r
1304 @param ModeNumber The text mode to set.\r
1305\r
1306 @retval EFI_SUCCESS The requested text mode is set.\r
1307 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of\r
1308 Graphics Console device error.\r
1309 @retval EFI_UNSUPPORTED The text mode number is not valid.\r
1310\r
1311**/\r
1312EFI_STATUS\r
1313EFIAPI\r
1314GraphicsConsoleConOutSetMode (\r
1315 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1316 IN UINTN ModeNumber\r
1317 )\r
1318{\r
1319 EFI_STATUS Status;\r
1320 GRAPHICS_CONSOLE_DEV *Private;\r
1321 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1322 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;\r
1323 UINT32 HorizontalResolution;\r
1324 UINT32 VerticalResolution;\r
1325 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1326 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1327 UINT32 ColorDepth;\r
1328 UINT32 RefreshRate;\r
1329 EFI_TPL OldTpl;\r
1330\r
1331 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1332\r
1333 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1334 GraphicsOutput = Private->GraphicsOutput;\r
1335 UgaDraw = Private->UgaDraw;\r
1336\r
1337 //\r
1338 // Make sure the requested mode number is supported\r
1339 //\r
1340 if (ModeNumber >= (UINTN)This->Mode->MaxMode) {\r
1341 Status = EFI_UNSUPPORTED;\r
1342 goto Done;\r
1343 }\r
1344\r
1345 ModeData = &(Private->ModeData[ModeNumber]);\r
1346\r
1347 if ((ModeData->Columns <= 0) && (ModeData->Rows <= 0)) {\r
1348 Status = EFI_UNSUPPORTED;\r
1349 goto Done;\r
1350 }\r
1351\r
1352 //\r
1353 // If the mode has been set at least one other time, then LineBuffer will not be NULL\r
1354 //\r
1355 if (Private->LineBuffer != NULL) {\r
1356 //\r
1357 // If the new mode is the same as the old mode, then just return EFI_SUCCESS\r
1358 //\r
1359 if ((INT32)ModeNumber == This->Mode->Mode) {\r
1360 //\r
1361 // Clear the current text window on the current graphics console\r
1362 //\r
1363 This->ClearScreen (This);\r
1364 Status = EFI_SUCCESS;\r
1365 goto Done;\r
1366 }\r
1367\r
1368 //\r
1369 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,\r
1370 // so erase the cursor, and free the LineBuffer for the current mode\r
1371 //\r
1372 FlushCursor (This);\r
1373\r
1374 FreePool (Private->LineBuffer);\r
1375 }\r
1376\r
1377 //\r
1378 // Attempt to allocate a line buffer for the requested mode number\r
1379 //\r
1380 NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);\r
1381\r
1382 if (NewLineBuffer == NULL) {\r
1383 //\r
1384 // The new line buffer could not be allocated, so return an error.\r
1385 // No changes to the state of the current console have been made, so the current console is still valid\r
1386 //\r
1387 Status = EFI_OUT_OF_RESOURCES;\r
1388 goto Done;\r
1389 }\r
1390\r
1391 //\r
1392 // Assign the current line buffer to the newly allocated line buffer\r
1393 //\r
1394 Private->LineBuffer = NewLineBuffer;\r
1395\r
1396 if (GraphicsOutput != NULL) {\r
1397 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {\r
1398 //\r
1399 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
1400 //\r
1401 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);\r
1402 if (EFI_ERROR (Status)) {\r
1403 //\r
1404 // The mode set operation failed\r
1405 //\r
1406 goto Done;\r
1407 }\r
1408 } else {\r
1409 //\r
1410 // The current graphics mode is correct, so simply clear the entire display\r
1411 //\r
1412 Status = GraphicsOutput->Blt (\r
1413 GraphicsOutput,\r
1414 &mGraphicsEfiColors[0],\r
1415 EfiBltVideoFill,\r
1416 0,\r
1417 0,\r
1418 0,\r
1419 0,\r
1420 ModeData->GopWidth,\r
1421 ModeData->GopHeight,\r
1422 0\r
1423 );\r
1424 }\r
1425 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
1426 //\r
1427 // Get the current UGA Draw mode information\r
1428 //\r
1429 Status = UgaDraw->GetMode (\r
1430 UgaDraw,\r
1431 &HorizontalResolution,\r
1432 &VerticalResolution,\r
1433 &ColorDepth,\r
1434 &RefreshRate\r
1435 );\r
1436 if (EFI_ERROR (Status) || (HorizontalResolution != ModeData->GopWidth) || (VerticalResolution != ModeData->GopHeight)) {\r
1437 //\r
1438 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode\r
1439 //\r
1440 Status = UgaDraw->SetMode (\r
1441 UgaDraw,\r
1442 ModeData->GopWidth,\r
1443 ModeData->GopHeight,\r
1444 32,\r
1445 60\r
1446 );\r
1447 if (EFI_ERROR (Status)) {\r
1448 //\r
1449 // The mode set operation failed\r
1450 //\r
1451 goto Done;\r
1452 }\r
1453 } else {\r
1454 //\r
1455 // The current graphics mode is correct, so simply clear the entire display\r
1456 //\r
1457 Status = UgaDraw->Blt (\r
1458 UgaDraw,\r
1459 (EFI_UGA_PIXEL *)(UINTN)&mGraphicsEfiColors[0],\r
1460 EfiUgaVideoFill,\r
1461 0,\r
1462 0,\r
1463 0,\r
1464 0,\r
1465 ModeData->GopWidth,\r
1466 ModeData->GopHeight,\r
1467 0\r
1468 );\r
1469 }\r
1470 }\r
1471\r
1472 //\r
1473 // The new mode is valid, so commit the mode change\r
1474 //\r
1475 This->Mode->Mode = (INT32)ModeNumber;\r
1476\r
1477 //\r
1478 // Move the text cursor to the upper left hand corner of the display and flush it\r
1479 //\r
1480 This->Mode->CursorColumn = 0;\r
1481 This->Mode->CursorRow = 0;\r
1482\r
1483 FlushCursor (This);\r
1484\r
1485 Status = EFI_SUCCESS;\r
1486\r
1487Done:\r
1488 gBS->RestoreTPL (OldTpl);\r
1489 return Status;\r
1490}\r
1491\r
1492/**\r
1493 Sets the background and foreground colors for the OutputString () and\r
1494 ClearScreen () functions.\r
1495\r
1496 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().\r
1497\r
1498 @param This Protocol instance pointer.\r
1499 @param Attribute The attribute to set. Bits 0..3 are the foreground\r
1500 color, and bits 4..6 are the background color.\r
1501 All other bits are undefined and must be zero.\r
1502\r
1503 @retval EFI_SUCCESS The requested attribute is set.\r
1504 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.\r
1505 @retval EFI_UNSUPPORTED The attribute requested is not defined.\r
1506\r
1507**/\r
1508EFI_STATUS\r
1509EFIAPI\r
1510GraphicsConsoleConOutSetAttribute (\r
1511 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1512 IN UINTN Attribute\r
1513 )\r
1514{\r
1515 EFI_TPL OldTpl;\r
1516\r
1517 if ((Attribute | 0x7F) != 0x7F) {\r
1518 return EFI_UNSUPPORTED;\r
1519 }\r
1520\r
1521 if ((INT32)Attribute == This->Mode->Attribute) {\r
1522 return EFI_SUCCESS;\r
1523 }\r
1524\r
1525 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1526\r
1527 FlushCursor (This);\r
1528\r
1529 This->Mode->Attribute = (INT32)Attribute;\r
1530\r
1531 FlushCursor (This);\r
1532\r
1533 gBS->RestoreTPL (OldTpl);\r
1534\r
1535 return EFI_SUCCESS;\r
1536}\r
1537\r
1538/**\r
1539 Clears the output device(s) display to the currently selected background\r
1540 color.\r
1541\r
1542 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().\r
1543\r
1544 @param This Protocol instance pointer.\r
1545\r
1546 @retval EFI_SUCCESS The operation completed successfully.\r
1547 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
1548 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
1549\r
1550**/\r
1551EFI_STATUS\r
1552EFIAPI\r
1553GraphicsConsoleConOutClearScreen (\r
1554 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1555 )\r
1556{\r
1557 EFI_STATUS Status;\r
1558 GRAPHICS_CONSOLE_DEV *Private;\r
1559 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1560 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1561 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1562 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1563 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1564 EFI_TPL OldTpl;\r
1565\r
1566 if (This->Mode->Mode == -1) {\r
1567 //\r
1568 // If current mode is not valid, return error.\r
1569 //\r
1570 return EFI_UNSUPPORTED;\r
1571 }\r
1572\r
1573 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1574\r
1575 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1576 GraphicsOutput = Private->GraphicsOutput;\r
1577 UgaDraw = Private->UgaDraw;\r
1578 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1579\r
1580 GetTextColors (This, &Foreground, &Background);\r
1581 if (GraphicsOutput != NULL) {\r
1582 Status = GraphicsOutput->Blt (\r
1583 GraphicsOutput,\r
1584 &Background,\r
1585 EfiBltVideoFill,\r
1586 0,\r
1587 0,\r
1588 0,\r
1589 0,\r
1590 ModeData->GopWidth,\r
1591 ModeData->GopHeight,\r
1592 0\r
1593 );\r
1594 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
1595 Status = UgaDraw->Blt (\r
1596 UgaDraw,\r
1597 (EFI_UGA_PIXEL *)(UINTN)&Background,\r
1598 EfiUgaVideoFill,\r
1599 0,\r
1600 0,\r
1601 0,\r
1602 0,\r
1603 ModeData->GopWidth,\r
1604 ModeData->GopHeight,\r
1605 0\r
1606 );\r
1607 } else {\r
1608 Status = EFI_UNSUPPORTED;\r
1609 }\r
1610\r
1611 This->Mode->CursorColumn = 0;\r
1612 This->Mode->CursorRow = 0;\r
1613\r
1614 FlushCursor (This);\r
1615\r
1616 gBS->RestoreTPL (OldTpl);\r
1617\r
1618 return Status;\r
1619}\r
1620\r
1621/**\r
1622 Sets the current coordinates of the cursor position.\r
1623\r
1624 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().\r
1625\r
1626 @param This Protocol instance pointer.\r
1627 @param Column The position to set the cursor to. Must be greater than or\r
1628 equal to zero and less than the number of columns and rows\r
1629 by QueryMode ().\r
1630 @param Row The position to set the cursor to. Must be greater than or\r
1631 equal to zero and less than the number of columns and rows\r
1632 by QueryMode ().\r
1633\r
1634 @retval EFI_SUCCESS The operation completed successfully.\r
1635 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
1636 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the\r
1637 cursor position is invalid for the current mode.\r
1638\r
1639**/\r
1640EFI_STATUS\r
1641EFIAPI\r
1642GraphicsConsoleConOutSetCursorPosition (\r
1643 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1644 IN UINTN Column,\r
1645 IN UINTN Row\r
1646 )\r
1647{\r
1648 GRAPHICS_CONSOLE_DEV *Private;\r
1649 GRAPHICS_CONSOLE_MODE_DATA *ModeData;\r
1650 EFI_STATUS Status;\r
1651 EFI_TPL OldTpl;\r
1652\r
1653 if (This->Mode->Mode == -1) {\r
1654 //\r
1655 // If current mode is not valid, return error.\r
1656 //\r
1657 return EFI_UNSUPPORTED;\r
1658 }\r
1659\r
1660 Status = EFI_SUCCESS;\r
1661\r
1662 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1663\r
1664 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1665 ModeData = &(Private->ModeData[This->Mode->Mode]);\r
1666\r
1667 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {\r
1668 Status = EFI_UNSUPPORTED;\r
1669 goto Done;\r
1670 }\r
1671\r
1672 if ((This->Mode->CursorColumn == (INT32)Column) && (This->Mode->CursorRow == (INT32)Row)) {\r
1673 Status = EFI_SUCCESS;\r
1674 goto Done;\r
1675 }\r
1676\r
1677 FlushCursor (This);\r
1678\r
1679 This->Mode->CursorColumn = (INT32)Column;\r
1680 This->Mode->CursorRow = (INT32)Row;\r
1681\r
1682 FlushCursor (This);\r
1683\r
1684Done:\r
1685 gBS->RestoreTPL (OldTpl);\r
1686\r
1687 return Status;\r
1688}\r
1689\r
1690/**\r
1691 Makes the cursor visible or invisible.\r
1692\r
1693 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
1694\r
1695 @param This Protocol instance pointer.\r
1696 @param Visible If TRUE, the cursor is set to be visible, If FALSE,\r
1697 the cursor is set to be invisible.\r
1698\r
1699 @retval EFI_SUCCESS The operation completed successfully.\r
1700 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
1701 defined text mode.\r
1702\r
1703**/\r
1704EFI_STATUS\r
1705EFIAPI\r
1706GraphicsConsoleConOutEnableCursor (\r
1707 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1708 IN BOOLEAN Visible\r
1709 )\r
1710{\r
1711 EFI_TPL OldTpl;\r
1712\r
1713 if (This->Mode->Mode == -1) {\r
1714 //\r
1715 // If current mode is not valid, return error.\r
1716 //\r
1717 return EFI_UNSUPPORTED;\r
1718 }\r
1719\r
1720 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
1721\r
1722 FlushCursor (This);\r
1723\r
1724 This->Mode->CursorVisible = Visible;\r
1725\r
1726 FlushCursor (This);\r
1727\r
1728 gBS->RestoreTPL (OldTpl);\r
1729 return EFI_SUCCESS;\r
1730}\r
1731\r
1732/**\r
1733 Gets Graphics Console device's foreground color and background color.\r
1734\r
1735 @param This Protocol instance pointer.\r
1736 @param Foreground Returned text foreground color.\r
1737 @param Background Returned text background color.\r
1738\r
1739 @retval EFI_SUCCESS It returned always.\r
1740\r
1741**/\r
1742EFI_STATUS\r
1743GetTextColors (\r
1744 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1745 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,\r
1746 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background\r
1747 )\r
1748{\r
1749 INTN Attribute;\r
1750\r
1751 Attribute = This->Mode->Attribute & 0x7F;\r
1752\r
1753 *Foreground = mGraphicsEfiColors[Attribute & 0x0f];\r
1754 *Background = mGraphicsEfiColors[Attribute >> 4];\r
1755\r
1756 return EFI_SUCCESS;\r
1757}\r
1758\r
1759/**\r
1760 Draw Unicode string on the Graphics Console device's screen.\r
1761\r
1762 @param This Protocol instance pointer.\r
1763 @param UnicodeWeight One Unicode string to be displayed.\r
1764 @param Count The count of Unicode string.\r
1765\r
1766 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.\r
1767 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw\r
1768 protocol exist.\r
1769 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.\r
1770\r
1771**/\r
1772EFI_STATUS\r
1773DrawUnicodeWeightAtCursorN (\r
1774 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1775 IN CHAR16 *UnicodeWeight,\r
1776 IN UINTN Count\r
1777 )\r
1778{\r
1779 EFI_STATUS Status;\r
1780 GRAPHICS_CONSOLE_DEV *Private;\r
1781 EFI_IMAGE_OUTPUT *Blt;\r
1782 EFI_STRING String;\r
1783 EFI_FONT_DISPLAY_INFO *FontInfo;\r
1784 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1785 EFI_HII_ROW_INFO *RowInfoArray;\r
1786 UINTN RowInfoArraySize;\r
1787\r
1788 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1789 Blt = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1790 if (Blt == NULL) {\r
1791 return EFI_OUT_OF_RESOURCES;\r
1792 }\r
1793\r
1794 Blt->Width = (UINT16)(Private->ModeData[This->Mode->Mode].GopWidth);\r
1795 Blt->Height = (UINT16)(Private->ModeData[This->Mode->Mode].GopHeight);\r
1796\r
1797 String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);\r
1798 if (String == NULL) {\r
1799 FreePool (Blt);\r
1800 return EFI_OUT_OF_RESOURCES;\r
1801 }\r
1802\r
1803 //\r
1804 // Set the end character\r
1805 //\r
1806 *(String + Count) = L'\0';\r
1807\r
1808 FontInfo = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
1809 if (FontInfo == NULL) {\r
1810 FreePool (Blt);\r
1811 FreePool (String);\r
1812 return EFI_OUT_OF_RESOURCES;\r
1813 }\r
1814\r
1815 //\r
1816 // Get current foreground and background colors.\r
1817 //\r
1818 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);\r
1819\r
1820 if (Private->GraphicsOutput != NULL) {\r
1821 //\r
1822 // If Graphics Output protocol exists, using HII Font protocol to draw.\r
1823 //\r
1824 Blt->Image.Screen = Private->GraphicsOutput;\r
1825\r
1826 Status = mHiiFont->StringToImage (\r
1827 mHiiFont,\r
1828 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN | EFI_HII_IGNORE_LINE_BREAK,\r
1829 String,\r
1830 FontInfo,\r
1831 &Blt,\r
1832 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1833 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
1834 NULL,\r
1835 NULL,\r
1836 NULL\r
1837 );\r
1838 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
1839 //\r
1840 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,\r
1841 // using UGA Draw protocol to draw.\r
1842 //\r
1843 ASSERT (Private->UgaDraw != NULL);\r
1844\r
1845 UgaDraw = Private->UgaDraw;\r
1846\r
1847 Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
1848 if (Blt->Image.Bitmap == NULL) {\r
1849 FreePool (Blt);\r
1850 FreePool (String);\r
1851 return EFI_OUT_OF_RESOURCES;\r
1852 }\r
1853\r
1854 RowInfoArray = NULL;\r
1855 //\r
1856 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,\r
1857 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.\r
1858 //\r
1859 Status = mHiiFont->StringToImage (\r
1860 mHiiFont,\r
1861 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK,\r
1862 String,\r
1863 FontInfo,\r
1864 &Blt,\r
1865 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1866 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
1867 &RowInfoArray,\r
1868 &RowInfoArraySize,\r
1869 NULL\r
1870 );\r
1871\r
1872 if (!EFI_ERROR (Status)) {\r
1873 //\r
1874 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will\r
1875 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.\r
1876 //\r
1877 ASSERT (RowInfoArraySize <= 1);\r
1878\r
1879 Status = UgaDraw->Blt (\r
1880 UgaDraw,\r
1881 (EFI_UGA_PIXEL *)Blt->Image.Bitmap,\r
1882 EfiUgaBltBufferToVideo,\r
1883 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1884 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
1885 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,\r
1886 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,\r
1887 RowInfoArray[0].LineWidth,\r
1888 RowInfoArray[0].LineHeight,\r
1889 Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1890 );\r
1891 }\r
1892\r
1893 FreePool (RowInfoArray);\r
1894 FreePool (Blt->Image.Bitmap);\r
1895 } else {\r
1896 Status = EFI_UNSUPPORTED;\r
1897 }\r
1898\r
1899 if (Blt != NULL) {\r
1900 FreePool (Blt);\r
1901 }\r
1902\r
1903 if (String != NULL) {\r
1904 FreePool (String);\r
1905 }\r
1906\r
1907 if (FontInfo != NULL) {\r
1908 FreePool (FontInfo);\r
1909 }\r
1910\r
1911 return Status;\r
1912}\r
1913\r
1914/**\r
1915 Flush the cursor on the screen.\r
1916\r
1917 If CursorVisible is FALSE, nothing to do and return directly.\r
1918 If CursorVisible is TRUE,\r
1919 i) If the cursor shows on screen, it will be erased.\r
1920 ii) If the cursor does not show on screen, it will be shown.\r
1921\r
1922 @param This Protocol instance pointer.\r
1923\r
1924 @retval EFI_SUCCESS The cursor is erased successfully.\r
1925\r
1926**/\r
1927EFI_STATUS\r
1928FlushCursor (\r
1929 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1930 )\r
1931{\r
1932 GRAPHICS_CONSOLE_DEV *Private;\r
1933 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;\r
1934 INTN GlyphX;\r
1935 INTN GlyphY;\r
1936 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1937 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
1938 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;\r
1939 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;\r
1940 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];\r
1941 UINTN PosX;\r
1942 UINTN PosY;\r
1943\r
1944 CurrentMode = This->Mode;\r
1945\r
1946 if (!CurrentMode->CursorVisible) {\r
1947 return EFI_SUCCESS;\r
1948 }\r
1949\r
1950 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);\r
1951 GraphicsOutput = Private->GraphicsOutput;\r
1952 UgaDraw = Private->UgaDraw;\r
1953\r
1954 //\r
1955 // In this driver, only narrow character was supported.\r
1956 //\r
1957 //\r
1958 // Blt a character to the screen\r
1959 //\r
1960 GlyphX = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;\r
1961 GlyphY = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;\r
1962 if (GraphicsOutput != NULL) {\r
1963 GraphicsOutput->Blt (\r
1964 GraphicsOutput,\r
1965 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)BltChar,\r
1966 EfiBltVideoToBltBuffer,\r
1967 GlyphX,\r
1968 GlyphY,\r
1969 0,\r
1970 0,\r
1971 EFI_GLYPH_WIDTH,\r
1972 EFI_GLYPH_HEIGHT,\r
1973 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1974 );\r
1975 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
1976 UgaDraw->Blt (\r
1977 UgaDraw,\r
1978 (EFI_UGA_PIXEL *)(UINTN)BltChar,\r
1979 EfiUgaVideoToBltBuffer,\r
1980 GlyphX,\r
1981 GlyphY,\r
1982 0,\r
1983 0,\r
1984 EFI_GLYPH_WIDTH,\r
1985 EFI_GLYPH_HEIGHT,\r
1986 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
1987 );\r
1988 }\r
1989\r
1990 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);\r
1991\r
1992 //\r
1993 // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
1994 //\r
1995 for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {\r
1996 for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {\r
1997 if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {\r
1998 BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;\r
1999 }\r
2000 }\r
2001 }\r
2002\r
2003 if (GraphicsOutput != NULL) {\r
2004 GraphicsOutput->Blt (\r
2005 GraphicsOutput,\r
2006 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)BltChar,\r
2007 EfiBltBufferToVideo,\r
2008 0,\r
2009 0,\r
2010 GlyphX,\r
2011 GlyphY,\r
2012 EFI_GLYPH_WIDTH,\r
2013 EFI_GLYPH_HEIGHT,\r
2014 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
2015 );\r
2016 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
2017 UgaDraw->Blt (\r
2018 UgaDraw,\r
2019 (EFI_UGA_PIXEL *)(UINTN)BltChar,\r
2020 EfiUgaBltBufferToVideo,\r
2021 0,\r
2022 0,\r
2023 GlyphX,\r
2024 GlyphY,\r
2025 EFI_GLYPH_WIDTH,\r
2026 EFI_GLYPH_HEIGHT,\r
2027 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)\r
2028 );\r
2029 }\r
2030\r
2031 return EFI_SUCCESS;\r
2032}\r
2033\r
2034/**\r
2035 HII Database Protocol notification event handler.\r
2036\r
2037 Register font package when HII Database Protocol has been installed.\r
2038\r
2039 @param[in] Event Event whose notification function is being invoked.\r
2040 @param[in] Context Pointer to the notification function's context.\r
2041**/\r
2042VOID\r
2043EFIAPI\r
2044RegisterFontPackage (\r
2045 IN EFI_EVENT Event,\r
2046 IN VOID *Context\r
2047 )\r
2048{\r
2049 EFI_STATUS Status;\r
2050 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;\r
2051 UINT32 PackageLength;\r
2052 UINT8 *Package;\r
2053 UINT8 *Location;\r
2054 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
2055\r
2056 //\r
2057 // Locate HII Database Protocol\r
2058 //\r
2059 Status = gBS->LocateProtocol (\r
2060 &gEfiHiiDatabaseProtocolGuid,\r
2061 NULL,\r
2062 (VOID **)&HiiDatabase\r
2063 );\r
2064 if (EFI_ERROR (Status)) {\r
2065 return;\r
2066 }\r
2067\r
2068 //\r
2069 // Add 4 bytes to the header for entire length for HiiAddPackages use only.\r
2070 //\r
2071 // +--------------------------------+ <-- Package\r
2072 // | |\r
2073 // | PackageLength(4 bytes) |\r
2074 // | |\r
2075 // |--------------------------------| <-- SimplifiedFont\r
2076 // | |\r
2077 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |\r
2078 // | |\r
2079 // |--------------------------------| <-- Location\r
2080 // | |\r
2081 // | gUsStdNarrowGlyphData |\r
2082 // | |\r
2083 // +--------------------------------+\r
2084\r
2085 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;\r
2086 Package = AllocateZeroPool (PackageLength);\r
2087 ASSERT (Package != NULL);\r
2088\r
2089 WriteUnaligned32 ((UINT32 *)Package, PackageLength);\r
2090 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)(Package + 4);\r
2091 SimplifiedFont->Header.Length = (UINT32)(PackageLength - 4);\r
2092 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
2093 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16)(mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));\r
2094\r
2095 Location = (UINT8 *)(&SimplifiedFont->NumberOfWideGlyphs + 1);\r
2096 CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);\r
2097\r
2098 //\r
2099 // Add this simplified font package to a package list then install it.\r
2100 //\r
2101 mHiiHandle = HiiAddPackages (\r
2102 &mFontPackageListGuid,\r
2103 NULL,\r
2104 Package,\r
2105 NULL\r
2106 );\r
2107 ASSERT (mHiiHandle != NULL);\r
2108 FreePool (Package);\r
2109}\r
2110\r
2111/**\r
2112 The user Entry Point for module GraphicsConsole. The user code starts with this function.\r
2113\r
2114 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
2115 @param[in] SystemTable A pointer to the EFI System Table.\r
2116\r
2117 @retval EFI_SUCCESS The entry point is executed successfully.\r
2118 @return other Some error occurs when executing this entry point.\r
2119\r
2120**/\r
2121EFI_STATUS\r
2122EFIAPI\r
2123InitializeGraphicsConsole (\r
2124 IN EFI_HANDLE ImageHandle,\r
2125 IN EFI_SYSTEM_TABLE *SystemTable\r
2126 )\r
2127{\r
2128 EFI_STATUS Status;\r
2129\r
2130 //\r
2131 // Register notify function on HII Database Protocol to add font package.\r
2132 //\r
2133 EfiCreateProtocolNotifyEvent (\r
2134 &gEfiHiiDatabaseProtocolGuid,\r
2135 TPL_CALLBACK,\r
2136 RegisterFontPackage,\r
2137 NULL,\r
2138 &mHiiRegistration\r
2139 );\r
2140\r
2141 //\r
2142 // Install driver model protocol(s).\r
2143 //\r
2144 Status = EfiLibInstallDriverBindingComponentName2 (\r
2145 ImageHandle,\r
2146 SystemTable,\r
2147 &gGraphicsConsoleDriverBinding,\r
2148 ImageHandle,\r
2149 &gGraphicsConsoleComponentName,\r
2150 &gGraphicsConsoleComponentName2\r
2151 );\r
2152 ASSERT_EFI_ERROR (Status);\r
2153\r
2154 return Status;\r
2155}\r