1 | /****************************************************************************** |
2 | * |
3 | * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface |
4 | * |
5 | *****************************************************************************/ |
6 | |
7 | /* |
8 | * Copyright (C) 2000 - 2016, Intel Corp. |
9 | * All rights reserved. |
10 | * |
11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions |
13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions, and the following disclaimer, |
16 | * without modification. |
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
18 | * substantially similar to the "NO WARRANTY" disclaimer below |
19 | * ("Disclaimer") and any redistribution must be conditioned upon |
20 | * including a substantially similar Disclaimer requirement for further |
21 | * binary redistribution. |
22 | * 3. Neither the names of the above-listed copyright holders nor the names |
23 | * of any contributors may be used to endorse or promote products derived |
24 | * from this software without specific prior written permission. |
25 | * |
26 | * Alternatively, this software may be distributed under the terms of the |
27 | * GNU General Public License ("GPL") version 2 as published by the Free |
28 | * Software Foundation. |
29 | * |
30 | * NO WARRANTY |
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ |
43 | |
44 | #include "acpi.h" |
45 | #include "accommon.h" |
46 | |
47 | |
48 | #define _COMPONENT ACPI_HARDWARE |
49 | ACPI_MODULE_NAME ("hwacpi" ) |
50 | |
51 | |
52 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ |
53 | /****************************************************************************** |
54 | * |
55 | * FUNCTION: AcpiHwSetMode |
56 | * |
57 | * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY |
58 | * |
59 | * RETURN: Status |
60 | * |
61 | * DESCRIPTION: Transitions the system into the requested mode. |
62 | * |
63 | ******************************************************************************/ |
64 | |
65 | ACPI_STATUS |
66 | AcpiHwSetMode ( |
67 | UINT32 Mode) |
68 | { |
69 | |
70 | ACPI_STATUS Status; |
71 | UINT32 Retry; |
72 | |
73 | |
74 | ACPI_FUNCTION_TRACE (HwSetMode); |
75 | |
76 | |
77 | /* If the Hardware Reduced flag is set, machine is always in acpi mode */ |
78 | |
79 | if (AcpiGbl_ReducedHardware) |
80 | { |
81 | return_ACPI_STATUS (AE_OK); |
82 | } |
83 | |
84 | /* |
85 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, |
86 | * system does not support mode transition. |
87 | */ |
88 | if (!AcpiGbl_FADT.SmiCommand) |
89 | { |
90 | ACPI_ERROR ((AE_INFO, "No SMI_CMD in FADT, mode transition failed" )); |
91 | return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); |
92 | } |
93 | |
94 | /* |
95 | * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE |
96 | * in FADT: If it is zero, enabling or disabling is not supported. |
97 | * As old systems may have used zero for mode transition, |
98 | * we make sure both the numbers are zero to determine these |
99 | * transitions are not supported. |
100 | */ |
101 | if (!AcpiGbl_FADT.AcpiEnable && !AcpiGbl_FADT.AcpiDisable) |
102 | { |
103 | ACPI_ERROR ((AE_INFO, |
104 | "No ACPI mode transition supported in this system " |
105 | "(enable/disable both zero)" )); |
106 | return_ACPI_STATUS (AE_OK); |
107 | } |
108 | |
109 | switch (Mode) |
110 | { |
111 | case ACPI_SYS_MODE_ACPI: |
112 | |
113 | /* BIOS should have disabled ALL fixed and GP events */ |
114 | |
115 | Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, |
116 | (UINT32) AcpiGbl_FADT.AcpiEnable, 8); |
117 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Attempting to enable ACPI mode\n" )); |
118 | break; |
119 | |
120 | case ACPI_SYS_MODE_LEGACY: |
121 | /* |
122 | * BIOS should clear all fixed status bits and restore fixed event |
123 | * enable bits to default |
124 | */ |
125 | Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, |
126 | (UINT32) AcpiGbl_FADT.AcpiDisable, 8); |
127 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, |
128 | "Attempting to enable Legacy (non-ACPI) mode\n" )); |
129 | break; |
130 | |
131 | default: |
132 | |
133 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
134 | } |
135 | |
136 | if (ACPI_FAILURE (Status)) |
137 | { |
138 | ACPI_EXCEPTION ((AE_INFO, Status, |
139 | "Could not write ACPI mode change" )); |
140 | return_ACPI_STATUS (Status); |
141 | } |
142 | |
143 | /* |
144 | * Some hardware takes a LONG time to switch modes. Give them 3 sec to |
145 | * do so, but allow faster systems to proceed more quickly. |
146 | */ |
147 | Retry = 3000; |
148 | while (Retry) |
149 | { |
150 | if (AcpiHwGetMode () == Mode) |
151 | { |
152 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, |
153 | "Mode %X successfully enabled\n" , Mode)); |
154 | return_ACPI_STATUS (AE_OK); |
155 | } |
156 | AcpiOsStall (ACPI_USEC_PER_MSEC); |
157 | Retry--; |
158 | } |
159 | |
160 | ACPI_ERROR ((AE_INFO, "Hardware did not change modes" )); |
161 | return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); |
162 | } |
163 | |
164 | |
165 | /******************************************************************************* |
166 | * |
167 | * FUNCTION: AcpiHwGetMode |
168 | * |
169 | * PARAMETERS: none |
170 | * |
171 | * RETURN: SYS_MODE_ACPI or SYS_MODE_LEGACY |
172 | * |
173 | * DESCRIPTION: Return current operating state of system. Determined by |
174 | * querying the SCI_EN bit. |
175 | * |
176 | ******************************************************************************/ |
177 | |
178 | UINT32 |
179 | AcpiHwGetMode ( |
180 | void) |
181 | { |
182 | ACPI_STATUS Status; |
183 | UINT32 Value; |
184 | |
185 | |
186 | ACPI_FUNCTION_TRACE (HwGetMode); |
187 | |
188 | |
189 | /* If the Hardware Reduced flag is set, machine is always in acpi mode */ |
190 | |
191 | if (AcpiGbl_ReducedHardware) |
192 | { |
193 | return_UINT32 (ACPI_SYS_MODE_ACPI); |
194 | } |
195 | |
196 | /* |
197 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, |
198 | * system does not support mode transition. |
199 | */ |
200 | if (!AcpiGbl_FADT.SmiCommand) |
201 | { |
202 | return_UINT32 (ACPI_SYS_MODE_ACPI); |
203 | } |
204 | |
205 | Status = AcpiReadBitRegister (ACPI_BITREG_SCI_ENABLE, &Value); |
206 | if (ACPI_FAILURE (Status)) |
207 | { |
208 | return_UINT32 (ACPI_SYS_MODE_LEGACY); |
209 | } |
210 | |
211 | if (Value) |
212 | { |
213 | return_UINT32 (ACPI_SYS_MODE_ACPI); |
214 | } |
215 | else |
216 | { |
217 | return_UINT32 (ACPI_SYS_MODE_LEGACY); |
218 | } |
219 | } |
220 | |
221 | #endif /* !ACPI_REDUCED_HARDWARE */ |
222 | |