2 Reset Architectural Protocol implementation.
4 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Protocol/Reset.h>
19 #include <Guid/AcpiDescription.h>
21 #include <Library/BaseLib.h>
22 #include <Library/IoLib.h>
23 #include <Library/PciLib.h>
24 #include <Library/HobLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/UefiBootServicesTableLib.h>
30 /// Handle for the Reset Architectural Protocol
32 EFI_HANDLE mResetHandle
= NULL
;
35 /// Copy of ACPI Description HOB in runtime memory
37 EFI_ACPI_DESCRIPTION mAcpiDescription
;
42 @param[in] ResetType Warm or cold
43 @param[in] ResetStatus Possible cause of reset
44 @param[in] DataSize Size of ResetData in bytes
45 @param[in] ResetData Optional Unicode string
51 IN EFI_RESET_TYPE ResetType
,
52 IN EFI_STATUS ResetStatus
,
54 IN VOID
*ResetData OPTIONAL
62 case EfiResetShutdown
:
66 if ((mAcpiDescription
.PM1a_CNT_BLK
.Address
!= 0) && (mAcpiDescription
.SLP_TYPa
!= 0)) {
67 switch (mAcpiDescription
.PM1a_CNT_BLK
.AddressSpaceId
) {
68 case EFI_ACPI_3_0_SYSTEM_IO
:
69 IoAndThenOr16 ((UINTN
)mAcpiDescription
.PM1a_CNT_BLK
.Address
, 0xc3ff, (UINT16
)(0x2000 | (mAcpiDescription
.SLP_TYPa
<< 10)));
71 case EFI_ACPI_3_0_SYSTEM_MEMORY
:
72 MmioAndThenOr16 ((UINTN
)mAcpiDescription
.PM1a_CNT_BLK
.Address
, 0xc3ff, (UINT16
)(0x2000 | (mAcpiDescription
.SLP_TYPa
<< 10)));
80 if ((mAcpiDescription
.PM1b_CNT_BLK
.Address
!= 0) && (mAcpiDescription
.SLP_TYPb
!= 0)) {
81 switch (mAcpiDescription
.PM1b_CNT_BLK
.AddressSpaceId
) {
82 case EFI_ACPI_3_0_SYSTEM_IO
:
83 IoAndThenOr16 ((UINTN
)mAcpiDescription
.PM1b_CNT_BLK
.Address
, 0xc3ff, (UINT16
)(0x2000 | (mAcpiDescription
.SLP_TYPb
<< 10)));
85 case EFI_ACPI_3_0_SYSTEM_MEMORY
:
86 MmioAndThenOr16 ((UINTN
)mAcpiDescription
.PM1b_CNT_BLK
.Address
, 0xc3ff, (UINT16
)(0x2000 | (mAcpiDescription
.SLP_TYPb
<< 10)));
91 // If Shutdown fails, then let fall through to reset
95 if ((mAcpiDescription
.RESET_REG
.Address
!= 0) &&
96 ((mAcpiDescription
.RESET_REG
.AddressSpaceId
== EFI_ACPI_3_0_SYSTEM_IO
) ||
97 (mAcpiDescription
.RESET_REG
.AddressSpaceId
== EFI_ACPI_3_0_SYSTEM_MEMORY
) ||
98 (mAcpiDescription
.RESET_REG
.AddressSpaceId
== EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE
))) {
100 // Use ACPI System Reset
102 switch (mAcpiDescription
.RESET_REG
.AddressSpaceId
) {
103 case EFI_ACPI_3_0_SYSTEM_IO
:
105 // Send reset request through I/O port register
107 IoWrite8 ((UINTN
)mAcpiDescription
.RESET_REG
.Address
, mAcpiDescription
.RESET_VALUE
);
112 case EFI_ACPI_3_0_SYSTEM_MEMORY
:
114 // Send reset request through MMIO register
116 MmioWrite8 ((UINTN
)mAcpiDescription
.RESET_REG
.Address
, mAcpiDescription
.RESET_VALUE
);
121 case EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE
:
123 // Send reset request through PCI register
125 Register
= (UINT8
)mAcpiDescription
.RESET_REG
.Address
;
126 Func
= (UINT8
) (RShiftU64 (mAcpiDescription
.RESET_REG
.Address
, 16) & 0x7);
127 Dev
= (UINT8
) (RShiftU64 (mAcpiDescription
.RESET_REG
.Address
, 32) & 0x1F);
128 PciWrite8 (PCI_LIB_ADDRESS (0, Dev
, Func
, Register
), mAcpiDescription
.RESET_VALUE
);
137 // If system comes here, means ACPI reset is not supported, so do Legacy System Reset, assume 8042 available
139 IoWrite8 (0x64, 0xfe);
147 // Given we should have reset getting here would be bad
154 Initialize the state information for the Reset Architectural Protocol.
156 @param[in] ImageHandle Image handle of the loaded driver
157 @param[in] SystemTable Pointer to the System Table
159 @retval EFI_SUCCESS Thread can be successfully created
160 @retval EFI_UNSUPPORTED Cannot find the info to reset system
166 IN EFI_HANDLE ImageHandle
,
167 IN EFI_SYSTEM_TABLE
*SystemTable
171 EFI_HOB_GUID_TYPE
*HobAcpiDescription
;
174 // Make sure the Reset Architectural Protocol is not already installed in the system
176 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gEfiResetArchProtocolGuid
);
179 // Get ACPI Description HOB
181 HobAcpiDescription
= GetFirstGuidHob (&gEfiAcpiDescriptionGuid
);
182 if (HobAcpiDescription
== NULL
) {
183 return EFI_UNSUPPORTED
;
187 // Copy it to Runtime Memory
189 ASSERT (sizeof (EFI_ACPI_DESCRIPTION
) == GET_GUID_HOB_DATA_SIZE (HobAcpiDescription
));
190 CopyMem (&mAcpiDescription
, GET_GUID_HOB_DATA (HobAcpiDescription
), sizeof (EFI_ACPI_DESCRIPTION
));
192 DEBUG ((DEBUG_INFO
, "ACPI Reset Base - %lx\n", mAcpiDescription
.RESET_REG
.Address
));
193 DEBUG ((DEBUG_INFO
, "ACPI Reset Value - %02x\n", (UINTN
)mAcpiDescription
.RESET_VALUE
));
194 DEBUG ((DEBUG_INFO
, "IAPC support - %x\n", (UINTN
)(mAcpiDescription
.IAPC_BOOT_ARCH
)));
197 // Hook the runtime service table
199 SystemTable
->RuntimeServices
->ResetSystem
= EfiAcpiResetSystem
;
202 // Install the Reset Architectural Protocol onto a new handle
204 Status
= gBS
->InstallMultipleProtocolInterfaces (
206 &gEfiResetArchProtocolGuid
, NULL
,
209 ASSERT_EFI_ERROR (Status
);