summaryrefslogtreecommitdiff
path: root/DuetPkg/AcpiResetDxe
diff options
context:
space:
mode:
authorniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>2010-02-21 09:30:01 +0000
committerniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>2010-02-21 09:30:01 +0000
commit0e047a2a83d3e4c04f73d26f3978a4efde0b2bc4 (patch)
treeb36827e00942f134465e3defa8f747f93ecefd73 /DuetPkg/AcpiResetDxe
parent450ec0ed87d34dd325b66515dd7530fc59ac6267 (diff)
Port AcpiResetDxe from EDK to EDKII to enable reset function on DUET above legacy free platform.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10034 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'DuetPkg/AcpiResetDxe')
-rw-r--r--DuetPkg/AcpiResetDxe/Reset.c194
-rw-r--r--DuetPkg/AcpiResetDxe/Reset.h74
-rw-r--r--DuetPkg/AcpiResetDxe/Reset.inf54
-rw-r--r--DuetPkg/AcpiResetDxe/ResetEntry.c88
4 files changed, 410 insertions, 0 deletions
diff --git a/DuetPkg/AcpiResetDxe/Reset.c b/DuetPkg/AcpiResetDxe/Reset.c
new file mode 100644
index 000000000..fe2d0a8da
--- /dev/null
+++ b/DuetPkg/AcpiResetDxe/Reset.c
@@ -0,0 +1,194 @@
+/*++ @file
+ Reset Architectural Protocol implementation.
+
+Copyright (c) 2006 - 2010, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+--*/
+
+#include "Reset.h"
+
+/**
+ Use ACPI method to reset the sytem. If fail, use legacy 8042 method to reset the system
+
+ @param[in] AcpiDescription Global variable to record reset info
+
+**/
+VOID
+SystemReset (
+ IN EFI_ACPI_DESCRIPTION *AcpiDescription
+ )
+{
+ UINT8 Dev;
+ UINT8 Func;
+ UINT8 Register;
+
+ if ((AcpiDescription->RESET_REG.Address != 0) &&
+ ((AcpiDescription->RESET_REG.AddressSpaceId == EFI_ACPI_3_0_SYSTEM_IO) ||
+ (AcpiDescription->RESET_REG.AddressSpaceId == EFI_ACPI_3_0_SYSTEM_MEMORY) ||
+ (AcpiDescription->RESET_REG.AddressSpaceId == EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE))) {
+ //
+ // Use ACPI System Reset
+ //
+ switch (AcpiDescription->RESET_REG.AddressSpaceId) {
+ case EFI_ACPI_3_0_SYSTEM_IO:
+ IoWrite8 ((UINTN) AcpiDescription->RESET_REG.Address, AcpiDescription->RESET_VALUE);
+ break;
+ case EFI_ACPI_3_0_SYSTEM_MEMORY:
+ MmioWrite8 ((UINTN) AcpiDescription->RESET_REG.Address, AcpiDescription->RESET_VALUE);
+ break;
+ case EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE:
+ Register = (UINT8) AcpiDescription->RESET_REG.Address;
+ Func = (UINT8) (RShiftU64 (AcpiDescription->RESET_REG.Address, 16) & 0x7);
+ Dev = (UINT8) (RShiftU64 (AcpiDescription->RESET_REG.Address, 32) & 0x1F);
+ PciWrite8 (PCI_LIB_ADDRESS (0, Dev, Func, Register), AcpiDescription->RESET_VALUE);
+ break;
+ }
+ }
+
+ //
+ // If system comes here, means ACPI reset fail, do Legacy System Reset, assume 8042 available
+ //
+ Register = 0xfe;
+ IoWrite8 (0x64, Register);
+
+ //
+ // System should reset now
+ //
+
+ return ;
+}
+
+/**
+ Use ACPI method to shutdown the sytem
+
+ @param[in] AcpiDescription Global variable to record reset info
+
+ @retval EFI_UNSUPPORTED Shutdown fails
+
+**/
+EFI_STATUS
+SystemShutdown (
+ IN EFI_ACPI_DESCRIPTION *AcpiDescription
+ )
+{
+ UINT16 Value;
+
+ //
+ // 1. Write SLP_TYPa
+ //
+ if ((AcpiDescription->PM1a_CNT_BLK.Address != 0) && (AcpiDescription->SLP_TYPa != 0)) {
+ switch (AcpiDescription->PM1a_CNT_BLK.AddressSpaceId) {
+ case EFI_ACPI_3_0_SYSTEM_IO:
+ Value = IoRead16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address);
+ Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPa << 10);
+ IoWrite16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address, Value);
+ break;
+ case EFI_ACPI_3_0_SYSTEM_MEMORY:
+ Value = MmioRead16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address);
+ Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPa << 10);
+ MmioWrite16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address, Value);
+ break;
+ }
+ }
+
+ //
+ // 2. Write SLP_TYPb
+ //
+ if ((AcpiDescription->PM1b_CNT_BLK.Address != 0) && (AcpiDescription->SLP_TYPb != 0)) {
+ switch (AcpiDescription->PM1b_CNT_BLK.AddressSpaceId) {
+ case EFI_ACPI_3_0_SYSTEM_IO:
+ Value = IoRead16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address);
+ Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPb << 10);
+ IoWrite16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address, Value);
+ break;
+ case EFI_ACPI_3_0_SYSTEM_MEMORY:
+ Value = MmioRead16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address);
+ Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPb << 10);
+ MmioWrite16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address, Value);
+ break;
+ }
+ }
+
+ //
+ // Done, if code runs here, mean not shutdown correctly
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Reset the system.
+
+ @param[in] ResetType Warm or cold
+ @param[in] ResetStatus Possible cause of reset
+ @param[in] DataSize Size of ResetData in bytes
+ @param[in] ResetData Optional Unicode string
+ @param[in] AcpiDescription Global variable to record reset info
+
+**/
+VOID
+EFIAPI
+AcpiResetSystem (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN CHAR16 *ResetData, OPTIONAL
+ IN EFI_ACPI_DESCRIPTION *AcpiDescription
+ )
+{
+ EFI_STATUS Status;
+
+ switch (ResetType) {
+ case EfiResetWarm:
+ case EfiResetCold:
+ SystemReset (AcpiDescription);
+ break;
+
+ case EfiResetShutdown:
+ Status = SystemShutdown (AcpiDescription);
+ if (EFI_ERROR (Status)) {
+ SystemReset (AcpiDescription);
+ }
+ break;
+
+ default:
+ return ;
+ }
+
+ //
+ // Given we should have reset getting here would be bad
+ //
+ ASSERT (FALSE);
+}
+
+BOOLEAN
+GetAcpiDescription (
+ IN EFI_ACPI_DESCRIPTION *AcpiDescription
+ )
+{
+ EFI_HOB_GUID_TYPE *HobAcpiDescription;
+ //
+ // Get AcpiDescription Hob
+ //
+ HobAcpiDescription = GetFirstGuidHob (&gEfiAcpiDescriptionGuid);
+ if (HobAcpiDescription == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Copy it to Runtime Memory
+ //
+ ASSERT (sizeof (EFI_ACPI_DESCRIPTION) == GET_GUID_HOB_DATA_SIZE (HobAcpiDescription));
+ CopyMem (AcpiDescription, GET_GUID_HOB_DATA (HobAcpiDescription), sizeof (EFI_ACPI_DESCRIPTION));
+
+ DEBUG ((EFI_D_ERROR, "ACPI Reset Base - %lx\n", AcpiDescription->RESET_REG.Address));
+ DEBUG ((EFI_D_ERROR, "ACPI Reset Value - %02x\n", (UINTN)AcpiDescription->RESET_VALUE));
+ DEBUG ((EFI_D_ERROR, "IAPC support - %x\n", (UINTN)(AcpiDescription->IAPC_BOOT_ARCH)));
+ return TRUE;
+}
diff --git a/DuetPkg/AcpiResetDxe/Reset.h b/DuetPkg/AcpiResetDxe/Reset.h
new file mode 100644
index 000000000..448c103b2
--- /dev/null
+++ b/DuetPkg/AcpiResetDxe/Reset.h
@@ -0,0 +1,74 @@
+/*++ @file
+ Some definitions for reset.
+
+Copyright (c) 2006 - 2010, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+--*/
+
+#ifndef _ACPI_RESET_H
+#define _ACPI_RESET_H
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/Reset.h>
+#include <Guid/AcpiDescription.h>
+
+/**
+ Initialize the state information for the Reset Architectural Protocol.
+
+ @param[in] ImageHandle Image handle of the loaded driver
+ @param[in] SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Thread can be successfully created
+ @retval EFI_UNSUPPORTED Cannot find the info to reset system
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeReset (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+;
+
+/**
+ Reset the system.
+
+ @param[in] ResetType Warm or cold
+ @param[in] ResetStatus Possible cause of reset
+ @param[in] DataSize Size of ResetData in bytes
+ @param[in] ResetData Optional Unicode string
+
+**/
+VOID
+EFIAPI
+AcpiResetSystem (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN CHAR16 *ResetData, OPTIONAL
+ IN EFI_ACPI_DESCRIPTION *AcpiDescription
+ )
+;
+
+BOOLEAN
+GetAcpiDescription (
+ IN EFI_ACPI_DESCRIPTION *AcpiDescription
+ );
+
+#endif
diff --git a/DuetPkg/AcpiResetDxe/Reset.inf b/DuetPkg/AcpiResetDxe/Reset.inf
new file mode 100644
index 000000000..3af6becbe
--- /dev/null
+++ b/DuetPkg/AcpiResetDxe/Reset.inf
@@ -0,0 +1,54 @@
+#/** @file
+# Component description file for AcpiResetDxe module.
+#
+# Copyright (c) 2006 - 2010, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#--*/
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AcpiReset
+ FILE_GUID = 6F0198AA-1F1D-426D-AE3E-39AB633FCC28
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeReset
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DuetPkg/DuetPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ IoLib
+ PciLib
+ HobLib
+ BaseLib
+ BaseMemoryLib
+
+[Sources]
+ Reset.c
+ Reset.h
+ ResetEntry.c
+
+[Protocols]
+ gEfiResetArchProtocolGuid
+
+[Guids]
+ gEfiAcpiDescriptionGuid
+
+[Depex]
+ TRUE
+
+[BuildOptions]
+ MSFT:*_*_IA32_CC_FLAGS = /Od
+
+
diff --git a/DuetPkg/AcpiResetDxe/ResetEntry.c b/DuetPkg/AcpiResetDxe/ResetEntry.c
new file mode 100644
index 000000000..3da08a10d
--- /dev/null
+++ b/DuetPkg/AcpiResetDxe/ResetEntry.c
@@ -0,0 +1,88 @@
+/*++ @file
+ Entrypoint of AcpiResetDxe driver.
+
+Copyright (c) 2010, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+--*/
+
+#include "Reset.h"
+
+EFI_ACPI_DESCRIPTION mAcpiDescription;
+
+/**
+ Reset the system.
+
+ @param[in] ResetType Warm or cold
+ @param[in] ResetStatus Possible cause of reset
+ @param[in] DataSize Size of ResetData in bytes
+ @param[in] ResetData Optional Unicode string
+
+**/
+VOID
+EFIAPI
+EfiAcpiResetSystem (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN CHAR16 *ResetData OPTIONAL
+ )
+{
+ AcpiResetSystem (ResetType, ResetStatus, DataSize, ResetData, &mAcpiDescription);
+}
+
+/**
+ Initialize the state information for the Reset Architectural Protocol.
+
+ @param[in] ImageHandle Image handle of the loaded driver
+ @param[in] SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Thread can be successfully created
+ @retval EFI_UNSUPPORTED Cannot find the info to reset system
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeReset (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ //
+ // Initialize AcpiDescription
+ //
+ if (!GetAcpiDescription (&mAcpiDescription)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure the Reset Architectural Protocol is not already installed in the system
+ //
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid);
+
+ //
+ // Hook the runtime service table
+ //
+ SystemTable->RuntimeServices->ResetSystem = EfiAcpiResetSystem;
+
+ //
+ // Now install the Reset RT AP on a new handle
+ //
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiResetArchProtocolGuid,
+ NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}