/** @file\r
BDS Lib functions which contain all the code to connect console device\r
\r
-Copyright (c) 2004 - 2009, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
**/\r
\r
#include "InternalBdsLib.h"\r
-#include "Bmp.h"\r
+#include <IndustryStandard/Bmp.h>\r
+\r
\r
/**\r
Check if we need to save the EFI variable with "ConVarName" as name\r
IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath\r
)\r
{\r
+ EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
UINTN DevicePathSize;\r
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
//\r
// Finally, Update the variable of the default console by NewDevicePath\r
//\r
- gRT->SetVariable (\r
- ConVarName,\r
- &gEfiGlobalVariableGuid,\r
- Attributes,\r
- GetDevicePathSize (NewDevicePath),\r
- NewDevicePath\r
- );\r
+ DevicePathSize = GetDevicePathSize (NewDevicePath);\r
+ Status = gRT->SetVariable (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ Attributes,\r
+ DevicePathSize,\r
+ NewDevicePath\r
+ );\r
+ if ((DevicePathSize == 0) && (Status == EFI_NOT_FOUND)) {\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ ASSERT_EFI_ERROR (Status);\r
\r
if (VarConsole == NewDevicePath) {\r
if (VarConsole != NULL) {\r
}\r
}\r
\r
- return EFI_SUCCESS;\r
+ return Status;\r
\r
}\r
\r
\r
SetDevicePathEndNode (Next);\r
//\r
- // Check USB1.1 console\r
+ // Connect the USB console\r
+ // USB console device path is a short-form device path that \r
+ // starts with the first element being a USB WWID\r
+ // or a USB Class device path\r
//\r
if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&\r
((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)\r
|| (DevicePathSubType (Instance) == MSG_USB_WWID_DP)\r
)) {\r
- //\r
- // Check the Usb console in Usb2.0 bus firstly, then Usb1.1 bus\r
- //\r
- Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_EHCI, Instance);\r
- if (!EFI_ERROR (Status)) {\r
- DeviceExist = TRUE;\r
- }\r
-\r
- Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_UHCI, Instance);\r
+ Status = BdsLibConnectUsbDevByShortFormDP (0xFF, Instance);\r
if (!EFI_ERROR (Status)) {\r
DeviceExist = TRUE;\r
}\r
UINTN Height;\r
UINTN Width;\r
UINTN ImageIndex;\r
+ UINT32 DataSizePerLine;\r
BOOLEAN IsAllocated;\r
+ UINT32 ColorMapNum;\r
+\r
+ if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
\r
return EFI_UNSUPPORTED;\r
}\r
\r
+ //\r
+ // Only support BITMAPINFOHEADER format.\r
+ // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER\r
+ //\r
+ if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // The data size in each line must be 4 byte alignment.\r
+ //\r
+ DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);\r
+ BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);\r
+ if (BltBufferSize > (UINT32) ~0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((BmpHeader->Size != BmpImageSize) || \r
+ (BmpHeader->Size < BmpHeader->ImageOffset) ||\r
+ (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
//\r
// Calculate Color Map offset in the image.\r
//\r
Image = BmpImage;\r
BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
+ if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {\r
+ switch (BmpHeader->BitPerPixel) {\r
+ case 1:\r
+ ColorMapNum = 2;\r
+ break;\r
+ case 4:\r
+ ColorMapNum = 16;\r
+ break;\r
+ case 8:\r
+ ColorMapNum = 256;\r
+ break;\r
+ default:\r
+ ColorMapNum = 0;\r
+ break;\r
+ }\r
+ if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) != sizeof (BMP_COLOR_MAP) * ColorMapNum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
\r
//\r
// Calculate graphics image data address in the image\r
//\r
// Calculate the BltBuffer needed size.\r
//\r
- BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
- if (BltBufferSize >= SIZE_4GB) {\r
- //\r
- // If the BMP resolution is too large\r
- //\r
+ BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);\r
+ //\r
+ // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
+ //\r
+ if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
return EFI_UNSUPPORTED;\r
}\r
- \r
+ BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+\r
IsAllocated = FALSE;\r
if (*GopBlt == NULL) {\r
//\r
UINT32 ColorDepth;\r
UINT32 RefreshRate;\r
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+ EFI_BOOT_LOGO_PROTOCOL *BootLogo;\r
+ UINTN NumberOfLogos;\r
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;\r
+ UINTN LogoDestX;\r
+ UINTN LogoDestY;\r
+ UINTN LogoHeight;\r
+ UINTN LogoWidth;\r
+ UINTN NewDestX;\r
+ UINTN NewDestY;\r
+ UINTN NewHeight;\r
+ UINTN NewWidth;\r
+ UINT64 BufferSize;\r
\r
UgaDraw = NULL;\r
//\r
return EFI_UNSUPPORTED;\r
}\r
\r
+ //\r
+ // Try to open Boot Logo Protocol.\r
+ //\r
+ BootLogo = NULL;\r
+ gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);\r
+\r
//\r
// Erase Cursor from screen\r
//\r
return EFI_UNSUPPORTED;\r
}\r
\r
+ Blt = NULL;\r
+ NumberOfLogos = 0;\r
+ LogoDestX = 0;\r
+ LogoDestY = 0;\r
+ LogoHeight = 0;\r
+ LogoWidth = 0;\r
+ NewDestX = 0;\r
+ NewDestY = 0;\r
+ NewHeight = 0;\r
+ NewWidth = 0;\r
Instance = 0;\r
while (1) {\r
ImageData = NULL;\r
&CoordinateY\r
);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
//\r
\r
CoordinateX = 0;\r
CoordinateY = 0;\r
- Attribute = EfiBadgingDisplayAttributeCenter;\r
+ if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
+ Attribute = EfiBadgingDisplayAttributeCenter;\r
+ } else {\r
+ Attribute = EfiBadgingDisplayAttributeCustomized;\r
+ } \r
}\r
\r
+ if (Blt != NULL) {\r
+ FreePool (Blt);\r
+ }\r
Blt = NULL;\r
Status = ConvertBmpToGopBlt (\r
ImageData,\r
DestY = (SizeOfY - Height) / 2;\r
break;\r
\r
+ case EfiBadgingDisplayAttributeCustomized:\r
+ DestX = (SizeOfX - Width) / 2;\r
+ DestY = ((SizeOfY * 382) / 1000) - Height / 2;\r
+ break;\r
+\r
default:\r
DestX = CoordinateX;\r
DestY = CoordinateY;\r
Width * sizeof (EFI_UGA_PIXEL)\r
);\r
} else {\r
- Status = EFI_UNSUPPORTED;\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Report displayed Logo information.\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ NumberOfLogos++;\r
+\r
+ if (LogoWidth == 0) {\r
+ //\r
+ // The first Logo.\r
+ //\r
+ LogoDestX = (UINTN) DestX;\r
+ LogoDestY = (UINTN) DestY;\r
+ LogoWidth = Width;\r
+ LogoHeight = Height;\r
+ } else {\r
+ //\r
+ // Merge new logo with old one.\r
+ //\r
+ NewDestX = MIN ((UINTN) DestX, LogoDestX);\r
+ NewDestY = MIN ((UINTN) DestY, LogoDestY);\r
+ NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;\r
+ NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;\r
+\r
+ LogoDestX = NewDestX;\r
+ LogoDestY = NewDestY;\r
+ LogoWidth = NewWidth;\r
+ LogoHeight = NewHeight;\r
+ }\r
}\r
}\r
\r
FreePool (ImageData);\r
\r
+ if (Badging == NULL) {\r
+ break;\r
+ }\r
+ }\r
+\r
+Done:\r
+ if (BootLogo == NULL || NumberOfLogos == 0) {\r
+ //\r
+ // No logo displayed.\r
+ //\r
if (Blt != NULL) {\r
FreePool (Blt);\r
}\r
\r
- if (Badging == NULL) {\r
- break;\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Advertise displayed Logo information.\r
+ //\r
+ if (NumberOfLogos == 1) {\r
+ //\r
+ // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.\r
+ //\r
+ LogoBlt = Blt;\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ //\r
+ // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation. \r
+ //\r
+ if (Blt != NULL) {\r
+ FreePool (Blt);\r
}\r
+\r
+ //\r
+ // Ensure the LogoHeight * LogoWidth doesn't overflow\r
+ //\r
+ if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ BufferSize = MultU64x64 (LogoWidth, LogoHeight);\r
+\r
+ //\r
+ // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
+ //\r
+ if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+ if (LogoBlt == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ if (GraphicsOutput != NULL) {\r
+ Status = GraphicsOutput->Blt (\r
+ GraphicsOutput,\r
+ LogoBlt,\r
+ EfiBltVideoToBltBuffer,\r
+ LogoDestX,\r
+ LogoDestY,\r
+ 0,\r
+ 0,\r
+ LogoWidth,\r
+ LogoHeight,\r
+ LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+ );\r
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+ Status = UgaDraw->Blt (\r
+ UgaDraw,\r
+ (EFI_UGA_PIXEL *) LogoBlt,\r
+ EfiUgaVideoToBltBuffer,\r
+ LogoDestX,\r
+ LogoDestY,\r
+ 0,\r
+ 0,\r
+ LogoWidth,\r
+ LogoHeight,\r
+ LogoWidth * sizeof (EFI_UGA_PIXEL)\r
+ );\r
+ } else {\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);\r
}\r
+ FreePool (LogoBlt);\r
\r
return Status;\r
}\r