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