]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
Set graphic mode if graphic mode is not same with the one which GraphicsConsole drive...
[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 if (ModeNumber != Private->GraphicsOutput->Mode->Mode) {
501 //
502 // Current graphics mode is not set or is not set to the mode which we has found,
503 // set the new graphic mode.
504 //
505 Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);
506 if (EFI_ERROR (Status)) {
507 //
508 // The mode set operation failed
509 //
510 goto Error;
511 }
512 }
513 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
514 //
515 // At first try to set user-defined resolution
516 //
517 ColorDepth = 32;
518 RefreshRate = 60;
519 Status = Private->UgaDraw->SetMode (
520 Private->UgaDraw,
521 HorizontalResolution,
522 VerticalResolution,
523 ColorDepth,
524 RefreshRate
525 );
526 if (EFI_ERROR (Status)) {
527 //
528 // Try to set 800*600 which is required by UEFI/EFI spec
529 //
530 Status = Private->UgaDraw->SetMode (
531 Private->UgaDraw,
532 800,
533 600,
534 ColorDepth,
535 RefreshRate
536 );
537 if (EFI_ERROR (Status)) {
538 Status = Private->UgaDraw->GetMode (
539 Private->UgaDraw,
540 &HorizontalResolution,
541 &VerticalResolution,
542 &ColorDepth,
543 &RefreshRate
544 );
545 if (EFI_ERROR (Status)) {
546 goto Error;
547 }
548 }
549 }
550 }
551
552 //
553 // Initialize the mode which GraphicsConsole supports.
554 //
555 Status = InitializeGraphicsConsoleTextMode (
556 HorizontalResolution,
557 VerticalResolution,
558 ModeNumber,
559 &MaxMode,
560 &Private->ModeData
561 );
562
563 if (EFI_ERROR (Status)) {
564 goto Error;
565 }
566
567 //
568 // Update the maximum number of modes
569 //
570 Private->SimpleTextOutputMode.MaxMode = (INT32) MaxMode;
571
572 DEBUG_CODE_BEGIN ();
573 Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);
574 if (EFI_ERROR (Status)) {
575 goto Error;
576 }
577 Status = GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");
578 if (EFI_ERROR (Status)) {
579 goto Error;
580 }
581 DEBUG_CODE_END ();
582
583 //
584 // Install protocol interfaces for the Graphics Console device.
585 //
586 Status = gBS->InstallMultipleProtocolInterfaces (
587 &Controller,
588 &gEfiSimpleTextOutProtocolGuid,
589 &Private->SimpleTextOutput,
590 NULL
591 );
592
593 Error:
594 if (EFI_ERROR (Status)) {
595 //
596 // Close the GOP and UGA Draw Protocol
597 //
598 if (Private->GraphicsOutput != NULL) {
599 gBS->CloseProtocol (
600 Controller,
601 &gEfiGraphicsOutputProtocolGuid,
602 This->DriverBindingHandle,
603 Controller
604 );
605 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
606 gBS->CloseProtocol (
607 Controller,
608 &gEfiUgaDrawProtocolGuid,
609 This->DriverBindingHandle,
610 Controller
611 );
612 }
613
614 if (Private->LineBuffer != NULL) {
615 FreePool (Private->LineBuffer);
616 }
617
618 if (Private->ModeData != NULL) {
619 FreePool (Private->ModeData);
620 }
621
622 //
623 // Free private data
624 //
625 FreePool (Private);
626 }
627
628 return Status;
629 }
630
631 /**
632 Stop this driver on Controller by removing Simple Text Out protocol
633 and closing the Graphics Output Protocol or UGA Draw protocol on Controller.
634 (UGA Draw protocol could be skipped if PcdUgaConsumeSupport is set to FALSE.)
635
636
637 @param This Protocol instance pointer.
638 @param Controller Handle of device to stop driver on
639 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
640 children is zero stop the entire bus driver.
641 @param ChildHandleBuffer List of Child Handles to Stop.
642
643 @retval EFI_SUCCESS This driver is removed Controller.
644 @retval EFI_NOT_STARTED Simple Text Out protocol could not be found the
645 Controller.
646 @retval other This driver was not removed from this device.
647
648 **/
649 EFI_STATUS
650 EFIAPI
651 GraphicsConsoleControllerDriverStop (
652 IN EFI_DRIVER_BINDING_PROTOCOL *This,
653 IN EFI_HANDLE Controller,
654 IN UINTN NumberOfChildren,
655 IN EFI_HANDLE *ChildHandleBuffer
656 )
657 {
658 EFI_STATUS Status;
659 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;
660 GRAPHICS_CONSOLE_DEV *Private;
661
662 Status = gBS->OpenProtocol (
663 Controller,
664 &gEfiSimpleTextOutProtocolGuid,
665 (VOID **) &SimpleTextOutput,
666 This->DriverBindingHandle,
667 Controller,
668 EFI_OPEN_PROTOCOL_GET_PROTOCOL
669 );
670 if (EFI_ERROR (Status)) {
671 return EFI_NOT_STARTED;
672 }
673
674 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);
675
676 Status = gBS->UninstallProtocolInterface (
677 Controller,
678 &gEfiSimpleTextOutProtocolGuid,
679 &Private->SimpleTextOutput
680 );
681
682 if (!EFI_ERROR (Status)) {
683 //
684 // Close the GOP or UGA IO Protocol
685 //
686 if (Private->GraphicsOutput != NULL) {
687 gBS->CloseProtocol (
688 Controller,
689 &gEfiGraphicsOutputProtocolGuid,
690 This->DriverBindingHandle,
691 Controller
692 );
693 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
694 gBS->CloseProtocol (
695 Controller,
696 &gEfiUgaDrawProtocolGuid,
697 This->DriverBindingHandle,
698 Controller
699 );
700 }
701
702 if (Private->LineBuffer != NULL) {
703 FreePool (Private->LineBuffer);
704 }
705
706 if (Private->ModeData != NULL) {
707 FreePool (Private->ModeData);
708 }
709
710 //
711 // Free our instance data
712 //
713 FreePool (Private);
714 }
715
716 return Status;
717 }
718
719 /**
720 Check if the current specific mode supported the user defined resolution
721 for the Graphics Console device based on Graphics Output Protocol.
722
723 If yes, set the graphic devcice's current mode to this specific mode.
724
725 @param GraphicsOutput Graphics Output Protocol instance pointer.
726 @param HorizontalResolution User defined horizontal resolution
727 @param VerticalResolution User defined vertical resolution.
728 @param CurrentModeNumber Current specific mode to be check.
729
730 @retval EFI_SUCCESS The mode is supported.
731 @retval EFI_UNSUPPORTED The specific mode is out of range of graphics
732 device supported.
733 @retval other The specific mode does not support user defined
734 resolution or failed to set the current mode to the
735 specific mode on graphics device.
736
737 **/
738 EFI_STATUS
739 CheckModeSupported (
740 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
741 IN UINT32 HorizontalResolution,
742 IN UINT32 VerticalResolution,
743 OUT UINT32 *CurrentModeNumber
744 )
745 {
746 UINT32 ModeNumber;
747 EFI_STATUS Status;
748 UINTN SizeOfInfo;
749 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
750 UINT32 MaxMode;
751
752 Status = EFI_SUCCESS;
753 MaxMode = GraphicsOutput->Mode->MaxMode;
754
755 for (ModeNumber = 0; ModeNumber < MaxMode; ModeNumber++) {
756 Status = GraphicsOutput->QueryMode (
757 GraphicsOutput,
758 ModeNumber,
759 &SizeOfInfo,
760 &Info
761 );
762 if (!EFI_ERROR (Status)) {
763 if ((Info->HorizontalResolution == HorizontalResolution) &&
764 (Info->VerticalResolution == VerticalResolution)) {
765 if ((GraphicsOutput->Mode->Info->HorizontalResolution == HorizontalResolution) &&
766 (GraphicsOutput->Mode->Info->VerticalResolution == VerticalResolution)) {
767 //
768 // If video device has been set to this mode, we do not need to SetMode again
769 //
770 FreePool (Info);
771 break;
772 } else {
773 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
774 if (!EFI_ERROR (Status)) {
775 FreePool (Info);
776 break;
777 }
778 }
779 }
780 FreePool (Info);
781 }
782 }
783
784 if (ModeNumber == GraphicsOutput->Mode->MaxMode) {
785 Status = EFI_UNSUPPORTED;
786 }
787
788 *CurrentModeNumber = ModeNumber;
789 return Status;
790 }
791
792
793 /**
794 Locate HII Database protocol and HII Font protocol.
795
796 @retval EFI_SUCCESS HII Database protocol and HII Font protocol
797 are located successfully.
798 @return other Failed to locate HII Database protocol or
799 HII Font protocol.
800
801 **/
802 EFI_STATUS
803 EfiLocateHiiProtocol (
804 VOID
805 )
806 {
807 EFI_HANDLE Handle;
808 UINTN Size;
809 EFI_STATUS Status;
810
811 //
812 // There should only be one - so buffer size is this
813 //
814 Size = sizeof (EFI_HANDLE);
815
816 Status = gBS->LocateHandle (
817 ByProtocol,
818 &gEfiHiiDatabaseProtocolGuid,
819 NULL,
820 &Size,
821 (VOID **) &Handle
822 );
823
824 if (EFI_ERROR (Status)) {
825 return Status;
826 }
827
828 Status = gBS->HandleProtocol (
829 Handle,
830 &gEfiHiiDatabaseProtocolGuid,
831 (VOID **) &mHiiDatabase
832 );
833
834 if (EFI_ERROR (Status)) {
835 return Status;
836 }
837
838 Status = gBS->HandleProtocol (
839 Handle,
840 &gEfiHiiFontProtocolGuid,
841 (VOID **) &mHiiFont
842 );
843 return Status;
844 }
845
846 //
847 // Body of the STO functions
848 //
849
850 /**
851 Reset the text output device hardware and optionally run diagnostics.
852
853 Implements SIMPLE_TEXT_OUTPUT.Reset().
854 If ExtendeVerification is TRUE, then perform dependent Graphics Console
855 device reset, and set display mode to mode 0.
856 If ExtendedVerification is FALSE, only set display mode to mode 0.
857
858 @param This Protocol instance pointer.
859 @param ExtendedVerification Indicates that the driver may perform a more
860 exhaustive verification operation of the device
861 during reset.
862
863 @retval EFI_SUCCESS The text output device was reset.
864 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and
865 could not be reset.
866
867 **/
868 EFI_STATUS
869 EFIAPI
870 GraphicsConsoleConOutReset (
871 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
872 IN BOOLEAN ExtendedVerification
873 )
874 {
875 EFI_STATUS Status;
876 Status = This->SetMode (This, 0);
877 if (EFI_ERROR (Status)) {
878 return Status;
879 }
880 Status = This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
881 return Status;
882 }
883
884
885 /**
886 Write a Unicode string to the output device.
887
888 Implements SIMPLE_TEXT_OUTPUT.OutputString().
889 The Unicode string will be converted to Glyphs and will be
890 sent to the Graphics Console.
891
892 @param This Protocol instance pointer.
893 @param WString The NULL-terminated Unicode string to be displayed
894 on the output device(s). All output devices must
895 also support the Unicode drawing defined in this file.
896
897 @retval EFI_SUCCESS The string was output to the device.
898 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
899 the text.
900 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
901 defined text mode.
902 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
903 characters in the Unicode string could not be
904 rendered and were skipped.
905
906 **/
907 EFI_STATUS
908 EFIAPI
909 GraphicsConsoleConOutOutputString (
910 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
911 IN CHAR16 *WString
912 )
913 {
914 GRAPHICS_CONSOLE_DEV *Private;
915 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
916 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
917 INTN Mode;
918 UINTN MaxColumn;
919 UINTN MaxRow;
920 UINTN Width;
921 UINTN Height;
922 UINTN Delta;
923 EFI_STATUS Status;
924 BOOLEAN Warning;
925 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
926 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
927 UINTN DeltaX;
928 UINTN DeltaY;
929 UINTN Count;
930 UINTN Index;
931 INT32 OriginAttribute;
932 EFI_TPL OldTpl;
933
934 if (This->Mode->Mode == -1) {
935 //
936 // If current mode is not valid, return error.
937 //
938 return EFI_UNSUPPORTED;
939 }
940
941 Status = EFI_SUCCESS;
942
943 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
944 //
945 // Current mode
946 //
947 Mode = This->Mode->Mode;
948 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
949 GraphicsOutput = Private->GraphicsOutput;
950 UgaDraw = Private->UgaDraw;
951
952 MaxColumn = Private->ModeData[Mode].Columns;
953 MaxRow = Private->ModeData[Mode].Rows;
954 DeltaX = (UINTN) Private->ModeData[Mode].DeltaX;
955 DeltaY = (UINTN) Private->ModeData[Mode].DeltaY;
956 Width = MaxColumn * EFI_GLYPH_WIDTH;
957 Height = (MaxRow - 1) * EFI_GLYPH_HEIGHT;
958 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
959
960 //
961 // The Attributes won't change when during the time OutputString is called
962 //
963 GetTextColors (This, &Foreground, &Background);
964
965 FlushCursor (This);
966
967 Warning = FALSE;
968
969 //
970 // Backup attribute
971 //
972 OriginAttribute = This->Mode->Attribute;
973
974 while (*WString != L'\0') {
975
976 if (*WString == CHAR_BACKSPACE) {
977 //
978 // If the cursor is at the left edge of the display, then move the cursor
979 // one row up.
980 //
981 if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {
982 This->Mode->CursorRow--;
983 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);
984 This->OutputString (This, SpaceStr);
985 FlushCursor (This);
986 This->Mode->CursorRow--;
987 This->Mode->CursorColumn = (INT32) (MaxColumn - 1);
988 } else if (This->Mode->CursorColumn > 0) {
989 //
990 // If the cursor is not at the left edge of the display, then move the cursor
991 // left one column.
992 //
993 This->Mode->CursorColumn--;
994 This->OutputString (This, SpaceStr);
995 FlushCursor (This);
996 This->Mode->CursorColumn--;
997 }
998
999 WString++;
1000
1001 } else if (*WString == CHAR_LINEFEED) {
1002 //
1003 // If the cursor is at the bottom of the display, then scroll the display one
1004 // row, and do not update the cursor position. Otherwise, move the cursor
1005 // down one row.
1006 //
1007 if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {
1008 if (GraphicsOutput != NULL) {
1009 //
1010 // Scroll Screen Up One Row
1011 //
1012 GraphicsOutput->Blt (
1013 GraphicsOutput,
1014 NULL,
1015 EfiBltVideoToVideo,
1016 DeltaX,
1017 DeltaY + EFI_GLYPH_HEIGHT,
1018 DeltaX,
1019 DeltaY,
1020 Width,
1021 Height,
1022 Delta
1023 );
1024
1025 //
1026 // Print Blank Line at last line
1027 //
1028 GraphicsOutput->Blt (
1029 GraphicsOutput,
1030 &Background,
1031 EfiBltVideoFill,
1032 0,
1033 0,
1034 DeltaX,
1035 DeltaY + Height,
1036 Width,
1037 EFI_GLYPH_HEIGHT,
1038 Delta
1039 );
1040 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1041 //
1042 // Scroll Screen Up One Row
1043 //
1044 UgaDraw->Blt (
1045 UgaDraw,
1046 NULL,
1047 EfiUgaVideoToVideo,
1048 DeltaX,
1049 DeltaY + EFI_GLYPH_HEIGHT,
1050 DeltaX,
1051 DeltaY,
1052 Width,
1053 Height,
1054 Delta
1055 );
1056
1057 //
1058 // Print Blank Line at last line
1059 //
1060 UgaDraw->Blt (
1061 UgaDraw,
1062 (EFI_UGA_PIXEL *) (UINTN) &Background,
1063 EfiUgaVideoFill,
1064 0,
1065 0,
1066 DeltaX,
1067 DeltaY + Height,
1068 Width,
1069 EFI_GLYPH_HEIGHT,
1070 Delta
1071 );
1072 }
1073 } else {
1074 This->Mode->CursorRow++;
1075 }
1076
1077 WString++;
1078
1079 } else if (*WString == CHAR_CARRIAGE_RETURN) {
1080 //
1081 // Move the cursor to the beginning of the current row.
1082 //
1083 This->Mode->CursorColumn = 0;
1084 WString++;
1085
1086 } else if (*WString == WIDE_CHAR) {
1087
1088 This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;
1089 WString++;
1090
1091 } else if (*WString == NARROW_CHAR) {
1092
1093 This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);
1094 WString++;
1095
1096 } else {
1097 //
1098 // Print the character at the current cursor position and move the cursor
1099 // right one column. If this moves the cursor past the right edge of the
1100 // display, then the line should wrap to the beginning of the next line. This
1101 // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
1102 // bottom of the display, and the line wraps, then the display will be scrolled
1103 // one line.
1104 // If wide char is going to be displayed, need to display one character at a time
1105 // Or, need to know the display length of a certain string.
1106 //
1107 // Index is used to determine how many character width units (wide = 2, narrow = 1)
1108 // Count is used to determine how many characters are used regardless of their attributes
1109 //
1110 for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {
1111 if (WString[Count] == CHAR_NULL ||
1112 WString[Count] == CHAR_BACKSPACE ||
1113 WString[Count] == CHAR_LINEFEED ||
1114 WString[Count] == CHAR_CARRIAGE_RETURN ||
1115 WString[Count] == WIDE_CHAR ||
1116 WString[Count] == NARROW_CHAR) {
1117 break;
1118 }
1119 //
1120 // Is the wide attribute on?
1121 //
1122 if ((This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {
1123 //
1124 // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
1125 //
1126 Index++;
1127 //
1128 // This is the end-case where if we are at column 79 and about to print a wide character
1129 // We should prevent this from happening because we will wrap inappropriately. We should
1130 // not print this character until the next line.
1131 //
1132 if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {
1133 Index++;
1134 break;
1135 }
1136 }
1137 }
1138
1139 Status = DrawUnicodeWeightAtCursorN (This, WString, Count);
1140 if (EFI_ERROR (Status)) {
1141 Warning = TRUE;
1142 }
1143 //
1144 // At the end of line, output carriage return and line feed
1145 //
1146 WString += Count;
1147 This->Mode->CursorColumn += (INT32) Index;
1148 if (This->Mode->CursorColumn > (INT32) MaxColumn) {
1149 This->Mode->CursorColumn -= 2;
1150 This->OutputString (This, SpaceStr);
1151 }
1152
1153 if (This->Mode->CursorColumn >= (INT32) MaxColumn) {
1154 FlushCursor (This);
1155 This->OutputString (This, mCrLfString);
1156 FlushCursor (This);
1157 }
1158 }
1159 }
1160
1161 This->Mode->Attribute = OriginAttribute;
1162
1163 FlushCursor (This);
1164
1165 if (Warning) {
1166 Status = EFI_WARN_UNKNOWN_GLYPH;
1167 }
1168
1169 gBS->RestoreTPL (OldTpl);
1170 return Status;
1171
1172 }
1173
1174 /**
1175 Verifies that all characters in a Unicode string can be output to the
1176 target device.
1177
1178 Implements SIMPLE_TEXT_OUTPUT.TestString().
1179 If one of the characters in the *Wstring is neither valid valid Unicode
1180 drawing characters, not ASCII code, then this function will return
1181 EFI_UNSUPPORTED
1182
1183 @param This Protocol instance pointer.
1184 @param WString The NULL-terminated Unicode string to be examined for the output
1185 device(s).
1186
1187 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
1188 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be
1189 rendered by one or more of the output devices mapped
1190 by the EFI handle.
1191
1192 **/
1193 EFI_STATUS
1194 EFIAPI
1195 GraphicsConsoleConOutTestString (
1196 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1197 IN CHAR16 *WString
1198 )
1199 {
1200 EFI_STATUS Status;
1201 UINT16 Count;
1202
1203 EFI_IMAGE_OUTPUT *Blt;
1204
1205 Blt = NULL;
1206 Count = 0;
1207
1208 while (WString[Count] != 0) {
1209 Status = mHiiFont->GetGlyph (
1210 mHiiFont,
1211 WString[Count],
1212 NULL,
1213 &Blt,
1214 NULL
1215 );
1216 if (Blt != NULL) {
1217 FreePool (Blt);
1218 Blt = NULL;
1219 }
1220 Count++;
1221
1222 if (EFI_ERROR (Status)) {
1223 return EFI_UNSUPPORTED;
1224 }
1225 }
1226
1227 return EFI_SUCCESS;
1228 }
1229
1230
1231 /**
1232 Returns information for an available text mode that the output device(s)
1233 supports
1234
1235 Implements SIMPLE_TEXT_OUTPUT.QueryMode().
1236 It returnes information for an available text mode that the Graphics Console supports.
1237 In this driver,we only support text mode 80x25, which is defined as mode 0.
1238
1239 @param This Protocol instance pointer.
1240 @param ModeNumber The mode number to return information on.
1241 @param Columns The returned columns of the requested mode.
1242 @param Rows The returned rows of the requested mode.
1243
1244 @retval EFI_SUCCESS The requested mode information is returned.
1245 @retval EFI_UNSUPPORTED The mode number is not valid.
1246
1247 **/
1248 EFI_STATUS
1249 EFIAPI
1250 GraphicsConsoleConOutQueryMode (
1251 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1252 IN UINTN ModeNumber,
1253 OUT UINTN *Columns,
1254 OUT UINTN *Rows
1255 )
1256 {
1257 GRAPHICS_CONSOLE_DEV *Private;
1258 EFI_STATUS Status;
1259 EFI_TPL OldTpl;
1260
1261 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {
1262 return EFI_UNSUPPORTED;
1263 }
1264
1265 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1266 Status = EFI_SUCCESS;
1267
1268 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1269
1270 *Columns = Private->ModeData[ModeNumber].Columns;
1271 *Rows = Private->ModeData[ModeNumber].Rows;
1272
1273 if (*Columns <= 0 || *Rows <= 0) {
1274 Status = EFI_UNSUPPORTED;
1275 goto Done;
1276
1277 }
1278
1279 Done:
1280 gBS->RestoreTPL (OldTpl);
1281 return Status;
1282 }
1283
1284
1285 /**
1286 Sets the output device(s) to a specified mode.
1287
1288 Implements SIMPLE_TEXT_OUTPUT.SetMode().
1289 Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
1290
1291 @param This Protocol instance pointer.
1292 @param ModeNumber The text mode to set.
1293
1294 @retval EFI_SUCCESS The requested text mode is set.
1295 @retval EFI_DEVICE_ERROR The requested text mode cannot be set because of
1296 Graphics Console device error.
1297 @retval EFI_UNSUPPORTED The text mode number is not valid.
1298
1299 **/
1300 EFI_STATUS
1301 EFIAPI
1302 GraphicsConsoleConOutSetMode (
1303 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1304 IN UINTN ModeNumber
1305 )
1306 {
1307 EFI_STATUS Status;
1308 GRAPHICS_CONSOLE_DEV *Private;
1309 GRAPHICS_CONSOLE_MODE_DATA *ModeData;
1310 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewLineBuffer;
1311 UINT32 HorizontalResolution;
1312 UINT32 VerticalResolution;
1313 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1314 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1315 UINT32 ColorDepth;
1316 UINT32 RefreshRate;
1317 EFI_TPL OldTpl;
1318
1319 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1320
1321 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1322 GraphicsOutput = Private->GraphicsOutput;
1323 UgaDraw = Private->UgaDraw;
1324
1325 //
1326 // Make sure the requested mode number is supported
1327 //
1328 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {
1329 Status = EFI_UNSUPPORTED;
1330 goto Done;
1331 }
1332
1333 ModeData = &(Private->ModeData[ModeNumber]);
1334
1335 if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {
1336 Status = EFI_UNSUPPORTED;
1337 goto Done;
1338 }
1339
1340 //
1341 // If the mode has been set at least one other time, then LineBuffer will not be NULL
1342 //
1343 if (Private->LineBuffer != NULL) {
1344 //
1345 // If the new mode is the same as the old mode, then just return EFI_SUCCESS
1346 //
1347 if ((INT32) ModeNumber == This->Mode->Mode) {
1348 //
1349 // Clear the current text window on the current graphics console
1350 //
1351 This->ClearScreen (This);
1352 Status = EFI_SUCCESS;
1353 goto Done;
1354 }
1355 //
1356 // Otherwise, the size of the text console and/or the GOP/UGA mode will be changed,
1357 // so erase the cursor, and free the LineBuffer for the current mode
1358 //
1359 FlushCursor (This);
1360
1361 FreePool (Private->LineBuffer);
1362 }
1363
1364 //
1365 // Attempt to allocate a line buffer for the requested mode number
1366 //
1367 NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);
1368
1369 if (NewLineBuffer == NULL) {
1370 //
1371 // The new line buffer could not be allocated, so return an error.
1372 // No changes to the state of the current console have been made, so the current console is still valid
1373 //
1374 Status = EFI_OUT_OF_RESOURCES;
1375 goto Done;
1376 }
1377
1378 //
1379 // Assign the current line buffer to the newly allocated line buffer
1380 //
1381 Private->LineBuffer = NewLineBuffer;
1382
1383 if (GraphicsOutput != NULL) {
1384 if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {
1385 //
1386 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1387 //
1388 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);
1389 if (EFI_ERROR (Status)) {
1390 //
1391 // The mode set operation failed
1392 //
1393 goto Done;
1394 }
1395 } else {
1396 //
1397 // The current graphics mode is correct, so simply clear the entire display
1398 //
1399 Status = GraphicsOutput->Blt (
1400 GraphicsOutput,
1401 &mGraphicsEfiColors[0],
1402 EfiBltVideoFill,
1403 0,
1404 0,
1405 0,
1406 0,
1407 ModeData->GopWidth,
1408 ModeData->GopHeight,
1409 0
1410 );
1411 }
1412 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1413 //
1414 // Get the current UGA Draw mode information
1415 //
1416 Status = UgaDraw->GetMode (
1417 UgaDraw,
1418 &HorizontalResolution,
1419 &VerticalResolution,
1420 &ColorDepth,
1421 &RefreshRate
1422 );
1423 if (EFI_ERROR (Status) || HorizontalResolution != ModeData->GopWidth || VerticalResolution != ModeData->GopHeight) {
1424 //
1425 // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new graphics mode
1426 //
1427 Status = UgaDraw->SetMode (
1428 UgaDraw,
1429 ModeData->GopWidth,
1430 ModeData->GopHeight,
1431 32,
1432 60
1433 );
1434 if (EFI_ERROR (Status)) {
1435 //
1436 // The mode set operation failed
1437 //
1438 goto Done;
1439 }
1440 } else {
1441 //
1442 // The current graphics mode is correct, so simply clear the entire display
1443 //
1444 Status = UgaDraw->Blt (
1445 UgaDraw,
1446 (EFI_UGA_PIXEL *) (UINTN) &mGraphicsEfiColors[0],
1447 EfiUgaVideoFill,
1448 0,
1449 0,
1450 0,
1451 0,
1452 ModeData->GopWidth,
1453 ModeData->GopHeight,
1454 0
1455 );
1456 }
1457 }
1458
1459 //
1460 // The new mode is valid, so commit the mode change
1461 //
1462 This->Mode->Mode = (INT32) ModeNumber;
1463
1464 //
1465 // Move the text cursor to the upper left hand corner of the display and flush it
1466 //
1467 This->Mode->CursorColumn = 0;
1468 This->Mode->CursorRow = 0;
1469
1470 FlushCursor (This);
1471
1472 Status = EFI_SUCCESS;
1473
1474 Done:
1475 gBS->RestoreTPL (OldTpl);
1476 return Status;
1477 }
1478
1479
1480 /**
1481 Sets the background and foreground colors for the OutputString () and
1482 ClearScreen () functions.
1483
1484 Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
1485
1486 @param This Protocol instance pointer.
1487 @param Attribute The attribute to set. Bits 0..3 are the foreground
1488 color, and bits 4..6 are the background color.
1489 All other bits are undefined and must be zero.
1490
1491 @retval EFI_SUCCESS The requested attribute is set.
1492 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to Graphics Console port error.
1493 @retval EFI_UNSUPPORTED The attribute requested is not defined.
1494
1495 **/
1496 EFI_STATUS
1497 EFIAPI
1498 GraphicsConsoleConOutSetAttribute (
1499 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1500 IN UINTN Attribute
1501 )
1502 {
1503 EFI_TPL OldTpl;
1504
1505 if ((Attribute | 0xFF) != 0xFF) {
1506 return EFI_UNSUPPORTED;
1507 }
1508
1509 if (This->Mode->Mode == -1) {
1510 //
1511 // If current mode is not valid, return error.
1512 //
1513 return EFI_UNSUPPORTED;
1514 }
1515
1516 if ((INT32) Attribute == This->Mode->Attribute) {
1517 return EFI_SUCCESS;
1518 }
1519
1520 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1521
1522 FlushCursor (This);
1523
1524 This->Mode->Attribute = (INT32) Attribute;
1525
1526 FlushCursor (This);
1527
1528 gBS->RestoreTPL (OldTpl);
1529
1530 return EFI_SUCCESS;
1531 }
1532
1533
1534 /**
1535 Clears the output device(s) display to the currently selected background
1536 color.
1537
1538 Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
1539
1540 @param This Protocol instance pointer.
1541
1542 @retval EFI_SUCCESS The operation completed successfully.
1543 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1544 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
1545
1546 **/
1547 EFI_STATUS
1548 EFIAPI
1549 GraphicsConsoleConOutClearScreen (
1550 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
1551 )
1552 {
1553 EFI_STATUS Status;
1554 GRAPHICS_CONSOLE_DEV *Private;
1555 GRAPHICS_CONSOLE_MODE_DATA *ModeData;
1556 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1557 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1558 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
1559 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
1560 EFI_TPL OldTpl;
1561
1562 if (This->Mode->Mode == -1) {
1563 //
1564 // If current mode is not valid, return error.
1565 //
1566 return EFI_UNSUPPORTED;
1567 }
1568
1569 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1570
1571 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1572 GraphicsOutput = Private->GraphicsOutput;
1573 UgaDraw = Private->UgaDraw;
1574 ModeData = &(Private->ModeData[This->Mode->Mode]);
1575
1576 GetTextColors (This, &Foreground, &Background);
1577 if (GraphicsOutput != NULL) {
1578 Status = GraphicsOutput->Blt (
1579 GraphicsOutput,
1580 &Background,
1581 EfiBltVideoFill,
1582 0,
1583 0,
1584 0,
1585 0,
1586 ModeData->GopWidth,
1587 ModeData->GopHeight,
1588 0
1589 );
1590 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1591 Status = UgaDraw->Blt (
1592 UgaDraw,
1593 (EFI_UGA_PIXEL *) (UINTN) &Background,
1594 EfiUgaVideoFill,
1595 0,
1596 0,
1597 0,
1598 0,
1599 ModeData->GopWidth,
1600 ModeData->GopHeight,
1601 0
1602 );
1603 } else {
1604 Status = EFI_UNSUPPORTED;
1605 }
1606
1607 This->Mode->CursorColumn = 0;
1608 This->Mode->CursorRow = 0;
1609
1610 FlushCursor (This);
1611
1612 gBS->RestoreTPL (OldTpl);
1613
1614 return Status;
1615 }
1616
1617
1618 /**
1619 Sets the current coordinates of the cursor position.
1620
1621 Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
1622
1623 @param This Protocol instance pointer.
1624 @param Column The position to set the cursor to. Must be greater than or
1625 equal to zero and less than the number of columns and rows
1626 by QueryMode ().
1627 @param Row The position to set the cursor to. Must be greater than or
1628 equal to zero and less than the number of columns and rows
1629 by QueryMode ().
1630
1631 @retval EFI_SUCCESS The operation completed successfully.
1632 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
1633 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the
1634 cursor position is invalid for the current mode.
1635
1636 **/
1637 EFI_STATUS
1638 EFIAPI
1639 GraphicsConsoleConOutSetCursorPosition (
1640 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1641 IN UINTN Column,
1642 IN UINTN Row
1643 )
1644 {
1645 GRAPHICS_CONSOLE_DEV *Private;
1646 GRAPHICS_CONSOLE_MODE_DATA *ModeData;
1647 EFI_STATUS Status;
1648 EFI_TPL OldTpl;
1649
1650 if (This->Mode->Mode == -1) {
1651 //
1652 // If current mode is not valid, return error.
1653 //
1654 return EFI_UNSUPPORTED;
1655 }
1656
1657 Status = EFI_SUCCESS;
1658
1659 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1660
1661 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1662 ModeData = &(Private->ModeData[This->Mode->Mode]);
1663
1664 if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {
1665 Status = EFI_UNSUPPORTED;
1666 goto Done;
1667 }
1668
1669 if ((This->Mode->CursorColumn == (INT32) Column) && (This->Mode->CursorRow == (INT32) Row)) {
1670 Status = EFI_SUCCESS;
1671 goto Done;
1672 }
1673
1674 FlushCursor (This);
1675
1676 This->Mode->CursorColumn = (INT32) Column;
1677 This->Mode->CursorRow = (INT32) Row;
1678
1679 FlushCursor (This);
1680
1681 Done:
1682 gBS->RestoreTPL (OldTpl);
1683
1684 return Status;
1685 }
1686
1687
1688 /**
1689 Makes the cursor visible or invisible.
1690
1691 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
1692
1693 @param This Protocol instance pointer.
1694 @param Visible If TRUE, the cursor is set to be visible, If FALSE,
1695 the cursor is set to be invisible.
1696
1697 @retval EFI_SUCCESS The operation completed successfully.
1698 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
1699 defined text mode.
1700
1701 **/
1702 EFI_STATUS
1703 EFIAPI
1704 GraphicsConsoleConOutEnableCursor (
1705 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1706 IN BOOLEAN Visible
1707 )
1708 {
1709 EFI_TPL OldTpl;
1710
1711 if (This->Mode->Mode == -1) {
1712 //
1713 // If current mode is not valid, return error.
1714 //
1715 return EFI_UNSUPPORTED;
1716 }
1717
1718 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1719
1720 FlushCursor (This);
1721
1722 This->Mode->CursorVisible = Visible;
1723
1724 FlushCursor (This);
1725
1726 gBS->RestoreTPL (OldTpl);
1727 return EFI_SUCCESS;
1728 }
1729
1730 /**
1731 Gets Graphics Console devcie's foreground color and background color.
1732
1733 @param This Protocol instance pointer.
1734 @param Foreground Returned text foreground color.
1735 @param Background Returned text background color.
1736
1737 @retval EFI_SUCCESS It returned always.
1738
1739 **/
1740 EFI_STATUS
1741 GetTextColors (
1742 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1743 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
1744 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background
1745 )
1746 {
1747 INTN Attribute;
1748
1749 Attribute = This->Mode->Attribute & 0x7F;
1750
1751 *Foreground = mGraphicsEfiColors[Attribute & 0x0f];
1752 *Background = mGraphicsEfiColors[Attribute >> 4];
1753
1754 return EFI_SUCCESS;
1755 }
1756
1757 /**
1758 Draw Unicode string on the Graphics Console device's screen.
1759
1760 @param This Protocol instance pointer.
1761 @param UnicodeWeight One Unicode string to be displayed.
1762 @param Count The count of Unicode string.
1763
1764 @retval EFI_OUT_OF_RESOURCES If no memory resource to use.
1765 @retval EFI_UNSUPPORTED If no Graphics Output protocol and UGA Draw
1766 protocol exist.
1767 @retval EFI_SUCCESS Drawing Unicode string implemented successfully.
1768
1769 **/
1770 EFI_STATUS
1771 DrawUnicodeWeightAtCursorN (
1772 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1773 IN CHAR16 *UnicodeWeight,
1774 IN UINTN Count
1775 )
1776 {
1777 EFI_STATUS Status;
1778 GRAPHICS_CONSOLE_DEV *Private;
1779 EFI_IMAGE_OUTPUT *Blt;
1780 EFI_STRING String;
1781 EFI_FONT_DISPLAY_INFO *FontInfo;
1782 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1783 EFI_HII_ROW_INFO *RowInfoArray;
1784 UINTN RowInfoArraySize;
1785
1786 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1787 Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
1788 if (Blt == NULL) {
1789 return EFI_OUT_OF_RESOURCES;
1790 }
1791
1792 Blt->Width = (UINT16) (Private->ModeData[This->Mode->Mode].GopWidth);
1793 Blt->Height = (UINT16) (Private->ModeData[This->Mode->Mode].GopHeight);
1794
1795 String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);
1796 if (String == NULL) {
1797 FreePool (Blt);
1798 return EFI_OUT_OF_RESOURCES;
1799 }
1800 //
1801 // Set the end character
1802 //
1803 *(String + Count) = L'\0';
1804
1805 FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));
1806 if (FontInfo == NULL) {
1807 FreePool (Blt);
1808 FreePool (String);
1809 return EFI_OUT_OF_RESOURCES;
1810 }
1811 //
1812 // Get current foreground and background colors.
1813 //
1814 GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);
1815
1816 if (Private->GraphicsOutput != NULL) {
1817 //
1818 // If Graphics Output protocol exists, using HII Font protocol to draw.
1819 //
1820 Blt->Image.Screen = Private->GraphicsOutput;
1821
1822 Status = mHiiFont->StringToImage (
1823 mHiiFont,
1824 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN | EFI_HII_IGNORE_LINE_BREAK,
1825 String,
1826 FontInfo,
1827 &Blt,
1828 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1829 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1830 NULL,
1831 NULL,
1832 NULL
1833 );
1834
1835 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1836 //
1837 // If Graphics Output protocol cannot be found and PcdUgaConsumeSupport enabled,
1838 // using UGA Draw protocol to draw.
1839 //
1840 ASSERT (Private->UgaDraw!= NULL);
1841
1842 UgaDraw = Private->UgaDraw;
1843
1844 Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
1845 if (Blt->Image.Bitmap == NULL) {
1846 FreePool (Blt);
1847 FreePool (String);
1848 return EFI_OUT_OF_RESOURCES;
1849 }
1850
1851 RowInfoArray = NULL;
1852 //
1853 // StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,
1854 // we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.
1855 //
1856 Status = mHiiFont->StringToImage (
1857 mHiiFont,
1858 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK,
1859 String,
1860 FontInfo,
1861 &Blt,
1862 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1863 This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1864 &RowInfoArray,
1865 &RowInfoArraySize,
1866 NULL
1867 );
1868
1869 if (!EFI_ERROR (Status)) {
1870 //
1871 // Line breaks are handled by caller of DrawUnicodeWeightAtCursorN, so the updated parameter RowInfoArraySize by StringToImage will
1872 // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.
1873 //
1874 ASSERT (RowInfoArraySize <= 1);
1875
1876 Status = UgaDraw->Blt (
1877 UgaDraw,
1878 (EFI_UGA_PIXEL *) Blt->Image.Bitmap,
1879 EfiUgaBltBufferToVideo,
1880 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1881 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1882 This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
1883 (This->Mode->CursorRow) * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
1884 RowInfoArray[0].LineWidth,
1885 RowInfoArray[0].LineHeight,
1886 Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1887 );
1888 }
1889
1890 FreePool (RowInfoArray);
1891 FreePool (Blt->Image.Bitmap);
1892 } else {
1893 Status = EFI_UNSUPPORTED;
1894 }
1895
1896 if (Blt != NULL) {
1897 FreePool (Blt);
1898 }
1899 if (String != NULL) {
1900 FreePool (String);
1901 }
1902 if (FontInfo != NULL) {
1903 FreePool (FontInfo);
1904 }
1905 return Status;
1906 }
1907
1908 /**
1909 Flush the cursor on the screen.
1910
1911 If CursorVisible is FALSE, nothing to do and return directly.
1912 If CursorVisible is TRUE,
1913 i) If the cursor shows on screen, it will be erased.
1914 ii) If the cursor does not show on screen, it will be shown.
1915
1916 @param This Protocol instance pointer.
1917
1918 @retval EFI_SUCCESS The cursor is erased successfully.
1919
1920 **/
1921 EFI_STATUS
1922 FlushCursor (
1923 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
1924 )
1925 {
1926 GRAPHICS_CONSOLE_DEV *Private;
1927 EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;
1928 INTN GlyphX;
1929 INTN GlyphY;
1930 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1931 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
1932 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;
1933 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;
1934 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];
1935 UINTN PosX;
1936 UINTN PosY;
1937
1938 CurrentMode = This->Mode;
1939
1940 if (!CurrentMode->CursorVisible) {
1941 return EFI_SUCCESS;
1942 }
1943
1944 Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
1945 GraphicsOutput = Private->GraphicsOutput;
1946 UgaDraw = Private->UgaDraw;
1947
1948 //
1949 // In this driver, only narrow character was supported.
1950 //
1951 //
1952 // Blt a character to the screen
1953 //
1954 GlyphX = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;
1955 GlyphY = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;
1956 if (GraphicsOutput != NULL) {
1957 GraphicsOutput->Blt (
1958 GraphicsOutput,
1959 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,
1960 EfiBltVideoToBltBuffer,
1961 GlyphX,
1962 GlyphY,
1963 0,
1964 0,
1965 EFI_GLYPH_WIDTH,
1966 EFI_GLYPH_HEIGHT,
1967 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1968 );
1969 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
1970 UgaDraw->Blt (
1971 UgaDraw,
1972 (EFI_UGA_PIXEL *) (UINTN) BltChar,
1973 EfiUgaVideoToBltBuffer,
1974 GlyphX,
1975 GlyphY,
1976 0,
1977 0,
1978 EFI_GLYPH_WIDTH,
1979 EFI_GLYPH_HEIGHT,
1980 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
1981 );
1982 }
1983
1984 GetTextColors (This, &Foreground.Pixel, &Background.Pixel);
1985
1986 //
1987 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
1988 //
1989 for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {
1990 for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {
1991 if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {
1992 BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;
1993 }
1994 }
1995 }
1996
1997 if (GraphicsOutput != NULL) {
1998 GraphicsOutput->Blt (
1999 GraphicsOutput,
2000 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,
2001 EfiBltBufferToVideo,
2002 0,
2003 0,
2004 GlyphX,
2005 GlyphY,
2006 EFI_GLYPH_WIDTH,
2007 EFI_GLYPH_HEIGHT,
2008 EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
2009 );
2010 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
2011 UgaDraw->Blt (
2012 UgaDraw,
2013 (EFI_UGA_PIXEL *) (UINTN) BltChar,
2014 EfiUgaBltBufferToVideo,
2015 0,
2016 0,
2017 GlyphX,
2018 GlyphY,
2019 EFI_GLYPH_WIDTH,
2020 EFI_GLYPH_HEIGHT,
2021 EFI_GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)
2022 );
2023 }
2024
2025 return EFI_SUCCESS;
2026 }
2027
2028 /**
2029 HII Database Protocol notification event handler.
2030
2031 Register font package when HII Database Protocol has been installed.
2032
2033 @param[in] Event Event whose notification function is being invoked.
2034 @param[in] Context Pointer to the notification function's context.
2035 **/
2036 VOID
2037 EFIAPI
2038 RegisterFontPackage (
2039 IN EFI_EVENT Event,
2040 IN VOID *Context
2041 )
2042 {
2043 EFI_STATUS Status;
2044 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;
2045 UINT32 PackageLength;
2046 UINT8 *Package;
2047 UINT8 *Location;
2048 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
2049
2050 //
2051 // Locate HII Database Protocol
2052 //
2053 Status = gBS->LocateProtocol (
2054 &gEfiHiiDatabaseProtocolGuid,
2055 NULL,
2056 (VOID **) &HiiDatabase
2057 );
2058 ASSERT_EFI_ERROR (Status);
2059
2060 //
2061 // Add 4 bytes to the header for entire length for HiiAddPackages use only.
2062 //
2063 // +--------------------------------+ <-- Package
2064 // | |
2065 // | PackageLength(4 bytes) |
2066 // | |
2067 // |--------------------------------| <-- SimplifiedFont
2068 // | |
2069 // |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
2070 // | |
2071 // |--------------------------------| <-- Location
2072 // | |
2073 // | gUsStdNarrowGlyphData |
2074 // | |
2075 // +--------------------------------+
2076
2077 PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;
2078 Package = AllocateZeroPool (PackageLength);
2079 ASSERT (Package != NULL);
2080
2081 WriteUnaligned32((UINT32 *) Package,PackageLength);
2082 SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *) (Package + 4);
2083 SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);
2084 SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;
2085 SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));
2086
2087 Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);
2088 CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);
2089
2090 //
2091 // Add this simplified font package to a package list then install it.
2092 //
2093 mHiiHandle = HiiAddPackages (
2094 &mFontPackageListGuid,
2095 NULL,
2096 Package,
2097 NULL
2098 );
2099 ASSERT (mHiiHandle != NULL);
2100 FreePool (Package);
2101 }
2102
2103 /**
2104 The user Entry Point for module GraphicsConsole. The user code starts with this function.
2105
2106 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2107 @param[in] SystemTable A pointer to the EFI System Table.
2108
2109 @retval EFI_SUCCESS The entry point is executed successfully.
2110 @return other Some error occurs when executing this entry point.
2111
2112 **/
2113 EFI_STATUS
2114 EFIAPI
2115 InitializeGraphicsConsole (
2116 IN EFI_HANDLE ImageHandle,
2117 IN EFI_SYSTEM_TABLE *SystemTable
2118 )
2119 {
2120 EFI_STATUS Status;
2121
2122 //
2123 // Register notify function on HII Database Protocol to add font package.
2124 //
2125 EfiCreateProtocolNotifyEvent (
2126 &gEfiHiiDatabaseProtocolGuid,
2127 TPL_CALLBACK,
2128 RegisterFontPackage,
2129 NULL,
2130 &mHiiRegistration
2131 );
2132
2133 //
2134 // Install driver model protocol(s).
2135 //
2136 Status = EfiLibInstallDriverBindingComponentName2 (
2137 ImageHandle,
2138 SystemTable,
2139 &gGraphicsConsoleDriverBinding,
2140 ImageHandle,
2141 &gGraphicsConsoleComponentName,
2142 &gGraphicsConsoleComponentName2
2143 );
2144 ASSERT_EFI_ERROR (Status);
2145
2146 return Status;
2147 }
2148
2149