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