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