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