1 /** @file
2   Logo DXE Driver, install Edkii Platform Logo protocol.
3 
4   Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
5   Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
6 
7   SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 #include <Uefi.h>
12 #include <Protocol/HiiDatabase.h>
13 #include <Protocol/GraphicsOutput.h>
14 #include <Protocol/HiiImageEx.h>
15 #include <Protocol/PlatformLogo.h>
16 #include <Protocol/HiiPackageList.h>
17 #include <Library/UefiBootServicesTableLib.h>
18 #include <Library/DebugLib.h>
19 
20 typedef struct {
21   EFI_IMAGE_ID                          ImageId;
22   EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
23   INTN                                  OffsetX;
24   INTN                                  OffsetY;
25 } LOGO_ENTRY;
26 
27 STATIC EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
28 STATIC EFI_HII_HANDLE            mHiiHandle;
29 STATIC LOGO_ENTRY                mLogos[] = {
30   {
31     IMAGE_TOKEN (IMG_LOGO),
32     EdkiiPlatformLogoDisplayAttributeCenter,
33     0,
34     0
35   }
36 };
37 
38 /**
39   Load a platform logo image and return its data and attributes.
40 
41   @param This              The pointer to this protocol instance.
42   @param Instance          The visible image instance is found.
43   @param Image             Points to the image.
44   @param Attribute         The display attributes of the image returned.
45   @param OffsetX           The X offset of the image regarding the Attribute.
46   @param OffsetY           The Y offset of the image regarding the Attribute.
47 
48   @retval EFI_SUCCESS      The image was fetched successfully.
49   @retval EFI_NOT_FOUND    The specified image could not be found.
50 **/
51 STATIC
52 EFI_STATUS
53 EFIAPI
54 GetImage (
55   IN     EDKII_PLATFORM_LOGO_PROTOCOL          *This,
56   IN OUT UINT32                                *Instance,
57      OUT EFI_IMAGE_INPUT                       *Image,
58      OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute,
59      OUT INTN                                  *OffsetX,
60      OUT INTN                                  *OffsetY
61   )
62 {
63   UINT32 Current;
64 
65   if (Instance == NULL || Image == NULL ||
66       Attribute == NULL || OffsetX == NULL || OffsetY == NULL) {
67     return EFI_INVALID_PARAMETER;
68   }
69 
70   Current = *Instance;
71   if (Current >= ARRAY_SIZE (mLogos)) {
72     return EFI_NOT_FOUND;
73   }
74 
75   (*Instance)++;
76   *Attribute = mLogos[Current].Attribute;
77   *OffsetX   = mLogos[Current].OffsetX;
78   *OffsetY   = mLogos[Current].OffsetY;
79 
80   return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle,
81                         mLogos[Current].ImageId, Image);
82 }
83 
84 STATIC EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = {
85   GetImage
86 };
87 
88 /**
89   Entrypoint of this module.
90 
91   This function is the entrypoint of this module. It installs the Edkii
92   Platform Logo protocol.
93 
94   @param  ImageHandle       The firmware allocated handle for the EFI image.
95   @param  SystemTable       A pointer to the EFI System Table.
96 
97   @retval EFI_SUCCESS       The entry point is executed successfully.
98 
99 **/
100 EFI_STATUS
101 EFIAPI
102 InitializeLogo (
103   IN EFI_HANDLE               ImageHandle,
104   IN EFI_SYSTEM_TABLE         *SystemTable
105   )
106 {
107   EFI_STATUS                  Status;
108   EFI_HII_PACKAGE_LIST_HEADER *PackageList;
109   EFI_HII_DATABASE_PROTOCOL   *HiiDatabase;
110   EFI_HANDLE                  Handle;
111 
112   Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL,
113                   (VOID **) &HiiDatabase);
114   ASSERT_EFI_ERROR (Status);
115 
116   Status = gBS->LocateProtocol (&gEfiHiiImageExProtocolGuid, NULL,
117                   (VOID **) &mHiiImageEx);
118   ASSERT_EFI_ERROR (Status);
119 
120   //
121   // Retrieve HII package list from ImageHandle
122   //
123   Status = gBS->OpenProtocol (ImageHandle, &gEfiHiiPackageListProtocolGuid,
124                   (VOID **) &PackageList, ImageHandle, NULL,
125                   EFI_OPEN_PROTOCOL_GET_PROTOCOL);
126   if (EFI_ERROR (Status)) {
127     DEBUG ((DEBUG_ERROR,
128       "HII Image Package with logo not found in PE/COFF resource section\n"));
129     return Status;
130   }
131 
132   //
133   // Publish HII package list to HII Database.
134   //
135   Status = HiiDatabase->NewPackageList (HiiDatabase, PackageList, NULL,
136                           &mHiiHandle);
137   if (!EFI_ERROR (Status)) {
138     Handle = NULL;
139     Status = gBS->InstallMultipleProtocolInterfaces (&Handle,
140                     &gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo, NULL);
141   }
142   return Status;
143 }
144