]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Add DriverHealthManagerDxe driver.
authorRuiyu Ni <ruiyu.ni@intel.com>
Wed, 6 May 2015 04:50:56 +0000 (04:50 +0000)
committerniruiyu <niruiyu@Edk2>
Wed, 6 May 2015 04:50:56 +0000 (04:50 +0000)
DriverHealthManagerDxe provides a driver health management VFR form
which will be sent by UefiBootManagerLib when booting a boot option.
It also provides another driver health management VFR form which will
be included by certain boot manager menu through the VFR class GUID.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17331 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthConfigureVfr.Vfr [new file with mode: 0644]
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.c [new file with mode: 0644]
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.h [new file with mode: 0644]
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf [new file with mode: 0644]
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerStrings.uni [new file with mode: 0644]
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerVfr.Vfr [new file with mode: 0644]
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerVfr.h [new file with mode: 0644]

index 14418f90b27e3c80111eb11082e81ddd7841409f..e38421225a78c64fe47d1c6b75f3b146a1a452a1 100644 (file)
 \r
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf\r
   MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf\r
 \r
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf\r
   MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf\r
+  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf\r
   MdeModulePkg/Universal/CapsulePei/CapsulePei.inf\r
   MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf\r
   MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf\r
   MdeModulePkg/Universal/CapsulePei/CapsulePei.inf\r
   MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf\r
   MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf\r
