]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/AcpiResetDxe/Reset.c
Port AcpiResetDxe from EDK to EDKII to enable reset function on DUET above legacy...
[mirror_edk2.git] / DuetPkg / AcpiResetDxe / Reset.c
CommitLineData
0e047a2a
RN
1/*++ @file\r
2 Reset Architectural Protocol implementation.\r
3\r
4Copyright (c) 2006 - 2010, Intel Corporation \r
5All rights reserved. This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php \r
9 \r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
13--*/\r
14\r
15#include "Reset.h"\r
16\r
17/**\r
18 Use ACPI method to reset the sytem. If fail, use legacy 8042 method to reset the system\r
19\r
20 @param[in] AcpiDescription Global variable to record reset info\r
21\r
22**/\r
23VOID\r
24SystemReset (\r
25 IN EFI_ACPI_DESCRIPTION *AcpiDescription\r
26 )\r
27{\r
28 UINT8 Dev;\r
29 UINT8 Func;\r
30 UINT8 Register;\r
31\r
32 if ((AcpiDescription->RESET_REG.Address != 0) &&\r
33 ((AcpiDescription->RESET_REG.AddressSpaceId == EFI_ACPI_3_0_SYSTEM_IO) ||\r
34 (AcpiDescription->RESET_REG.AddressSpaceId == EFI_ACPI_3_0_SYSTEM_MEMORY) ||\r
35 (AcpiDescription->RESET_REG.AddressSpaceId == EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE))) {\r
36 //\r
37 // Use ACPI System Reset\r
38 //\r
39 switch (AcpiDescription->RESET_REG.AddressSpaceId) {\r
40 case EFI_ACPI_3_0_SYSTEM_IO:\r
41 IoWrite8 ((UINTN) AcpiDescription->RESET_REG.Address, AcpiDescription->RESET_VALUE);\r
42 break;\r
43 case EFI_ACPI_3_0_SYSTEM_MEMORY:\r
44 MmioWrite8 ((UINTN) AcpiDescription->RESET_REG.Address, AcpiDescription->RESET_VALUE);\r
45 break;\r
46 case EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE:\r
47 Register = (UINT8) AcpiDescription->RESET_REG.Address;\r
48 Func = (UINT8) (RShiftU64 (AcpiDescription->RESET_REG.Address, 16) & 0x7);\r
49 Dev = (UINT8) (RShiftU64 (AcpiDescription->RESET_REG.Address, 32) & 0x1F);\r
50 PciWrite8 (PCI_LIB_ADDRESS (0, Dev, Func, Register), AcpiDescription->RESET_VALUE);\r
51 break;\r
52 }\r
53 }\r
54\r
55 //\r
56 // If system comes here, means ACPI reset fail, do Legacy System Reset, assume 8042 available\r
57 //\r
58 Register = 0xfe;\r
59 IoWrite8 (0x64, Register);\r
60\r
61 //\r
62 // System should reset now\r
63 //\r
64\r
65 return ;\r
66}\r
67\r
68/**\r
69 Use ACPI method to shutdown the sytem\r
70\r
71 @param[in] AcpiDescription Global variable to record reset info\r
72\r
73 @retval EFI_UNSUPPORTED Shutdown fails\r
74\r
75**/\r
76EFI_STATUS\r
77SystemShutdown (\r
78 IN EFI_ACPI_DESCRIPTION *AcpiDescription\r
79 )\r
80{\r
81 UINT16 Value;\r
82\r
83 //\r
84 // 1. Write SLP_TYPa\r
85 //\r
86 if ((AcpiDescription->PM1a_CNT_BLK.Address != 0) && (AcpiDescription->SLP_TYPa != 0)) {\r
87 switch (AcpiDescription->PM1a_CNT_BLK.AddressSpaceId) {\r
88 case EFI_ACPI_3_0_SYSTEM_IO:\r
89 Value = IoRead16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address);\r
90 Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPa << 10);\r
91 IoWrite16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address, Value);\r
92 break;\r
93 case EFI_ACPI_3_0_SYSTEM_MEMORY:\r
94 Value = MmioRead16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address);\r
95 Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPa << 10);\r
96 MmioWrite16 ((UINTN) AcpiDescription->PM1a_CNT_BLK.Address, Value);\r
97 break;\r
98 }\r
99 }\r
100\r
101 //\r
102 // 2. Write SLP_TYPb\r
103 //\r
104 if ((AcpiDescription->PM1b_CNT_BLK.Address != 0) && (AcpiDescription->SLP_TYPb != 0)) {\r
105 switch (AcpiDescription->PM1b_CNT_BLK.AddressSpaceId) {\r
106 case EFI_ACPI_3_0_SYSTEM_IO:\r
107 Value = IoRead16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address);\r
108 Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPb << 10);\r
109 IoWrite16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address, Value);\r
110 break;\r
111 case EFI_ACPI_3_0_SYSTEM_MEMORY:\r
112 Value = MmioRead16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address);\r
113 Value = (Value & 0xc3ff) | 0x2000 | (AcpiDescription->SLP_TYPb << 10);\r
114 MmioWrite16 ((UINTN) AcpiDescription->PM1b_CNT_BLK.Address, Value);\r
115 break;\r
116 }\r
117 }\r
118\r
119 //\r
120 // Done, if code runs here, mean not shutdown correctly\r
121 //\r
122 return EFI_UNSUPPORTED;\r
123}\r
124\r
125/**\r
126 Reset the system.\r
127\r
128 @param[in] ResetType Warm or cold\r
129 @param[in] ResetStatus Possible cause of reset\r
130 @param[in] DataSize Size of ResetData in bytes\r
131 @param[in] ResetData Optional Unicode string\r
132 @param[in] AcpiDescription Global variable to record reset info\r
133\r
134**/\r
135VOID\r
136EFIAPI\r
137AcpiResetSystem (\r
138 IN EFI_RESET_TYPE ResetType,\r
139 IN EFI_STATUS ResetStatus,\r
140 IN UINTN DataSize,\r
141 IN CHAR16 *ResetData, OPTIONAL\r
142 IN EFI_ACPI_DESCRIPTION *AcpiDescription\r
143 )\r
144{\r
145 EFI_STATUS Status;\r
146\r
147 switch (ResetType) {\r
148 case EfiResetWarm:\r
149 case EfiResetCold:\r
150 SystemReset (AcpiDescription);\r
151 break;\r
152\r
153 case EfiResetShutdown:\r
154 Status = SystemShutdown (AcpiDescription);\r
155 if (EFI_ERROR (Status)) {\r
156 SystemReset (AcpiDescription);\r
157 }\r
158 break;\r
159\r
160 default:\r
161 return ;\r
162 }\r
163\r
164 //\r
165 // Given we should have reset getting here would be bad\r
166 //\r
167 ASSERT (FALSE);\r
168}\r
169\r
170BOOLEAN\r
171GetAcpiDescription (\r
172 IN EFI_ACPI_DESCRIPTION *AcpiDescription\r
173 )\r
174{\r
175 EFI_HOB_GUID_TYPE *HobAcpiDescription;\r
176 //\r
177 // Get AcpiDescription Hob\r
178 //\r
179 HobAcpiDescription = GetFirstGuidHob (&gEfiAcpiDescriptionGuid);\r
180 if (HobAcpiDescription == NULL) {\r
181 return FALSE;\r
182 }\r
183\r
184 //\r
185 // Copy it to Runtime Memory\r
186 //\r
187 ASSERT (sizeof (EFI_ACPI_DESCRIPTION) == GET_GUID_HOB_DATA_SIZE (HobAcpiDescription));\r
188 CopyMem (AcpiDescription, GET_GUID_HOB_DATA (HobAcpiDescription), sizeof (EFI_ACPI_DESCRIPTION));\r
189\r
190 DEBUG ((EFI_D_ERROR, "ACPI Reset Base - %lx\n", AcpiDescription->RESET_REG.Address));\r
191 DEBUG ((EFI_D_ERROR, "ACPI Reset Value - %02x\n", (UINTN)AcpiDescription->RESET_VALUE));\r
192 DEBUG ((EFI_D_ERROR, "IAPC support - %x\n", (UINTN)(AcpiDescription->IAPC_BOOT_ARCH)));\r
193 return TRUE;\r
194}\r