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