diff --git a/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthConfigureVfr.Vfr b/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthConfigureVfr.Vfr
new file mode 100644 (file)
index 0000000..12c8d60
--- /dev/null
@@ -0,0 +1,39 @@
+///** @file\r
+//  \r
+//    VFR to produce the formset used by BDS. This form only lists\r
+//    the Configure Required driver health instances.\r
+//  \r
+//  Copyright (c) 2013 - 2015, 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
+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+//**/\r
+#include "DriverHealthManagerVfr.h"\r
+\r
+formset\r
+  guid      = DRIVER_HEALTH_CONFIGURE_FORMSET_GUID,\r
+  title     = STRING_TOKEN(STR_FORM_TITLE),\r
+  help      = STRING_TOKEN(STR_FORM_HELP),\r
+  classguid = DRIVER_HEALTH_CONFIGURE_FORMSET_GUID,\r
+\r
+  form formid = DRIVER_HEALTH_FORM_ID,\r
+      title  = STRING_TOKEN(STR_FORM_TITLE);\r
+\r
+      label LABEL_BEGIN;\r
+      label LABEL_END;\r
+            \r
+      suppressif TRUE;\r
+          text\r
+              help  = STRING_TOKEN(STR_NULL),\r
+              text  = STRING_TOKEN(STR_NULL),\r
+              flags = INTERACTIVE,\r
+              key   = QUESTION_ID_REFRESH_CONFIGURE;\r
+      endif;\r
+\r
+  endform;\r
+endformset;\r
diff --git a/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.c b/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.c
new file mode 100644 (file)
index 0000000..3c863e5
--- /dev/null
@@ -0,0 +1,990 @@
+/** @file\r
+  This module produces two driver health manager forms.\r
+  One will be used by BDS core to configure the Configured Required\r
+  driver health instances, the other will be automatically included by\r
+  firmware setup (UI).\r
+\r
+Copyright (c) 2013 - 2015, 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
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DriverHealthManagerDxe.h"\r
+#include "DriverHealthManagerVfr.h"\r
+\r
+EFI_HII_CONFIG_ACCESS_PROTOCOL mDriverHealthManagerConfigAccess     = {\r
+  DriverHealthManagerFakeExtractConfig,\r
+  DriverHealthManagerFakeRouteConfig,\r
+  DriverHealthManagerCallback\r
+};\r
+\r
+EFI_GUID mDriverHealthManagerForm = DRIVER_HEALTH_MANAGER_FORMSET_GUID;\r
+\r
+FORM_DEVICE_PATH  mDriverHealthManagerFormDevicePath = {\r
+  {\r
+    {\r
+      HARDWARE_DEVICE_PATH,\r
+      HW_VENDOR_DP,\r
+      {\r
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    EFI_CALLER_ID_GUID\r
+  },\r
+  {\r
+    END_DEVICE_PATH_TYPE,\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    {\r
+      (UINT8) (END_DEVICE_PATH_LENGTH),\r
+      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
+    }\r
+  }\r
+};\r
+\r
+EFI_HII_HANDLE                       mDriverHealthManagerHiiHandle;\r
+EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO  *mDriverHealthManagerHealthInfo     = NULL;\r
+UINTN                                mDriverHealthManagerHealthInfoCount = 0;\r
+EFI_HII_DATABASE_PROTOCOL            *mDriverHealthManagerDatabase;\r
+\r
+\r
+extern UINT8 DriverHealthManagerVfrBin[];\r
+extern UINT8 DriverHealthConfigureVfrBin[];\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Request         A null-terminated Unicode string in <ConfigRequest> format.\r
+  @param Progress        On return, points to a character in the Request string.\r
+                         Points to the string's null terminator if request was successful.\r
+                         Points to the most recent '&' before the first failing name/value\r
+                         pair (or the beginning of the string if the failure is in the\r
+                         first name/value pair) if the request was not successful.\r
+  @param Results         A null-terminated Unicode string in <ConfigAltResp> format which\r
+                         has all values filled in for the names in the Request string.\r
+                         String to be allocated by the called function.\r
+\r
+  @retval  EFI_SUCCESS            The Results is filled with the requested values.\r
+  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
+  @retval  EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverHealthManagerFakeExtractConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Request,\r
+  OUT EFI_STRING                             *Progress,\r
+  OUT EFI_STRING                             *Results\r
+  )\r
+{\r
+  if (Progress == NULL || Results == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  *Progress = Request;\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Configuration   A null-terminated Unicode string in <ConfigResp> format.\r
+  @param Progress        A pointer to a string filled in with the offset of the most\r
+                         recent '&' before the first failing name/value pair (or the\r
+                         beginning of the string if the failure is in the first\r
+                         name/value pair) or the terminating NULL if all was successful.\r
+\r
+  @retval  EFI_SUCCESS            The Results is processed successfully.\r
+  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverHealthManagerFakeRouteConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Configuration,\r
+  OUT EFI_STRING                             *Progress\r
+  )\r
+{\r
+  if (Configuration == NULL || Progress == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+\r
+  Install the health manager forms.\r
+  One will be used by BDS core to configure the Configured Required\r
+  driver health instances, the other will be automatically included by\r
+  firmware setup (UI).\r
+\r
+  @param ImageHandle     The image handle.\r
+  @param SystemTable     The system table.\r
+\r
+  @retval  EFI_SUCEESS   The health manager forms are successfully installed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeDriverHealthManager (\r
+  EFI_HANDLE                 ImageHandle,\r
+  EFI_SYSTEM_TABLE           *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_HANDLE                  Handle;\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiDatabaseProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &mDriverHealthManagerDatabase\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Handle = NULL;\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Handle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &mDriverHealthManagerFormDevicePath,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  &mDriverHealthManagerConfigAccess,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  //\r
+  // Publish Driver Health HII data.\r
+  //\r
+  mDriverHealthManagerHiiHandle = HiiAddPackages (\r
+                                    &gEfiCallerIdGuid,\r
+                                    Handle,\r
+                                    DriverHealthManagerVfrBin,\r
+                                    DriverHealthConfigureVfrBin,\r
+                                    STRING_ARRAY_NAME,\r
+                                    NULL\r
+                                    );\r
+  ASSERT (mDriverHealthManagerHiiHandle != NULL);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+  Select the best matching language according to front page policy for best user experience.\r
+\r
+  This function supports both ISO 639-2 and RFC 4646 language codes, but language\r
+  code types may not be mixed in a single call to this function.\r
+\r
+  @param  SupportedLanguages   A pointer to a Null-terminated ASCII string that\r
+                               contains a set of language codes in the format\r
+                               specified by Iso639Language.\r
+  @param  Iso639Language       If TRUE, then all language codes are assumed to be\r
+                               in ISO 639-2 format.  If FALSE, then all language\r
+                               codes are assumed to be in RFC 4646 language format.\r
+\r
+  @retval NULL                 The best matching language could not be found in SupportedLanguages.\r
+  @retval NULL                 There are not enough resources available to return the best matching\r
+                               language.\r
+  @retval Other                A pointer to a Null-terminated ASCII string that is the best matching\r
+                               language in SupportedLanguages.\r
+**/\r
+CHAR8 *\r
+DriverHealthManagerSelectBestLanguage (\r
+  IN CHAR8        *SupportedLanguages,\r
+  IN BOOLEAN      Iso639Language\r
+  )\r
+{\r
+  CHAR8           *LanguageVariable;\r
+  CHAR8           *BestLanguage;\r
+\r
+  LanguageVariable =  GetEfiGlobalVariable (Iso639Language ? L"Lang" : L"PlatformLang");\r
+\r
+  BestLanguage = GetBestLanguage(\r
+                   SupportedLanguages,\r
+                   Iso639Language,\r
+                   (LanguageVariable != NULL) ? LanguageVariable : "",\r
+                   Iso639Language ? "eng" : "en-US",\r
+                   NULL\r
+                   );\r
+  if (LanguageVariable != NULL) {\r
+    FreePool (LanguageVariable);\r
+  }\r
+\r
+  return BestLanguage;\r
+}\r
+\r
+\r
+\r
+/**\r
+\r
+  This is an internal worker function to get the Component Name (2) protocol interface\r
+  and the language it supports.\r
+\r
+  @param  ProtocolGuid         A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.\r
+  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.\r
+  @param  ComponentName        A pointer to the Component Name (2) protocol interface.\r
+  @param  SupportedLanguage    The best suitable language that matches the SupportedLangues interface for the\r
+                               located Component Name (2) instance.\r
+\r
+  @retval EFI_SUCCESS          The Component Name (2) protocol instance is successfully located and we find\r
+                               the best matching language it support.\r
+  @retval EFI_UNSUPPORTED      The input Language is not supported by the Component Name (2) protocol.\r
+  @retval Other                Some error occurs when locating Component Name (2) protocol instance or finding\r
+                               the supported language.\r
+\r
+**/\r
+EFI_STATUS\r
+DriverHealthManagerGetComponentNameWorker (\r
+  IN  EFI_GUID                    *ProtocolGuid,\r
+  IN  EFI_HANDLE                  DriverBindingHandle,\r
+  OUT EFI_COMPONENT_NAME_PROTOCOL **ComponentName,\r
+  OUT CHAR8                       **SupportedLanguage\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+\r
+  //\r
+  // Locate Component Name (2) protocol on the driver binging handle.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                 DriverBindingHandle,\r
+                 ProtocolGuid,\r
+                 (VOID **) ComponentName,\r
+                 NULL,\r
+                 NULL,\r
+                 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                 );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Apply shell policy to select the best language.\r
+  //\r
+  *SupportedLanguage = DriverHealthManagerSelectBestLanguage (\r
+                         (*ComponentName)->SupportedLanguages,\r
+                         (BOOLEAN) (ProtocolGuid == &gEfiComponentNameProtocolGuid)\r
+                         );\r
+  if (*SupportedLanguage == NULL) {\r
+    Status = EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+\r
+  This is an internal worker function to get driver name from Component Name (2) protocol interface.\r
+\r
+  @param  ProtocolGuid         A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.\r
+  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.\r
+  @param  DriverName           A pointer to the Unicode string to return. This Unicode string is the name\r
+                               of the driver specified by This.\r
+\r
+  @retval EFI_SUCCESS          The driver name is successfully retrieved from Component Name (2) protocol\r
+                               interface.\r
+  @retval Other                The driver name cannot be retrieved from Component Name (2) protocol\r
+                               interface.\r
+\r
+**/\r
+EFI_STATUS\r
+DriverHealthManagerGetDriverNameWorker (\r
+  IN  EFI_GUID    *ProtocolGuid,\r
+  IN  EFI_HANDLE  DriverBindingHandle,\r
+  OUT CHAR16      **DriverName\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  CHAR8                          *BestLanguage;\r
+  EFI_COMPONENT_NAME_PROTOCOL    *ComponentName;\r
+\r
+  //\r
+  // Retrieve Component Name (2) protocol instance on the driver binding handle and\r
+  // find the best language this instance supports.\r
+  //\r
+  Status = DriverHealthManagerGetComponentNameWorker (\r
+             ProtocolGuid,\r
+             DriverBindingHandle,\r
+             &ComponentName,\r
+             &BestLanguage\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get the driver name from Component Name (2) protocol instance on the driver binging handle.\r
+  //\r
+  Status = ComponentName->GetDriverName (\r
+                            ComponentName,\r
+                            BestLanguage,\r
+                            DriverName\r
+                            );\r
+  FreePool (BestLanguage);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface\r
+  in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name.\r
+  If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward\r
+  compatibility support.\r
+\r
+  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.\r
+\r
+  @return A pointer to the Unicode string to return. This Unicode string is the name of the controller\r
+          specified by ControllerHandle and ChildHandle.\r
+\r
+\r
+**/\r
+CHAR16 *\r
+DriverHealthManagerGetDriverName (\r
+  IN  EFI_HANDLE  DriverBindingHandle\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  CHAR16          *DriverName;\r
+\r
+  //\r
+  // Get driver name from UEFI 2.0 Component Name 2 protocol interface.\r
+  //\r
+  Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentName2ProtocolGuid, DriverBindingHandle, &DriverName);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // If it fails to get the driver name from Component Name protocol interface, we should fall back on\r
+    // EFI 1.1 Component Name protocol interface.\r
+    //\r
+    Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentNameProtocolGuid, DriverBindingHandle, &DriverName);\r
+  }\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    return AllocateCopyPool (StrSize (DriverName), DriverName);\r
+  } else {\r
+    return ConvertDevicePathToText (DevicePathFromHandle (DriverBindingHandle), FALSE, TRUE);\r
+  }\r
+}\r
+\r
+\r
+\r
+/**\r
+  This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface\r
+  in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.\r
+  If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward\r
+  compatibility support.\r
+\r
+  @param  ProtocolGuid         A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.\r
+  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.\r
+  @param  ControllerHandle     The handle of a controller that the driver specified by This is managing.\r
+                               This handle specifies the controller whose name is to be returned.\r
+  @param  ChildHandle          The handle of the child controller to retrieve the name of. This is an\r
+                               optional parameter that may be NULL. It will be NULL for device drivers.\r
+                               It will also be NULL for bus drivers that attempt to retrieve the name\r
+                               of the bus controller. It will not be NULL for a bus driver that attempts\r
+                               to retrieve the name of a child controller.\r
+  @param  ControllerName       A pointer to the Unicode string to return. This Unicode string\r
+                               is the name of the controller specified by ControllerHandle and ChildHandle.\r
+\r
+  @retval  EFI_SUCCESS         The controller name is successfully retrieved from Component Name (2) protocol\r
+                               interface.\r
+  @retval  Other               The controller name cannot be retrieved from Component Name (2) protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+DriverHealthManagerGetControllerNameWorker (\r
+  IN  EFI_GUID    *ProtocolGuid,\r
+  IN  EFI_HANDLE  DriverBindingHandle,\r
+  IN  EFI_HANDLE  ControllerHandle,\r
+  IN  EFI_HANDLE  ChildHandle,\r
+  OUT CHAR16      **ControllerName\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  CHAR8                          *BestLanguage;\r
+  EFI_COMPONENT_NAME_PROTOCOL    *ComponentName;\r
+\r
+  //\r
+  // Retrieve Component Name (2) protocol instance on the driver binding handle and\r
+  // find the best language this instance supports.\r
+  //\r
+  Status = DriverHealthManagerGetComponentNameWorker (\r
+             ProtocolGuid,\r
+             DriverBindingHandle,\r
+             &ComponentName,\r
+             &BestLanguage\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get the controller name from Component Name (2) protocol instance on the driver binging handle.\r
+  //\r
+  Status = ComponentName->GetControllerName (\r
+                            ComponentName,\r
+                            ControllerHandle,\r
+                            ChildHandle,\r
+                            BestLanguage,\r
+                            ControllerName\r
+                            );\r
+  FreePool (BestLanguage);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+\r
+  This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface\r
+  in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.\r
+  If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward\r
+  compatibility support.\r
+\r
+  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.\r
+  @param  ControllerHandle     The handle of a controller that the driver specified by DriverBindingHandle is managing.\r
+                               This handle specifies the controller whose name is to be returned.\r
+  @param  ChildHandle          The handle of the child controller to retrieve the name of. This is an\r
+                               optional parameter that may be NULL. It will be NULL for device drivers.\r
+                               It will also be NULL for bus drivers that attempt to retrieve the name\r
+                               of the bus controller. It will not be NULL for a bus driver that attempts\r
+                               to retrieve the name of a child controller.\r
+\r
+  @return A pointer to the Unicode string to return. This Unicode string is the name of the controller\r
+          specified by ControllerHandle and ChildHandle.\r
+**/\r
+CHAR16 *\r
+DriverHealthManagerGetControllerName (\r
+  IN  EFI_HANDLE  DriverBindingHandle,\r
+  IN  EFI_HANDLE  ControllerHandle,\r
+  IN  EFI_HANDLE  ChildHandle\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  CHAR16          *ControllerName;\r
+\r
+  //\r
+  // Get controller name from UEFI 2.0 Component Name 2 protocol interface.\r
+  //\r
+  Status = DriverHealthManagerGetControllerNameWorker (\r
+             &gEfiComponentName2ProtocolGuid,\r
+             DriverBindingHandle,\r
+             ControllerHandle,\r
+             ChildHandle,\r
+             &ControllerName\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // If it fails to get the controller name from Component Name protocol interface, we should fall back on\r
+    // EFI 1.1 Component Name protocol interface.\r
+    //\r
+    Status = DriverHealthManagerGetControllerNameWorker (\r
+               &gEfiComponentNameProtocolGuid,\r
+               DriverBindingHandle,\r
+               ControllerHandle,\r
+               ChildHandle,\r
+               &ControllerName\r
+               );\r
+  }\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    return AllocateCopyPool (StrSize (ControllerName), ControllerName);\r
+  } else {\r
+    return ConvertDevicePathToText (DevicePathFromHandle (ChildHandle != NULL ? ChildHandle : ControllerHandle), FALSE, TRUE);\r
+  }\r
+}\r
+\r
+/**\r
+  The repair notify function.\r
+  @param Value  A value between 0 and Limit that identifies the current progress\r
+                of the repair operation.\r
+  @param Limit  The maximum value of Value for the current repair operation.\r
+                If Limit is 0, then the completion progress is indeterminate.\r
+                For example, a driver that wants to specify progress in percent\r
+                would use a Limit value of 100.\r
+\r
+  @retval EFI_SUCCESS  Successfully return from the notify function.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverHealthManagerRepairNotify (\r
+  IN UINTN        Value,\r
+  IN UINTN        Limit\r
+  )\r
+{\r
+  DEBUG ((EFI_D_INFO, "[DriverHealthManagement]RepairNotify: %d/%d\n", Value, Limit));\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Look for the formset GUID which has the gEfiHiiDriverHealthFormsetGuid class GUID in the specified HII package list.\r
+\r
+  @param Handle         Handle to the HII package list.\r
+  @param FormsetGuid    Return the formset GUID.\r
+\r
+  @retval EFI_SUCCESS   The formset is found successfully.\r
+  @retval EFI_NOT_FOUND The formset cannot be found.\r
+**/\r
+EFI_STATUS\r
+DriverHealthManagerGetFormsetId (\r
+  IN  EFI_HII_HANDLE   Handle,\r
+  OUT EFI_GUID         *FormsetGuid\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+  UINTN                        BufferSize;\r
+  UINT8                        *Package;\r
+  UINT8                        *OpCodeData;\r
+  UINT32                       Offset;\r
+  UINT32                       Offset2;\r
+  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
+  UINT8                        Index;\r
+  UINT8                        NumberOfClassGuid;\r
+  EFI_GUID                     *ClassGuid;\r
+\r
+  //\r
+  // Get HII PackageList\r
+  //\r
+  BufferSize     = 0;\r
+  HiiPackageList = NULL;\r
+  Status = mDriverHealthManagerDatabase->ExportPackageLists (mDriverHealthManagerDatabase, Handle, &BufferSize, HiiPackageList);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    HiiPackageList = AllocatePool (BufferSize);\r
+    ASSERT (HiiPackageList != NULL);\r
+\r
+    Status = mDriverHealthManagerDatabase->ExportPackageLists (mDriverHealthManagerDatabase, Handle, &BufferSize, HiiPackageList);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  ASSERT (HiiPackageList != NULL);\r
+\r
+  //\r
+  // Get Form package from this HII package List\r
+  //\r
+  for (Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); Offset < ReadUnaligned32 (&HiiPackageList->PackageLength); Offset += PackageHeader.Length) {\r
+    Package = ((UINT8 *) HiiPackageList) + Offset;\r
+    CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+\r
+    if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
+      //\r
+      // Search FormSet in this Form Package\r
+      //\r
+      \r
+      for (Offset2 = sizeof (EFI_HII_PACKAGE_HEADER); Offset2 < PackageHeader.Length; Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {\r
+        OpCodeData = Package + Offset2;\r
+\r
+        if ((((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) &&\r
+            (((EFI_IFR_OP_HEADER *) OpCodeData)->Length > OFFSET_OF (EFI_IFR_FORM_SET, Flags))) {\r
+          //\r
+          // Try to compare against formset class GUID\r
+          //\r
+          NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
+          ClassGuid         = (EFI_GUID *) (OpCodeData + sizeof (EFI_IFR_FORM_SET));\r
+          for (Index = 0; Index < NumberOfClassGuid; Index++) {\r
+            if (CompareGuid (&gEfiHiiDriverHealthFormsetGuid, &ClassGuid[Index])) {\r
+              CopyMem (FormsetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
+              FreePool (HiiPackageList);\r
+              return EFI_SUCCESS;\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Form package not found in this Package List\r
+  //\r
+  FreePool (HiiPackageList);\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Processes a single controller using the EFI Driver Health Protocol associated with\r
+  that controller.\r
+\r
+  @param DriverHealth       A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.\r
+  @param ControllerHandle   The class guid specifies which form set will be displayed.\r
+  @param ChildHandle        The handle of the child controller to retrieve the health\r
+                            status on.  This is an optional parameter that may be NULL.\r
+  @param HealthStatus       The health status of the controller.\r
+  @param MessageList        An array of warning or error messages associated\r
+                            with the controller specified by ControllerHandle and\r
+                            ChildHandle.  This is an optional parameter that may be NULL.\r
+  @param FormHiiHandle      The HII handle for an HII form associated with the\r
+                            controller specified by ControllerHandle and ChildHandle.\r
+**/\r
+VOID\r
+DriverHealthManagerProcessSingleControllerHealth (\r
+  IN  EFI_DRIVER_HEALTH_PROTOCOL         *DriverHealth,\r
+  IN  EFI_HANDLE                         ControllerHandle, OPTIONAL\r
+  IN  EFI_HANDLE                         ChildHandle,      OPTIONAL\r
+  IN  EFI_DRIVER_HEALTH_STATUS           HealthStatus,\r
+  IN  EFI_DRIVER_HEALTH_HII_MESSAGE      **MessageList,    OPTIONAL\r
+  IN  EFI_HII_HANDLE                     FormHiiHandle\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+\r
+  ASSERT (HealthStatus != EfiDriverHealthStatusConfigurationRequired);\r
+  //\r
+  // If the module need to be repaired or reconfiguration,  will process it until\r
+  // reach a terminal status. The status from EfiDriverHealthStatusRepairRequired after repair\r
+  // will be in (Health, Failed, Configuration Required).\r
+  //\r
+  switch (HealthStatus) {\r
+\r
+  case EfiDriverHealthStatusRepairRequired:\r
+    Status = DriverHealth->Repair (\r
+                             DriverHealth,\r
+                             ControllerHandle,\r
+                             ChildHandle,\r
+                             DriverHealthManagerRepairNotify\r
+                             );\r
+    break;\r
+\r
+  case EfiDriverHealthStatusRebootRequired:\r
+    gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
+    break;\r
+\r
+  case EfiDriverHealthStatusReconnectRequired:\r
+    Status = gBS->DisconnectController (ControllerHandle, NULL, NULL);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Disconnect failed.  Need to promote reconnect to a reboot.\r
+      //\r
+      gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
+    } else {\r
+      gBS->ConnectController (ControllerHandle, NULL, NULL, TRUE);\r
+    }\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+}\r
+\r
+/**\r
+  Update the form to include the driver health instances.\r
+\r
+  @param ConfigureOnly  Only include the configure required driver health instances\r
+                        when TRUE, include all the driver health instances otherwise.\r
+**/\r
+VOID\r
+DriverHealthManagerUpdateForm (\r
+  BOOLEAN                     ConfigureOnly\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_IFR_GUID_LABEL          *StartLabel;\r
+  EFI_IFR_GUID_LABEL          *EndLabel;\r
+  VOID                        *StartOpCodeHandle;\r
+  VOID                        *EndOpCodeHandle;\r
+  UINTN                       Index;\r
+  EFI_STRING_ID               Prompt;\r
+  EFI_STRING_ID               Help;\r
+  CHAR16                      String[512];\r
+  UINTN                       StringCount;\r
+  EFI_STRING                  TmpString;\r
+  EFI_STRING                  DriverName;\r
+  EFI_STRING                  ControllerName;\r
+  UINTN                       MessageIndex;\r
+  EFI_HANDLE                  DriverHandle;\r
+  EFI_STRING_ID               DevicePath;\r
+  EFI_GUID                    FormsetGuid;\r
+\r
+  EfiBootManagerFreeDriverHealthInfo (mDriverHealthManagerHealthInfo, mDriverHealthManagerHealthInfoCount);\r
+  mDriverHealthManagerHealthInfo = EfiBootManagerGetDriverHealthInfo (&mDriverHealthManagerHealthInfoCount);\r
+\r
+  //\r
+  // Allocate space for creation of UpdateData Buffer\r
+  //\r
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  ASSERT (StartOpCodeHandle != NULL);\r
+\r
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  ASSERT (EndOpCodeHandle != NULL);\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode as the start opcode\r
+  //\r
+  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+  StartLabel->Number       = LABEL_BEGIN;\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode as the end opcode\r
+  //\r
+  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+  EndLabel->Number       = LABEL_END;\r
+\r
+  for (Index = 0; Index < mDriverHealthManagerHealthInfoCount; Index++) {\r
+    if (ConfigureOnly && mDriverHealthManagerHealthInfo[Index].HealthStatus != EfiDriverHealthStatusConfigurationRequired) {\r
+      continue;\r
+    }\r
+    DriverName = DriverHealthManagerGetDriverName (mDriverHealthManagerHealthInfo[Index].DriverHealthHandle);\r
+    ASSERT (DriverName != NULL);\r
+\r
+    if (mDriverHealthManagerHealthInfo[Index].ControllerHandle == NULL) {\r
+      //\r
+      // The ControllerHandle is set to NULL and the HealthStatus is set to EfiDriverHealthStatusHealthy\r
+      // if all the controllers managed by the driver are in healthy state.\r
+      //\r
+      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy);\r
+      UnicodeSPrint (String, sizeof (String), L"%s", DriverName);\r
+    } else {\r
+      ControllerName = DriverHealthManagerGetControllerName (\r
+                         mDriverHealthManagerHealthInfo[Index].DriverHealthHandle,\r
+                         mDriverHealthManagerHealthInfo[Index].ControllerHandle,\r
+                         mDriverHealthManagerHealthInfo[Index].ChildHandle\r
+                         );\r
+      ASSERT (ControllerName != NULL);\r
+      UnicodeSPrint (String, sizeof (String), L"%s    %s", DriverName, ControllerName);\r
+      FreePool (ControllerName);\r
+    }\r
+    FreePool (DriverName);\r
+\r
+    Prompt = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL);\r
+\r
+    switch(mDriverHealthManagerHealthInfo[Index].HealthStatus) {\r
+    case EfiDriverHealthStatusRepairRequired:\r
+      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REPAIR_REQUIRED), NULL);\r
+      break;\r
+    case EfiDriverHealthStatusConfigurationRequired:\r
+      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_CONFIGURATION_REQUIRED), NULL);\r
+      break;\r
+    case EfiDriverHealthStatusFailed:\r
+      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_FAILED), NULL);\r
+      break;\r
+    case EfiDriverHealthStatusReconnectRequired:\r
+      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_RECONNECT_REQUIRED), NULL);\r
+      break;\r
+    case EfiDriverHealthStatusRebootRequired:\r
+      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REBOOT_REQUIRED), NULL);\r
+      break;\r
+    default:\r
+      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy);\r
+      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_HEALTHY), NULL);\r
+      break;\r
+    }\r
+    StringCount = UnicodeSPrint (String, sizeof (String), L"%s\n", TmpString);\r
+    FreePool (TmpString);\r
+\r
+    //\r
+    // Add the message of the Module itself provided as the help.\r
+    //\r
+    if (mDriverHealthManagerHealthInfo[Index].MessageList != NULL) {\r
+      for (MessageIndex = 0; mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle != NULL; MessageIndex++) {\r
+        TmpString = HiiGetString (\r
+                      mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle,\r
+                      mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].StringId,\r
+                      NULL\r
+                      );\r
+        StringCount += UnicodeSPrint (String + StringCount, sizeof (String) - sizeof (String[0]) * StringCount, L"\n%s", TmpString);\r
+        FreePool (TmpString);\r
+      }\r
+    }\r
+    Help = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL);\r
+\r
+    switch (mDriverHealthManagerHealthInfo[Index].HealthStatus) {\r
+    case EfiDriverHealthStatusConfigurationRequired:\r
+      Status = mDriverHealthManagerDatabase->GetPackageListHandle (\r
+                                               mDriverHealthManagerDatabase,\r
+                                               mDriverHealthManagerHealthInfo[Index].HiiHandle,\r
+                                               &DriverHandle\r
+                                               );\r
+      ASSERT_EFI_ERROR (Status);\r
+      TmpString  = ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, TRUE);\r
+      DevicePath = HiiSetString (mDriverHealthManagerHiiHandle, 0, TmpString, NULL);\r
+      FreePool (TmpString);\r
+\r
+      Status = DriverHealthManagerGetFormsetId (mDriverHealthManagerHealthInfo[Index].HiiHandle, &FormsetGuid);\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      HiiCreateGotoExOpCode (\r
+        StartOpCodeHandle,\r
+        0,\r
+        Prompt,\r
+        Help,\r
+        0,\r
+        0,\r
+        0,\r
+        &FormsetGuid,\r
+        DevicePath\r
+        );\r
+      break;\r
+\r
+    case EfiDriverHealthStatusRepairRequired:\r
+    case EfiDriverHealthStatusReconnectRequired:\r
+    case EfiDriverHealthStatusRebootRequired:\r
+      HiiCreateActionOpCode (\r
+        StartOpCodeHandle,\r
+        (EFI_QUESTION_ID) (Index + QUESTION_ID_DRIVER_HEALTH_BASE),\r
+        Prompt,\r
+        Help,\r
+        EFI_IFR_FLAG_CALLBACK,\r
+        0\r
+        );\r
+      break;\r
+\r
+    default:\r
+      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy ||\r
+              mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusFailed);\r
+      HiiCreateTextOpCode (\r
+        StartOpCodeHandle,\r
+        Prompt,\r
+        Help,\r
+        0\r
+        );\r
+      break;\r
+    }\r
+  }\r
+\r
+  Status = HiiUpdateForm (\r
+             mDriverHealthManagerHiiHandle,\r
+             ConfigureOnly ? PcdGetPtr (PcdDriverHealthConfigureForm) : &mDriverHealthManagerForm,\r
+             DRIVER_HEALTH_FORM_ID,\r
+             StartOpCodeHandle,\r
+             EndOpCodeHandle\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+  HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+}\r
+\r
+/**\r
+  Called when the form is closing to remove the dynamicly added string from the HII package list.\r
+**/\r
+VOID\r
+DriverHealthManagerCleanDynamicString (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+  UINTN                        BufferSize;\r
+  EFI_HII_PACKAGE_HEADER       *PackageHeader;\r
+  UINT32                       FixedStringSize;\r
+\r
+  FixedStringSize = *(UINT32 *) &STRING_ARRAY_NAME - sizeof (UINT32);\r
+  BufferSize      = sizeof (EFI_HII_PACKAGE_LIST_HEADER) + FixedStringSize + sizeof (EFI_HII_PACKAGE_HEADER);\r
+  HiiPackageList  = AllocatePool (BufferSize);\r
+  ASSERT (HiiPackageList != NULL);\r
+\r
+  HiiPackageList->PackageLength = (UINT32) BufferSize;\r
+  CopyMem (&HiiPackageList->PackageListGuid, &gEfiCallerIdGuid, sizeof (EFI_GUID));\r
+\r
+  PackageHeader = (EFI_HII_PACKAGE_HEADER *) (HiiPackageList + 1);\r
+  CopyMem (PackageHeader, STRING_ARRAY_NAME + sizeof (UINT32), FixedStringSize);\r
+\r
+  PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);\r
+  PackageHeader->Type   = EFI_HII_PACKAGE_END;\r
+  PackageHeader->Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
+\r
+  Status = mDriverHealthManagerDatabase->UpdatePackageList (\r
+                                           mDriverHealthManagerDatabase,\r
+                                           mDriverHealthManagerHiiHandle,\r
+                                           HiiPackageList\r
+                                           );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Form package not found in this Package List\r
+  //\r
+  FreePool (HiiPackageList);\r
+}\r
+\r
+/**\r
+  This function is invoked if user selected a interactive opcode from Driver Health's\r
+  Formset.\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Action          Specifies the type of action taken by the browser.\r
+  @param QuestionId      A unique value which is sent to the original exporting driver\r
+                         so that it can identify the type of data to expect.\r
+  @param Type            The type of value for the question.\r
+  @param Value           A pointer to the data being sent to the original exporting driver.\r
+  @param ActionRequest   On return, points to the action requested by the callback function.\r
+\r
+  @retval  EFI_SUCCESS           The callback successfully handled the action.\r
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverHealthManagerCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  EFI_BROWSER_ACTION                     Action,\r
+  IN  EFI_QUESTION_ID                        QuestionId,\r
+  IN  UINT8                                  Type,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
+  )\r
+{\r
+  UINTN                                      Index;\r
+\r
+  if (QuestionId == QUESTION_ID_REFRESH_MANAGER || QuestionId == QUESTION_ID_REFRESH_CONFIGURE) {\r
+    if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
+      DriverHealthManagerUpdateForm ((BOOLEAN) (QuestionId == QUESTION_ID_REFRESH_CONFIGURE));\r
+    } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {\r
+      DriverHealthManagerCleanDynamicString ();\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (Action != EFI_BROWSER_ACTION_CHANGED) {\r
+    //\r
+    // Do nothing for other UEFI Action. Only do call back when data is changed.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if ((Value == NULL) || (ActionRequest == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  DEBUG ((EFI_D_ERROR, "QuestionId = %x\n", QuestionId));\r
+\r
+  //\r
+  // We will have returned from processing a callback - user either hit ESC to exit, or selected\r
+  // a target to display.\r
+  // Process the diver health status states here.\r
+  //\r
+  Index = QuestionId - QUESTION_ID_DRIVER_HEALTH_BASE;\r
+  ASSERT (Index < mDriverHealthManagerHealthInfoCount);\r
+  //\r
+  // Process the driver's healthy status for the specify module\r
+  //\r
+  DriverHealthManagerProcessSingleControllerHealth (\r
+    mDriverHealthManagerHealthInfo[Index].DriverHealth,\r
+    mDriverHealthManagerHealthInfo[Index].ControllerHandle,\r
+    mDriverHealthManagerHealthInfo[Index].ChildHandle,\r
+    mDriverHealthManagerHealthInfo[Index].HealthStatus,\r
+    &(mDriverHealthManagerHealthInfo[Index].MessageList),\r
+    mDriverHealthManagerHealthInfo[Index].HiiHandle\r
+    );\r
+\r
+  DriverHealthManagerUpdateForm ((BOOLEAN) (QuestionId == QUESTION_ID_REFRESH_CONFIGURE));\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
diff --git a/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.h b/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.h
new file mode 100644 (file)
index 0000000..179bc94
--- /dev/null
@@ -0,0 +1,133 @@
+/** @file\r
+  This module produces two driver health manager forms.\r
+  One will be used by BDS core to configure the Configured Required\r
+  driver health instances, the other will be automatically included by\r
+  firmware setup (UI).\r
+\r
+Copyright (c) 2013 - 2015, 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
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _DRIVER_HEALTH_MANAGEMENT_DXE_H_\r
+#define _DRIVER_HEALTH_MANAGEMENT_DXE_H_\r
+\r
+#include <Uefi.h>\r
+#include <Base.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/DriverHealth.h>\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/FormBrowser2.h>\r
+#include <Protocol/HiiDatabase.h>\r
+#include <Guid/MdeModuleHii.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiBootManagerLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+///\r
+/// HII specific Vendor Device Path definition.\r
+///\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH             VendorDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL       End;\r
+} FORM_DEVICE_PATH;\r
+\r
+/**\r
+  This function is invoked if user selected a interactive opcode from Driver Health's\r
+  Formset. The decision by user is saved to gCallbackKey for later processing.\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Action          Specifies the type of action taken by the browser.\r
+  @param QuestionId      A unique value which is sent to the original exporting driver\r
+                         so that it can identify the type of data to expect.\r
+  @param Type            The type of value for the question.\r
+  @param Value           A pointer to the data being sent to the original exporting driver.\r
+  @param ActionRequest   On return, points to the action requested by the callback function.\r
+\r
+  @retval  EFI_SUCCESS           The callback successfully handled the action.\r
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverHealthManagerCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  EFI_BROWSER_ACTION                     Action,\r
+  IN  EFI_QUESTION_ID                        QuestionId,\r
+  IN  UINT8                                  Type,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
+  );\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Request         A null-terminated Unicode string in <ConfigRequest> format.\r
+  @param Progress        On return, points to a character in the Request string.\r
+                         Points to the string's null terminator if request was successful.\r
+                         Points to the most recent '&' before the first failing name/value\r
+                         pair (or the beginning of the string if the failure is in the\r
+                         first name/value pair) if the request was not successful.\r
+  @param Results         A null-terminated Unicode string in <ConfigAltResp> format which\r
+                         has all values filled in for the names in the Request string.\r
+                         String to be allocated by the called function.\r
+\r
+  @retval  EFI_SUCCESS            The Results is filled with the requested values.\r
+  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
+  @retval  EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverHealthManagerFakeExtractConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Request,\r
+  OUT EFI_STRING                             *Progress,\r
+  OUT EFI_STRING                             *Results\r
+  );\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Configuration   A null-terminated Unicode string in <ConfigResp> format.\r
+  @param Progress        A pointer to a string filled in with the offset of the most\r
+                         recent '&' before the first failing name/value pair (or the\r
+                         beginning of the string if the failure is in the first\r
+                         name/value pair) or the terminating NULL if all was successful.\r
+\r
+  @retval  EFI_SUCCESS            The Results is processed successfully.\r
+  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverHealthManagerFakeRouteConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Configuration,\r
+  OUT EFI_STRING                             *Progress\r
+  );\r
+#endif\r
diff --git a/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf b/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
new file mode 100644 (file)
index 0000000..ca4a4dd
--- /dev/null
@@ -0,0 +1,74 @@
+## @file\r
+#  This module produces two driver health manager forms.\r
+#  One will be used by BDS core to configure the Configured Required\r
+#  driver health instances, the other will be automatically included by\r
+#  firmware setup (UI).\r
+#\r
+#  Copyright (c) 2013 - 2015, 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
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  \r
+##\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DriverHealthManagerDxe\r
+  FILE_GUID                      = EBF8ED7C-0DD1-4787-84F1-F48D537DCACF\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = InitializeDriverHealthManager\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+\r
+[Sources.common]\r
+  DriverHealthManagerDxe.h\r
+  DriverHealthManagerDxe.c\r
+  DriverHealthManagerStrings.uni\r
+  DriverHealthManagerVfr.Vfr\r
+  DriverHealthManagerVfr.h\r
+  DriverHealthConfigureVfr.Vfr\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  UefiRuntimeServicesTableLib\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+  BaseLib\r
+  UefiLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+  HiiLib\r
+  UefiBootManagerLib\r
+  PcdLib\r
+  DevicePathLib\r
+\r
+[Protocols]\r
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES\r
+\r
+[Guids]\r
+  gEfiHiiDriverHealthFormsetGuid                ## CONSUMES ## GUID\r
+  gEfiIfrTianoGuid                              ## CONSUMES ## HII\r
+\r
+[Pcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDriverHealthConfigureForm      ## CONSUMES\r
+\r
+[Depex]\r
+  gEfiHiiDatabaseProtocolGuid AND gEfiFormBrowser2ProtocolGuid
\ No newline at end of file
diff --git a/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerStrings.uni b/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerStrings.uni
new file mode 100644 (file)
index 0000000..e3e4311
Binary files /dev/null and b/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerStrings.uni differ
diff --git a/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerVfr.Vfr b/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerVfr.Vfr
new file mode 100644 (file)
index 0000000..cfc1cf7
--- /dev/null
@@ -0,0 +1,38 @@
+///** @file\r
+//  \r
+//    VFR to produce the formset used by UI.\r
+//  \r
+//  Copyright (c) 2013 - 2015, 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
+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//**/\r
+\r
+#include "DriverHealthManagerVfr.h"\r
+\r
+formset\r
+  guid      = DRIVER_HEALTH_MANAGER_FORMSET_GUID,\r
+  title     = STRING_TOKEN(STR_FORM_TITLE),\r
+  help      = STRING_TOKEN(STR_FORM_HELP),\r
+  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,\r
+\r
+  form formid = DRIVER_HEALTH_FORM_ID,\r
+      title  = STRING_TOKEN(STR_FORM_TITLE);\r
+\r
+      label LABEL_BEGIN;\r
+      label LABEL_END;\r
+\r
+      suppressif TRUE;\r
+          text\r
+              help  = STRING_TOKEN(STR_NULL),\r
+              text  = STRING_TOKEN(STR_NULL),\r
+              flags = INTERACTIVE,\r
+              key   = QUESTION_ID_REFRESH_MANAGER;\r
+      endif;\r
+\r
+  endform;\r
+endformset;\r
diff --git a/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerVfr.h b/MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerVfr.h
new file mode 100644 (file)
index 0000000..61ca04a
--- /dev/null
@@ -0,0 +1,32 @@
+/** @file\r
+  Definition shared by VFR file and C file.\r
+\r
+Copyright (c) 2013 - 2015, 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
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _DRIVER_HEALTH_VFR_H_\r
+#define _DRIVER_HEALTH_VFR_H_\r
+#include <Guid/HiiPlatformSetupFormset.h>\r
+\r
+#define DRIVER_HEALTH_MANAGER_FORMSET_GUID         { 0xcfb3b000, 0x0b63, 0x444b, { 0xb1, 0xd1, 0x12, 0xd5, 0xd9, 0x5d, 0xc4, 0xfc } } \r
+#define DRIVER_HEALTH_CONFIGURE_FORMSET_GUID       { 0x4296d9f4, 0xf6fc, 0x4dde, { 0x86, 0x85, 0x8c, 0xe2, 0xd7, 0x9d, 0x90, 0xf0 } } \r
+\r
+#define LABEL_BEGIN                        0x2000\r
+#define LABEL_END                          0x2001\r
+\r
+#define DRIVER_HEALTH_FORM_ID              0x1001\r
+\r
+#define QUESTION_ID_REFRESH_MANAGER        0x0001\r
+#define QUESTION_ID_REFRESH_CONFIGURE      0x0002\r
+\r
+#define QUESTION_ID_DRIVER_HEALTH_BASE     0x0003\r
+\r
+#endif\r