blob: 425109a54dd29e84fcb939329f10a5095445f4ee [file] [log] [blame]
Vishal Bhoj82c80712015-12-15 21:13:33 +05301/*++ @file
2 Reset Architectural Protocol implementation.
3
4Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution. The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13--*/
14
15#include <PiDxe.h>
16
17#include <Protocol/Reset.h>
18
19#include <Guid/AcpiDescription.h>
20
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>
28
29///
30/// Handle for the Reset Architectural Protocol
31///
32EFI_HANDLE mResetHandle = NULL;
33
34///
35/// Copy of ACPI Description HOB in runtime memory
36///
37EFI_ACPI_DESCRIPTION mAcpiDescription;
38
39/**
40 Reset the system.
41
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
46
47**/
48VOID
49EFIAPI
50EfiAcpiResetSystem (
51 IN EFI_RESET_TYPE ResetType,
52 IN EFI_STATUS ResetStatus,
53 IN UINTN DataSize,
54 IN VOID *ResetData OPTIONAL
55 )
56{
57 UINT8 Dev;
58 UINT8 Func;
59 UINT8 Register;
60
61 switch (ResetType) {
62 case EfiResetShutdown:
63 //
64 // 1. Write SLP_TYPa
65 //
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)));
70 break;
71 case EFI_ACPI_3_0_SYSTEM_MEMORY:
72 MmioAndThenOr16 ((UINTN)mAcpiDescription.PM1a_CNT_BLK.Address, 0xc3ff, (UINT16)(0x2000 | (mAcpiDescription.SLP_TYPa << 10)));
73 break;
74 }
75 }
76
77 //
78 // 2. Write SLP_TYPb
79 //
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)));
84 break;
85 case EFI_ACPI_3_0_SYSTEM_MEMORY:
86 MmioAndThenOr16 ((UINTN)mAcpiDescription.PM1b_CNT_BLK.Address, 0xc3ff, (UINT16)(0x2000 | (mAcpiDescription.SLP_TYPb << 10)));
87 break;
88 }
89 }
90 //
91 // If Shutdown fails, then let fall through to reset
92 //
93 case EfiResetWarm:
94 case EfiResetCold:
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))) {
99 //
100 // Use ACPI System Reset
101 //
102 switch (mAcpiDescription.RESET_REG.AddressSpaceId) {
103 case EFI_ACPI_3_0_SYSTEM_IO:
104 //
105 // Send reset request through I/O port register
106 //
107 IoWrite8 ((UINTN)mAcpiDescription.RESET_REG.Address, mAcpiDescription.RESET_VALUE);
108 //
109 // Halt
110 //
111 CpuDeadLoop ();
112 case EFI_ACPI_3_0_SYSTEM_MEMORY:
113 //
114 // Send reset request through MMIO register
115 //
116 MmioWrite8 ((UINTN)mAcpiDescription.RESET_REG.Address, mAcpiDescription.RESET_VALUE);
117 //
118 // Halt
119 //
120 CpuDeadLoop ();
121 case EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE:
122 //
123 // Send reset request through PCI register
124 //
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);
129 //
130 // Halt
131 //
132 CpuDeadLoop ();
133 }
134 }
135
136 //
137 // If system comes here, means ACPI reset is not supported, so do Legacy System Reset, assume 8042 available
138 //
139 IoWrite8 (0x64, 0xfe);
140 CpuDeadLoop ();
141
142 default:
143 break;
144 }
145
146 //
147 // Given we should have reset getting here would be bad
148 //
149 ASSERT (FALSE);
150 CpuDeadLoop();
151}
152
153/**
154 Initialize the state information for the Reset Architectural Protocol.
155
156 @param[in] ImageHandle Image handle of the loaded driver
157 @param[in] SystemTable Pointer to the System Table
158
159 @retval EFI_SUCCESS Thread can be successfully created
160 @retval EFI_UNSUPPORTED Cannot find the info to reset system
161
162**/
163EFI_STATUS
164EFIAPI
165InitializeReset (
166 IN EFI_HANDLE ImageHandle,
167 IN EFI_SYSTEM_TABLE *SystemTable
168 )
169{
170 EFI_STATUS Status;
171 EFI_HOB_GUID_TYPE *HobAcpiDescription;
172
173 //
174 // Make sure the Reset Architectural Protocol is not already installed in the system
175 //
176 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid);
177
178 //
179 // Get ACPI Description HOB
180 //
181 HobAcpiDescription = GetFirstGuidHob (&gEfiAcpiDescriptionGuid);
182 if (HobAcpiDescription == NULL) {
183 return EFI_UNSUPPORTED;
184 }
185
186 //
187 // Copy it to Runtime Memory
188 //
189 ASSERT (sizeof (EFI_ACPI_DESCRIPTION) == GET_GUID_HOB_DATA_SIZE (HobAcpiDescription));
190 CopyMem (&mAcpiDescription, GET_GUID_HOB_DATA (HobAcpiDescription), sizeof (EFI_ACPI_DESCRIPTION));
191
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)));
195
196 //
197 // Hook the runtime service table
198 //
199 SystemTable->RuntimeServices->ResetSystem = EfiAcpiResetSystem;
200
201 //
202 // Install the Reset Architectural Protocol onto a new handle
203 //
204 Status = gBS->InstallMultipleProtocolInterfaces (
205 &mResetHandle,
206 &gEfiResetArchProtocolGuid, NULL,
207 NULL
208 );
209 ASSERT_EFI_ERROR (Status);
210
211 return Status;
212}