+/** @file\r
+ Reset Architectural Protocol implementation\r
+\r
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+\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 "ResetSystem.h"\r
+\r
+//\r
+// The handle onto which the Reset Architectural Protocol is installed\r
+//\r
+EFI_HANDLE mResetHandle = NULL;\r
+\r
+/**\r
+ The driver's entry point.\r
+\r
+ It initializes the Reset Architectural Protocol.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+ \r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval other Cannot install ResetArch protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeResetSystem (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Make sure the Reset Architectural Protocol is not already installed in the system\r
+ //\r
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid);\r
+\r
+ //\r
+ // Hook the runtime service table\r
+ //\r
+ gRT->ResetSystem = ResetSystem;\r
+\r
+ //\r
+ // Now install the Reset RT AP on a new handle\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mResetHandle,\r
+ &gEfiResetArchProtocolGuid,\r
+ NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Reset system for capsule update.\r
+\r
+ @param[in] CapsuleDataPtr Pointer to the capsule block descriptors.\r
+ \r
+**/\r
+VOID\r
+CapsuleReset (\r
+ IN UINTN CapsuleDataPtr\r
+ )\r
+{\r
+ //\r
+ // This implementation assumes that we're using a variable\r
+ // to indicate capsule updates.\r
+ //\r
+ gRT->SetVariable (\r
+ EFI_CAPSULE_VARIABLE_NAME,\r
+ &gEfiCapsuleVendorGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+ sizeof (UINTN),\r
+ (VOID *) &CapsuleDataPtr\r
+ );\r
+\r
+ EnterS3WithImmediateWake ();\r
+\r
+ //\r
+ // Should not return\r
+ //\r
+ CpuDeadLoop ();\r
+}\r
+\r
+/**\r
+ Put the system into S3 power state. \r
+**/\r
+VOID\r
+DoS3 (\r
+ VOID\r
+ )\r
+{\r
+ EnterS3WithImmediateWake ();\r
+\r
+ //\r
+ // Should not return\r
+ //\r
+ CpuDeadLoop ();\r
+}\r
+\r
+/**\r
+ Resets the entire platform.\r
+\r
+ @param[in] ResetType The type of reset to perform.\r
+ @param[in] ResetStatus The status code for the reset.\r
+ @param[in] DataSize The size, in bytes, of WatchdogData.\r
+ @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or\r
+ EfiResetShutdown the data buffer starts with a Null-terminated\r
+ string, optionally followed by additional binary data.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ResetSystem (\r
+ IN EFI_RESET_TYPE ResetType,\r
+ IN EFI_STATUS ResetStatus,\r
+ IN UINTN DataSize,\r
+ IN VOID *ResetData OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Size;\r
+ UINTN CapsuleDataPtr;\r
+\r
+ switch (ResetType) {\r
+ case EfiResetWarm:\r
+\r
+ //\r
+ //Check if there are pending capsules to process\r
+ //\r
+ Size = sizeof (CapsuleDataPtr);\r
+ Status = EfiGetVariable (\r
+ EFI_CAPSULE_VARIABLE_NAME,\r
+ &gEfiCapsuleVendorGuid,\r
+ NULL,\r
+ &Size,\r
+ (VOID *) &CapsuleDataPtr\r
+ );\r
+\r
+ if (Status == EFI_SUCCESS) {\r
+ //\r
+ //Process capsules across a system reset.\r
+ //\r
+ DoS3();\r
+ }\r
+\r
+ ResetWarm ();\r
+\r
+ break;\r
+\r
+ case EfiResetCold:\r
+ ResetCold ();\r
+ break;\r
+\r
+ case EfiResetShutdown:\r
+ ResetShutdown ();\r
+ return ;\r
+\r
+ default:\r
+ return ;\r
+ }\r
+\r
+ //\r
+ // Given we should have reset getting here would be bad\r
+ //\r
+ ASSERT (FALSE);\r
+}\r