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