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