BOOLEAN mInFrameworkUpdatePakcage = FALSE;\r
UINT64 mGuidCount = 0;\r
\r
+EFI_GUID mGuidBase = { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e }};\r
+\r
+\r
\r
/**\r
Get the number of package IFR and STRING packages in the package list passed in.\r
EFI_STATUS\r
GetPackageCount (\r
IN CONST EFI_HII_PACKAGES *Packages,\r
- UINTN *IfrPackageCount,\r
- UINTN *StringPackageCount\r
+ OUT UINTN *IfrPackageCount,\r
+ OUT UINTN *StringPackageCount,\r
+ OUT UINTN *FontPackageCount\r
)\r
{\r
UINTN Index;\r
ASSERT (Packages != NULL);\r
ASSERT (IfrPackageCount != NULL);\r
ASSERT (StringPackageCount != NULL);\r
+ ASSERT (FontPackageCount != NULL);\r
\r
*IfrPackageCount = 0;\r
*StringPackageCount = 0;\r
+ *FontPackageCount = 0;\r
\r
TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
\r
// may not be the exact number of valid package number in the binary generated \r
// by HII Build tool.\r
//\r
- switch (TianoAutogenPackageHdrArray[Index]->PackageHeader.Type) {\r
- case EFI_HII_PACKAGE_FORMS:\r
+ switch (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type) {\r
+ case EFI_HII_IFR:\r
*IfrPackageCount += 1;\r
break;\r
- case EFI_HII_PACKAGE_STRINGS:\r
+ case EFI_HII_STRING:\r
*StringPackageCount += 1;\r
break;\r
\r
- case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
+ case EFI_HII_FONT:\r
+ *FontPackageCount += 1;\r
break;\r
\r
//\r
// The following fonts are invalid for a module that using Framework to UEFI thunk layer.\r
//\r
- case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
- case EFI_HII_PACKAGE_FONTS:\r
- case EFI_HII_PACKAGE_IMAGES:\r
default:\r
ASSERT (FALSE);\r
return EFI_INVALID_PARAMETER;\r
{\r
EFI_STATUS Status;\r
LIST_ENTRY *Link;\r
- HII_THUNK_CONTEXT *ThunkContext;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
\r
Link = GetFirstNode (&Private->ThunkContextListHead);\r
while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
StringPackageListHeader\r
);\r
ASSERT_EFI_ERROR (Status);\r
- \r
+\r
+ ThunkContext->SharingStringPack = TRUE;\r
+ StringPackageThunkContext->SharingStringPack = TRUE;\r
+\r
}\r
}\r
\r
Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
}\r
+\r
+}\r
+\r
+/**\r
+ Caculate the size of UEFI Simple Font Package that is needed to \r
+ convert all the font a Framework Font Paackage.\r
+\r
+ ONLY Narrow Font is supported. Wide Font is discarded. \r
+\r
+ If the Package Header is not of EFI_HII_FONT type, then ASSERT.\r
+\r
+ @param The Package header of the Framework Font Package.\r
+ \r
+ @return The size of the UEFI Simple Font Package.\r
+ \r
+**/\r
+UINTN\r
+GetUefiSimpleFontPackSize (\r
+ IN CONST EFI_HII_PACK_HEADER * PackHeader\r
+ )\r
+{\r
+ UINTN Size;\r
+ EFI_HII_FONT_PACK *FwFontPack;\r
+\r
+ FwFontPack = (EFI_HII_FONT_PACK *) PackHeader;\r
+\r
+ ASSERT (FwFontPack->Header.Type == EFI_HII_FONT);\r
\r
+ Size = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) \r
+ + (FwFontPack->NumberOfNarrowGlyphs * sizeof (EFI_NARROW_GLYPH));\r
+\r
+ return Size;\r
}\r
\r
\r
+/**\r
+ Convert Font Package in Framework format to a newly allocated UEFI\r
+ Simple Font Package.\r
+\r
+ ONLY Narrow Font is supported. Wide Font is discarded. \r
+\r
+ If memory allocation fails, then ASSERT.\r
+\r
+ @param FwFontPack Framework Font Package.\r
+\r
+ @reture UEFI Simple Font Package.\r
+**/\r
+EFI_HII_SIMPLE_FONT_PACKAGE_HDR *\r
+FrameworkFontPackToUefiSimpliedFont (\r
+ IN CONST EFI_HII_PACK_HEADER * PackHeader\r
+ )\r
+{\r
+ EFI_HII_SIMPLE_FONT_PACKAGE_HDR *FontPack;\r
+ UINTN Size;\r
+ EFI_NARROW_GLYPH *FwNarrowGlyph;\r
+ EFI_NARROW_GLYPH *NarrowGlyph;\r
+ UINTN Idx;\r
+ EFI_HII_FONT_PACK *FwFontPack;\r
+\r
+ Size = GetUefiSimpleFontPackSize (PackHeader);\r
+\r
+ FwFontPack = (EFI_HII_FONT_PACK *) PackHeader;\r
+\r
+ FontPack = AllocateZeroPool (Size);\r
+ ASSERT (FontPack != NULL);\r
+\r
+ //\r
+ // Prepare the Header information.\r
+ //\r
+ FontPack->Header.Length = (UINT32) Size;\r
+ FontPack->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
+\r
+ FontPack->NumberOfNarrowGlyphs = FwFontPack->NumberOfNarrowGlyphs;\r
+ \r
+ //\r
+ // ONLY Narrow Font is supported. Wide Font is discarded. \r
+ //\r
+ FontPack->NumberOfWideGlyphs = 0;\r
+ \r
+ //\r
+ // Copy Narrow Glyph\r
+ //\r
+ NarrowGlyph = (EFI_NARROW_GLYPH *) (FontPack + 1);\r
+ FwNarrowGlyph = (EFI_NARROW_GLYPH *) (FwFontPack + 1);\r
+ CopyMem (NarrowGlyph, FwNarrowGlyph, sizeof (EFI_NARROW_GLYPH) * FwFontPack->NumberOfNarrowGlyphs);\r
+ for (Idx = 0; Idx < FwFontPack->NumberOfNarrowGlyphs; Idx++) {\r
+ //\r
+ // Clear the GLYPH_NON_BREAKING (EFI_GLYPH_WIDE is used here as they are all 0x02)\r
+ // attribute which is not defined in UEFI EFI_NARROW_GLYPH\r
+ //\r
+ NarrowGlyph[Idx].Attributes = (UINT8) (NarrowGlyph[Idx].Attributes & ~(EFI_GLYPH_WIDE));\r
+ }\r
+\r
+ return FontPack;\r
+}\r
+\r
/**\r
Prepare a UEFI Package List from a Framework HII package list registered\r
from a Framework HII NewPack () function.\r
UINT32 PackageLength;\r
EFI_HII_PACKAGE_HEADER PackageHeader;\r
UINTN Index;\r
- TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
+ TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
+ EFI_HII_SIMPLE_FONT_PACKAGE_HDR *FontPack;\r
+ \r
\r
ASSERT (Packages != NULL);\r
ASSERT (PackageListGuid != NULL);\r
PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
\r
for (Index = 0; Index < NumberOfPackages; Index++) {\r
- CopyMem (&PackageLength, &TianoAutogenPackageHdrArray[Index]->BinaryLength, sizeof (UINT32));\r
- //\r
- //TIANO_AUTOGEN_PACKAGES_HEADER.BinaryLength include the BinaryLength itself.\r
- //\r
- PackageListLength += (PackageLength - sizeof(UINT32)); \r
+ if (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type == EFI_HII_FONT) {\r
+ //\r
+ // There is no tool to generate Font package in Framework HII's implementation.\r
+ // Therefore, Font Package be a C structure defined in Framework HII code. \r
+ // Therefore, Font Package will be in Framework HII format defined by EFI_HII_FONT_PACK.\r
+ // We need to create a UEFI Simple Font Package and copy over all data. Hence, EFI_HII_FONT\r
+ // is handled differently than EFI_HII_IFR and EFI_HII_STRING.\r
+ //\r
+ PackageListLength = (UINT32) (PackageListLength + GetUefiSimpleFontPackSize (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader));\r
+ \r
+ } else {\r
+ //\r
+ // For EFI_HII_IFR and EFI_HII_STRING, EDK II's VFR Compiler and Build.exe will generate a binary in a format\r
+ // defined by TIANO_AUTOGEN_PACKAGES_HEADER. A Framework HII's EFI_HII_PACK_HEADER is inserted before\r
+ // the UEFI package data.\r
+ //\r
+ CopyMem (&PackageLength, &TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Length, sizeof (UINT32));\r
+ //\r
+ // EFI_HII_PACK_HEADER.FrameworkPackageHeader.Length include the sizeof FrameworkPackageHeader itself.\r
+ //\r
+ PackageListLength += (PackageLength - sizeof(EFI_HII_PACK_HEADER));\r
+ \r
+ }\r
}\r
\r
//\r
\r
PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
\r
+ //\r
+ // Build the UEFI Package List.\r
+ //\r
for (Index = 0; Index < NumberOfPackages; Index++) {\r
- CopyMem (&PackageLength, &(TianoAutogenPackageHdrArray[Index]->BinaryLength), sizeof (UINT32));\r
- PackageLength -= sizeof (UINT32);\r
- CopyMem (PackageListData, &(TianoAutogenPackageHdrArray[Index]->PackageHeader), PackageLength);\r
+ if (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type == EFI_HII_FONT) {\r
+ PackageLength = (UINT32) GetUefiSimpleFontPackSize (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader);\r
+ FontPack = FrameworkFontPackToUefiSimpliedFont (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader);\r
+ CopyMem (PackageListData, FontPack, PackageLength);\r
+ FreePool (FontPack);\r
+ \r
+ } else {\r
+ CopyMem (&PackageLength, &(TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Length), sizeof (UINT32));\r
+ PackageLength -= sizeof (EFI_HII_PACK_HEADER);\r
+ CopyMem (PackageListData, &(TianoAutogenPackageHdrArray[Index]->PackageHeader), PackageLength);\r
+ \r
+ }\r
PackageListData += PackageLength;\r
}\r
\r
OUT EFI_GUID * Guid\r
)\r
{\r
- EFI_GUID GuidBase = { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e }};\r
-\r
- CopyGuid (Guid, &GuidBase);\r
+ CopyGuid (Guid, &mGuidBase);\r
\r
mGuidCount++; \r
*((UINT64 *) Guid) = *((UINT64 *) Guid) + mGuidCount;\r
LIST_ENTRY *Link;\r
EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader;\r
UINTN Size;\r
- HII_THUNK_CONTEXT *ThunkContext;\r
-\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
\r
Link = GetFirstNode (&Private->ThunkContextListHead);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
FreePool (StringPackageListHeader);\r
+\r
+ IfrThunkContext->SharingStringPack = TRUE;\r
+ ThunkContext->SharingStringPack = TRUE;\r
+ \r
return EFI_SUCCESS;\r
\r
}\r
Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
}\r
\r
+ //\r
+ // A Form Package must have a String Package to function.\r
+ // If ASSERT here, check the sequence of call to Hii->NewPack. \r
+ // String Pack must be registered before Ifr Package is registered.\r
+ //\r
ASSERT (FALSE);\r
return EFI_NOT_FOUND;\r
\r
EFI_STATUS Status;\r
UINTN StringPackageCount;\r
UINTN IfrPackageCount;\r
+ UINTN FontPackageCount;\r
EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
HII_THUNK_CONTEXT *ThunkContext;\r
HII_THUNK_CONTEXT *ThunkContextToRemove;\r
\r
PackageListHeader = NULL;\r
\r
- Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount);\r
+ Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount, &FontPackageCount);\r
ASSERT_EFI_ERROR (Status);\r
\r
if (IfrPackageCount > 1) {\r
//\r
// If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering\r
// packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is\r
- // not used as the name of the package list. A GUID is generated as a Package List\r
- // GUID.\r
+ // not used as the name of the package list. Formset GUID is used as the Package List\r
+ // GUID instead.\r
//\r
- ASSERT (StringPackageCount >=1 && IfrPackageCount == 1);\r
- IfrPackage = GetIfrPackage (Packages);\r
- GetFormSetGuid (IfrPackage, &ThunkContext->TagGuid);\r
+ ASSERT ((StringPackageCount >=1 && IfrPackageCount == 1) || (FontPackageCount > 0));\r
+ if (IfrPackageCount > 0) {\r
+ IfrPackage = GetIfrPackage (Packages);\r
+ GetFormSetGuid (IfrPackage, &ThunkContext->TagGuid);\r
+ } else {\r
+ ASSERT (FontPackageCount > 0);\r
+ GenerateRandomGuid (&ThunkContext->TagGuid);\r
+ }\r
+ \r
} else {\r
ThunkContextToRemove = TagGuidToIfrPackThunkContext (Private, Packages->GuidId);\r
\r
if (IfrPackageCount > 0 && \r
StringPackageCount > 0 && \r
- (ThunkContextToRemove!= NULL)) {\r
+ (ThunkContextToRemove != NULL)) {\r
DEBUG((EFI_D_WARN, "Framework code registers HII package list with the same GUID more than once.\n"));\r
- DEBUG((EFI_D_WARN, "This package list should be already registered. Just return successfully.\n"));\r
+ DEBUG((EFI_D_WARN, "Remove the previously registered package list and register the new one.\n"));\r
HiiRemovePack (This, ThunkContextToRemove->FwHiiHandle);\r
}\r
CopyGuid (&ThunkContext->TagGuid, Packages->GuidId);\r
+ \r
}\r
\r
//\r
// UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so\r
- // that Setup Utility can load the Buffer Storage using this protocol.\r
+ // that Setup Utility can load the Buffer Storage using this protocol. An UEFI VFR can only\r
+ // produce IFR package generated with Buffer Storage type and EFI Variable Storage.\r
+ // The default EFI_HII_CONFIG_ACCESS_PROTOCOL is used to Get/Set the Buffer Storage.\r
//\r
if (IfrPackageCount != 0) {\r
InstallDefaultConfigAccessProtocol (Packages, ThunkContext);\r
}\r
+ \r
PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &ThunkContext->TagGuid);\r
Status = mHiiDatabase->NewPackageList (\r
mHiiDatabase,\r
if (IfrPackageCount == 0) {\r
if (StringPackageCount != 0) {\r
//\r
- // Look for a Package List with only IFR Package with the same GUID name.\r
- // If found one, add the String Packages to it.\r
+ // Look for a Package List with only IFR Package with the same TAG GUID name.\r
+ // If found one, add the String Packages to the found Package List.\r
+ // This is needed because Framework HII Module may not register the String Package\r
+ // and IFR Package in one NewPack () call.\r
//\r
UpdatePackListWithOnlyIfrPack (\r
Private,\r
);\r
}\r
} else {\r
- CreateQuestionIdMap (ThunkContext);\r
- \r
if (StringPackageCount == 0) {\r
//\r
- // Register the Package List to UEFI HII first.\r
+ // Look for the String Package with the same TAG GUID name and add\r
+ // the found String Package to this Package List.\r
+ // This is needed because Framework HII Module may not register the String Package\r
+ // and IFR Package in one NewPack () call.\r
//\r
Status = FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
Private,\r
goto Done;\r
}\r
}\r
+ \r
+ //\r
+ // Parse the Formset. Must be called after FindStringPackAndUpdatePackListWithOnlyIfrPack is called so\r
+ // that String Package is ready.\r
+ //\r
+ ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
+ ASSERT (ThunkContext->FormSet != NULL);\r
+ \r
}\r
\r
Done:\r
}\r
\r
\r
+/**\r
+\r
+ Registers the various packages that are passed in a Package List.\r
+\r
+ @param This Pointer of Frameowk HII protocol instance.\r
+ @param Packages Pointer of HII packages.\r
+ @param Handle Handle value to be returned.\r
+\r
+ @retval EFI_SUCCESS Pacakges has added to HII database successfully.\r
+ @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
HiiNewPack (\r
IN EFI_HII_PACKAGES *Packages,\r
OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Extracts the various packs from a package list.\r
-\r
-Arguments:\r
-\r
- This - Pointer of HII protocol.\r
- Packages - Pointer of HII packages.\r
- Handle - Handle value to be returned.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Pacakges has added to HII database successfully.\r
- EFI_INVALID_PARAMETER - Invalid parameter.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
HII_THUNK_PRIVATE_DATA *Private;\r
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
\r
//\r
- // We use a simple Global variable to inform NewPackNotify\r
+ // We use a simple Global variable to inform NewOrAddPackNotify()\r
// that the package list registered here is already registered\r
- // in the HII Thunk Layer. So NewPackNotify does not need to\r
- // call RegisterUefiHiiHandle () to registered it.\r
+ // in the HII Thunk Layer. So NewOrAddPackNotify () does not need to\r
+ // call registered the Package List again.\r
//\r
mInFrameworkHiiNewPack = TRUE;\r
\r
return Status;\r
}\r
\r
+/**\r
+\r
+ Remove a package from the HII database.\r
+\r
+ @param This Pointer of Frameowk HII protocol instance.\r
+ @param Handle Handle value to be removed.\r
+\r
+ @retval EFI_SUCCESS Pacakges has added to HII database successfully.\r
+ @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
HiiRemovePack (\r
IN EFI_HII_PROTOCOL *This,\r
IN FRAMEWORK_EFI_HII_HANDLE Handle\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Removes the various packs from a Handle\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
- HII_THUNK_PRIVATE_DATA *Private;\r
- HII_THUNK_CONTEXT *ThunkContext;\r
+ HII_THUNK_PRIVATE_DATA *Private;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
EFI_TPL OldTpl;\r
\r
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
return Status;\r
}\r
\r
+/**\r
+ This notification function will be called when a Package List is registered\r
+ using UEFI HII interface. The Package List registered need to be recorded in\r
+ Framework Thunk module as Thunk Module may need to look for String Package in\r
+ the package registered.\r
+\r
+ If the Package List registered is not either Sting Package or IFR package, \r
+ then ASSERT. If the NotifyType is not ADD_PACK or NEW_PACK, then ASSERT.\r
+ Both cases means UEFI HII Database itself is buggy. \r
+\r
+ @param PackageType The Package Type.\r
+ @param PackageGuid The Package GUID.\r
+ @param Package The Package Header.\r
+ @param Handle The HII Handle of this Package List.\r
+ @param NotifyType The reason of the notification. \r
+\r
+ @retval EFI_SUCCESS The notification function is successful.\r
+ \r
+**/\r
EFI_STATUS\r
EFIAPI\r
NewOrAddPackNotify (\r
}\r
\r
//\r
- // We only create a ThunkContext if the Uefi Hii Handle is only already registered\r
- // by the HII Thunk Layer.\r
+ // We will create a ThunkContext to log the package list only if the\r
+ // package is not registered with by Framework HII Thunk module yet.\r
//\r
ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
if (ThunkContext == NULL) {\r
} \r
\r
if (PackageType == EFI_HII_PACKAGE_FORMS) {\r
- GetAttributesOfFirstFormSet (ThunkContext);\r
+ if (ThunkContext->FormSet != NULL) {\r
+ DestroyFormSet (ThunkContext->FormSet);\r
+ }\r
+\r
+ //\r
+ // Reparse the FormSet.\r
+ //\r
+ ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
+ ASSERT (ThunkContext->FormSet != NULL);\r
}\r
\r
return Status; \r
}\r
\r
-//\r
-// Framework HII module may cache a GUID as the name of the package list.\r
-// Then search for the Framework HII handle database for the handle matching\r
-// this GUID\r
+/**\r
+ This notification function will be called when a Package List is removed\r
+ using UEFI HII interface. The Package List removed need to be removed from\r
+ Framework Thunk module too.\r
+\r
+ If the Package List registered is not Sting Package, \r
+ then ASSERT. If the NotifyType is not REMOVE_PACK, then ASSERT.\r
+ Both cases means UEFI HII Database itself is buggy. \r
\r
+ @param PackageType The Package Type.\r
+ @param PackageGuid The Package GUID.\r
+ @param Package The Package Header.\r
+ @param Handle The HII Handle of this Package List.\r
+ @param NotifyType The reason of the notification. \r
+\r
+ @retval EFI_SUCCESS The notification function is successful.\r
+ \r
+**/\r
EFI_STATUS\r
EFIAPI\r
RemovePackNotify (\r