\r
--*/\r
\r
-#include "Reset.h"\r
+#include <PiDxe.h>\r
\r
-/**\r
- Use ACPI method to reset the sytem. If fail, use legacy 8042 method to reset the system\r
-\r
- @param[in] AcpiDescription Global variable to record reset info\r
-\r
-**/\r
-VOID\r
-SystemReset (\r
- IN EFI_ACPI_DESCRIPTION *AcpiDescription\r
- )\r
-{\r
- UINT8 Dev;\r
- UINT8 Func;\r
- UINT8 Register;\r
+#include <Protocol/Reset.h>\r
\r
- if ((AcpiDescription->RESET_REG.Address != 0) &&\r
- ((AcpiDescription->RESET_REG.AddressSpaceId == EFI_ACPI_3_0_SYSTEM_IO) ||\r
- (AcpiDescription->RESET_REG.AddressSpaceId == EFI_ACPI_3_0_SYSTEM_MEMORY) ||\r
- (AcpiDescription->RESET_REG.AddressSpaceId == EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE))) {\r
- //\r
- // Use ACPI System Reset\r
- //\r
- switch (AcpiDescription->RESET_REG.AddressSpaceId) {\r
- case EFI_ACPI_3_0_SYSTEM_IO:\r
- IoWrite8 ((UINTN) AcpiDescription->RESET_REG.Address, AcpiDescription->RESET_VALUE);\r
- break;\r
- case EFI_ACPI_3_0_SYSTEM_MEMORY:\r
- MmioWrite8 ((UINTN) AcpiDescription->RESET_REG.Address, AcpiDescription->RESET_VALUE);\r
- break;\r
- case EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE:\r
- Register = (UINT8) AcpiDescription->RESET_REG.Address;\r
- Func = (UINT8) (RShiftU64 (AcpiDescription->RESET_REG.Address, 16) & 0x7);\r
- Dev = (UINT8) (RShiftU64 (AcpiDescription->RESET_REG.Address, 32) & 0x1F);\r
- PciWrite8 (PCI_LIB_ADDRESS (0, Dev, Func, Register), AcpiDescription->RESET_VALUE);\r
- break;\r
- }\r
- }\r
+#include <Guid/AcpiDescription.h>\r
\r
- //\r
- // If system comes here, means ACPI reset fail, do Legacy System Reset, assume 8042 available\r
- //\r
- Register = 0xfe;\r
- IoWrite8 (0x64, Register);\r
+#include <Library/BaseLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/PciLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
\r
- //\r
- // System should reset now\r
- //\r
+///\r
+/// Handle for the Reset Architectural Protocol\r
+///\r
+EFI_HANDLE mResetHandle = NULL;\r
\r
- return ;\r
-}\r
-\r
-/**\r
- Use ACPI method to shutdown the sytem\r
-\r
- @param[in] AcpiDescription Global variable to record reset info\r
-\r
- @retval EFI_UNSUPPORTED Shutdown fails\r
-\r
-**/\r
-EFI_STATUS\r
-SystemShutdown (\r
- IN EFI_ACPI_DESCRIPTION *AcpiDescription\r
- )\r
-{\r
- UINT16 Value;\r
-\r
- //\r
- // 1. Write SLP_TYPa\r
- //\r
- if ((AcpiDescription->PM1a_CNT_BLK.Address != 0) && (AcpiDescription->SLP_TYPa != 0)) {\r
- switch (AcpiDescription->PM1a_CNT_BLK.AddressSpaceId) {\r
- case EFI_ACPI_3_0_SYSTEM_IO:\r
- Value = IoRead16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address);\r
- Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPa << 10);\r
- IoWrite16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address, Value);\r
- break;\r
- case EFI_ACPI_3_0_SYSTEM_MEMORY:\r
- Value = MmioRead16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address);\r
- Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPa << 10);\r
- MmioWrite16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address, Value);\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // 2. Write SLP_TYPb\r
- //\r
- if ((AcpiDescription->PM1b_CNT_BLK.Address != 0) && (AcpiDescription->SLP_TYPb != 0)) {\r
- switch (AcpiDescription->PM1b_CNT_BLK.AddressSpaceId) {\r
- case EFI_ACPI_3_0_SYSTEM_IO:\r
- Value = IoRead16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address);\r
- Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPb << 10);\r
- IoWrite16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address, Value);\r
- break;\r
- case EFI_ACPI_3_0_SYSTEM_MEMORY:\r
- Value = MmioRead16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address);\r
- Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPb << 10);\r
- MmioWrite16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address, Value);\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Done, if code runs here, mean not shutdown correctly\r
- //\r
- return EFI_UNSUPPORTED;\r
-}\r
+///\r
+/// Copy of ACPI Description HOB in runtime memory\r
+///\r
+EFI_ACPI_DESCRIPTION mAcpiDescription;\r
\r
/**\r
Reset the system.\r
@param[in] ResetStatus Possible cause of reset\r
@param[in] DataSize Size of ResetData in bytes\r
@param[in] ResetData Optional Unicode string\r
- @param[in] AcpiDescription Global variable to record reset info\r
\r
**/\r
VOID\r
EFIAPI\r
-AcpiResetSystem (\r
+EfiAcpiResetSystem (\r
IN EFI_RESET_TYPE ResetType,\r
IN EFI_STATUS ResetStatus,\r
IN UINTN DataSize,\r
- IN CHAR16 *ResetData, OPTIONAL\r
- IN EFI_ACPI_DESCRIPTION *AcpiDescription\r
+ IN VOID *ResetData OPTIONAL\r
)\r
{\r
- EFI_STATUS Status;\r
-\r
+ UINT8 Dev;\r
+ UINT8 Func;\r
+ UINT8 Register;\r
+ \r
switch (ResetType) {\r
+ case EfiResetShutdown:\r
+ //\r
+ // 1. Write SLP_TYPa\r
+ //\r
+ if ((mAcpiDescription.PM1a_CNT_BLK.Address != 0) && (mAcpiDescription.SLP_TYPa != 0)) {\r
+ switch (mAcpiDescription.PM1a_CNT_BLK.AddressSpaceId) {\r
+ case EFI_ACPI_3_0_SYSTEM_IO:\r
+ IoAndThenOr16 ((UINTN)mAcpiDescription.PM1a_CNT_BLK.Address, 0xc3ff, (UINT16)(0x2000 | (mAcpiDescription.SLP_TYPa << 10)));\r
+ break;\r
+ case EFI_ACPI_3_0_SYSTEM_MEMORY:\r
+ MmioAndThenOr16 ((UINTN)mAcpiDescription.PM1a_CNT_BLK.Address, 0xc3ff, (UINT16)(0x2000 | (mAcpiDescription.SLP_TYPa << 10)));\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // 2. Write SLP_TYPb\r
+ //\r
+ if ((mAcpiDescription.PM1b_CNT_BLK.Address != 0) && (mAcpiDescription.SLP_TYPb != 0)) {\r
+ switch (mAcpiDescription.PM1b_CNT_BLK.AddressSpaceId) {\r
+ case EFI_ACPI_3_0_SYSTEM_IO:\r
+ IoAndThenOr16 ((UINTN)mAcpiDescription.PM1b_CNT_BLK.Address, 0xc3ff, (UINT16)(0x2000 | (mAcpiDescription.SLP_TYPb << 10)));\r
+ break;\r
+ case EFI_ACPI_3_0_SYSTEM_MEMORY:\r
+ MmioAndThenOr16 ((UINTN)mAcpiDescription.PM1b_CNT_BLK.Address, 0xc3ff, (UINT16)(0x2000 | (mAcpiDescription.SLP_TYPb << 10)));\r
+ break;\r
+ }\r
+ }\r
+ //\r
+ // If Shutdown fails, then let fall through to reset \r
+ //\r
case EfiResetWarm:\r
case EfiResetCold:\r
- SystemReset (AcpiDescription);\r
- break;\r
-\r
- case EfiResetShutdown:\r
- Status = SystemShutdown (AcpiDescription);\r
- if (EFI_ERROR (Status)) {\r
- SystemReset (AcpiDescription);\r
+ if ((mAcpiDescription.RESET_REG.Address != 0) &&\r
+ ((mAcpiDescription.RESET_REG.AddressSpaceId == EFI_ACPI_3_0_SYSTEM_IO) ||\r
+ (mAcpiDescription.RESET_REG.AddressSpaceId == EFI_ACPI_3_0_SYSTEM_MEMORY) ||\r
+ (mAcpiDescription.RESET_REG.AddressSpaceId == EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE))) {\r
+ //\r
+ // Use ACPI System Reset\r
+ //\r
+ switch (mAcpiDescription.RESET_REG.AddressSpaceId) {\r
+ case EFI_ACPI_3_0_SYSTEM_IO:\r
+ //\r
+ // Send reset request through I/O port register\r
+ //\r
+ IoWrite8 ((UINTN)mAcpiDescription.RESET_REG.Address, mAcpiDescription.RESET_VALUE);\r
+ //\r
+ // Halt \r
+ //\r
+ CpuDeadLoop ();\r
+ case EFI_ACPI_3_0_SYSTEM_MEMORY:\r
+ //\r
+ // Send reset request through MMIO register\r
+ //\r
+ MmioWrite8 ((UINTN)mAcpiDescription.RESET_REG.Address, mAcpiDescription.RESET_VALUE);\r
+ //\r
+ // Halt \r
+ //\r
+ CpuDeadLoop ();\r
+ case EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE:\r
+ //\r
+ // Send reset request through PCI register\r
+ //\r
+ Register = (UINT8)mAcpiDescription.RESET_REG.Address;\r
+ Func = (UINT8) (RShiftU64 (mAcpiDescription.RESET_REG.Address, 16) & 0x7);\r
+ Dev = (UINT8) (RShiftU64 (mAcpiDescription.RESET_REG.Address, 32) & 0x1F);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, Dev, Func, Register), mAcpiDescription.RESET_VALUE);\r
+ //\r
+ // Halt \r
+ //\r
+ CpuDeadLoop ();\r
+ }\r
}\r
- break;\r
\r
- default:\r
- return ;\r
+ //\r
+ // If system comes here, means ACPI reset is not supported, so do Legacy System Reset, assume 8042 available\r
+ //\r
+ IoWrite8 (0x64, 0xfe);\r
+ CpuDeadLoop ();\r
}\r
\r
//\r
// Given we should have reset getting here would be bad\r
//\r
ASSERT (FALSE);\r
+ CpuDeadLoop();\r
}\r
\r
-BOOLEAN\r
-GetAcpiDescription (\r
- IN EFI_ACPI_DESCRIPTION *AcpiDescription\r
+/**\r
+ Initialize the state information for the Reset Architectural Protocol.\r
+\r
+ @param[in] ImageHandle Image handle of the loaded driver\r
+ @param[in] SystemTable Pointer to the System Table\r
+\r
+ @retval EFI_SUCCESS Thread can be successfully created\r
+ @retval EFI_UNSUPPORTED Cannot find the info to reset system\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeReset (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
- EFI_HOB_GUID_TYPE *HobAcpiDescription;\r
+ EFI_STATUS Status;\r
+ EFI_HOB_GUID_TYPE *HobAcpiDescription;\r
+\r
//\r
- // Get AcpiDescription Hob\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
+ // Get ACPI Description HOB\r
//\r
HobAcpiDescription = GetFirstGuidHob (&gEfiAcpiDescriptionGuid);\r
if (HobAcpiDescription == NULL) {\r
- return FALSE;\r
+ return EFI_UNSUPPORTED;\r
}\r
\r
//\r
// Copy it to Runtime Memory\r
//\r
ASSERT (sizeof (EFI_ACPI_DESCRIPTION) == GET_GUID_HOB_DATA_SIZE (HobAcpiDescription));\r
- CopyMem (AcpiDescription, GET_GUID_HOB_DATA (HobAcpiDescription), sizeof (EFI_ACPI_DESCRIPTION));\r
+ CopyMem (&mAcpiDescription, GET_GUID_HOB_DATA (HobAcpiDescription), sizeof (EFI_ACPI_DESCRIPTION));\r
+\r
+ DEBUG ((DEBUG_INFO, "ACPI Reset Base - %lx\n", mAcpiDescription.RESET_REG.Address));\r
+ DEBUG ((DEBUG_INFO, "ACPI Reset Value - %02x\n", (UINTN)mAcpiDescription.RESET_VALUE));\r
+ DEBUG ((DEBUG_INFO, "IAPC support - %x\n", (UINTN)(mAcpiDescription.IAPC_BOOT_ARCH)));\r
+ \r
+ //\r
+ // Hook the runtime service table\r
+ //\r
+ SystemTable->RuntimeServices->ResetSystem = EfiAcpiResetSystem;\r
+\r
+ //\r
+ // Install the Reset Architectural Protocol onto a new handle\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mResetHandle,\r
+ &gEfiResetArchProtocolGuid, NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- DEBUG ((EFI_D_ERROR, "ACPI Reset Base - %lx\n", AcpiDescription->RESET_REG.Address));\r
- DEBUG ((EFI_D_ERROR, "ACPI Reset Value - %02x\n", (UINTN)AcpiDescription->RESET_VALUE));\r
- DEBUG ((EFI_D_ERROR, "IAPC support - %x\n", (UINTN)(AcpiDescription->IAPC_BOOT_ARCH)));\r
- return TRUE;\r
+ return Status;\r
}\r