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