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