hwregs.c revision 1.1 1 1.1 jruoho
2 1.1 jruoho /*******************************************************************************
3 1.1 jruoho *
4 1.1 jruoho * Module Name: hwregs - Read/write access functions for the various ACPI
5 1.1 jruoho * control and status registers.
6 1.1 jruoho *
7 1.1 jruoho ******************************************************************************/
8 1.1 jruoho
9 1.1 jruoho /******************************************************************************
10 1.1 jruoho *
11 1.1 jruoho * 1. Copyright Notice
12 1.1 jruoho *
13 1.1 jruoho * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
14 1.1 jruoho * All rights reserved.
15 1.1 jruoho *
16 1.1 jruoho * 2. License
17 1.1 jruoho *
18 1.1 jruoho * 2.1. This is your license from Intel Corp. under its intellectual property
19 1.1 jruoho * rights. You may have additional license terms from the party that provided
20 1.1 jruoho * you this software, covering your right to use that party's intellectual
21 1.1 jruoho * property rights.
22 1.1 jruoho *
23 1.1 jruoho * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 1.1 jruoho * copy of the source code appearing in this file ("Covered Code") an
25 1.1 jruoho * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 1.1 jruoho * base code distributed originally by Intel ("Original Intel Code") to copy,
27 1.1 jruoho * make derivatives, distribute, use and display any portion of the Covered
28 1.1 jruoho * Code in any form, with the right to sublicense such rights; and
29 1.1 jruoho *
30 1.1 jruoho * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 1.1 jruoho * license (with the right to sublicense), under only those claims of Intel
32 1.1 jruoho * patents that are infringed by the Original Intel Code, to make, use, sell,
33 1.1 jruoho * offer to sell, and import the Covered Code and derivative works thereof
34 1.1 jruoho * solely to the minimum extent necessary to exercise the above copyright
35 1.1 jruoho * license, and in no event shall the patent license extend to any additions
36 1.1 jruoho * to or modifications of the Original Intel Code. No other license or right
37 1.1 jruoho * is granted directly or by implication, estoppel or otherwise;
38 1.1 jruoho *
39 1.1 jruoho * The above copyright and patent license is granted only if the following
40 1.1 jruoho * conditions are met:
41 1.1 jruoho *
42 1.1 jruoho * 3. Conditions
43 1.1 jruoho *
44 1.1 jruoho * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 1.1 jruoho * Redistribution of source code of any substantial portion of the Covered
46 1.1 jruoho * Code or modification with rights to further distribute source must include
47 1.1 jruoho * the above Copyright Notice, the above License, this list of Conditions,
48 1.1 jruoho * and the following Disclaimer and Export Compliance provision. In addition,
49 1.1 jruoho * Licensee must cause all Covered Code to which Licensee contributes to
50 1.1 jruoho * contain a file documenting the changes Licensee made to create that Covered
51 1.1 jruoho * Code and the date of any change. Licensee must include in that file the
52 1.1 jruoho * documentation of any changes made by any predecessor Licensee. Licensee
53 1.1 jruoho * must include a prominent statement that the modification is derived,
54 1.1 jruoho * directly or indirectly, from Original Intel Code.
55 1.1 jruoho *
56 1.1 jruoho * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 1.1 jruoho * Redistribution of source code of any substantial portion of the Covered
58 1.1 jruoho * Code or modification without rights to further distribute source must
59 1.1 jruoho * include the following Disclaimer and Export Compliance provision in the
60 1.1 jruoho * documentation and/or other materials provided with distribution. In
61 1.1 jruoho * addition, Licensee may not authorize further sublicense of source of any
62 1.1 jruoho * portion of the Covered Code, and must include terms to the effect that the
63 1.1 jruoho * license from Licensee to its licensee is limited to the intellectual
64 1.1 jruoho * property embodied in the software Licensee provides to its licensee, and
65 1.1 jruoho * not to intellectual property embodied in modifications its licensee may
66 1.1 jruoho * make.
67 1.1 jruoho *
68 1.1 jruoho * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 1.1 jruoho * substantial portion of the Covered Code or modification must reproduce the
70 1.1 jruoho * above Copyright Notice, and the following Disclaimer and Export Compliance
71 1.1 jruoho * provision in the documentation and/or other materials provided with the
72 1.1 jruoho * distribution.
73 1.1 jruoho *
74 1.1 jruoho * 3.4. Intel retains all right, title, and interest in and to the Original
75 1.1 jruoho * Intel Code.
76 1.1 jruoho *
77 1.1 jruoho * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 1.1 jruoho * Intel shall be used in advertising or otherwise to promote the sale, use or
79 1.1 jruoho * other dealings in products derived from or relating to the Covered Code
80 1.1 jruoho * without prior written authorization from Intel.
81 1.1 jruoho *
82 1.1 jruoho * 4. Disclaimer and Export Compliance
83 1.1 jruoho *
84 1.1 jruoho * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 1.1 jruoho * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 1.1 jruoho * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
87 1.1 jruoho * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
88 1.1 jruoho * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
89 1.1 jruoho * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 1.1 jruoho * PARTICULAR PURPOSE.
91 1.1 jruoho *
92 1.1 jruoho * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 1.1 jruoho * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 1.1 jruoho * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 1.1 jruoho * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 1.1 jruoho * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 1.1 jruoho * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
98 1.1 jruoho * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 1.1 jruoho * LIMITED REMEDY.
100 1.1 jruoho *
101 1.1 jruoho * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 1.1 jruoho * software or system incorporating such software without first obtaining any
103 1.1 jruoho * required license or other approval from the U. S. Department of Commerce or
104 1.1 jruoho * any other agency or department of the United States Government. In the
105 1.1 jruoho * event Licensee exports any such software from the United States or
106 1.1 jruoho * re-exports any such software from a foreign destination, Licensee shall
107 1.1 jruoho * ensure that the distribution and export/re-export of the software is in
108 1.1 jruoho * compliance with all laws, regulations, orders, or other restrictions of the
109 1.1 jruoho * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 1.1 jruoho * any of its subsidiaries will export/re-export any technical data, process,
111 1.1 jruoho * software, or service, directly or indirectly, to any country for which the
112 1.1 jruoho * United States government or any agency thereof requires an export license,
113 1.1 jruoho * other governmental approval, or letter of assurance, without first obtaining
114 1.1 jruoho * such license, approval or letter.
115 1.1 jruoho *
116 1.1 jruoho *****************************************************************************/
117 1.1 jruoho
118 1.1 jruoho #define __HWREGS_C__
119 1.1 jruoho
120 1.1 jruoho #include "acpi.h"
121 1.1 jruoho #include "accommon.h"
122 1.1 jruoho #include "acevents.h"
123 1.1 jruoho
124 1.1 jruoho #define _COMPONENT ACPI_HARDWARE
125 1.1 jruoho ACPI_MODULE_NAME ("hwregs")
126 1.1 jruoho
127 1.1 jruoho
128 1.1 jruoho /* Local Prototypes */
129 1.1 jruoho
130 1.1 jruoho static ACPI_STATUS
131 1.1 jruoho AcpiHwReadMultiple (
132 1.1 jruoho UINT32 *Value,
133 1.1 jruoho ACPI_GENERIC_ADDRESS *RegisterA,
134 1.1 jruoho ACPI_GENERIC_ADDRESS *RegisterB);
135 1.1 jruoho
136 1.1 jruoho static ACPI_STATUS
137 1.1 jruoho AcpiHwWriteMultiple (
138 1.1 jruoho UINT32 Value,
139 1.1 jruoho ACPI_GENERIC_ADDRESS *RegisterA,
140 1.1 jruoho ACPI_GENERIC_ADDRESS *RegisterB);
141 1.1 jruoho
142 1.1 jruoho
143 1.1 jruoho /******************************************************************************
144 1.1 jruoho *
145 1.1 jruoho * FUNCTION: AcpiHwValidateRegister
146 1.1 jruoho *
147 1.1 jruoho * PARAMETERS: Reg - GAS register structure
148 1.1 jruoho * MaxBitWidth - Max BitWidth supported (32 or 64)
149 1.1 jruoho * Address - Pointer to where the gas->address
150 1.1 jruoho * is returned
151 1.1 jruoho *
152 1.1 jruoho * RETURN: Status
153 1.1 jruoho *
154 1.1 jruoho * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS
155 1.1 jruoho * pointer, Address, SpaceId, BitWidth, and BitOffset.
156 1.1 jruoho *
157 1.1 jruoho ******************************************************************************/
158 1.1 jruoho
159 1.1 jruoho ACPI_STATUS
160 1.1 jruoho AcpiHwValidateRegister (
161 1.1 jruoho ACPI_GENERIC_ADDRESS *Reg,
162 1.1 jruoho UINT8 MaxBitWidth,
163 1.1 jruoho UINT64 *Address)
164 1.1 jruoho {
165 1.1 jruoho
166 1.1 jruoho /* Must have a valid pointer to a GAS structure */
167 1.1 jruoho
168 1.1 jruoho if (!Reg)
169 1.1 jruoho {
170 1.1 jruoho return (AE_BAD_PARAMETER);
171 1.1 jruoho }
172 1.1 jruoho
173 1.1 jruoho /*
174 1.1 jruoho * Copy the target address. This handles possible alignment issues.
175 1.1 jruoho * Address must not be null. A null address also indicates an optional
176 1.1 jruoho * ACPI register that is not supported, so no error message.
177 1.1 jruoho */
178 1.1 jruoho ACPI_MOVE_64_TO_64 (Address, &Reg->Address);
179 1.1 jruoho if (!(*Address))
180 1.1 jruoho {
181 1.1 jruoho return (AE_BAD_ADDRESS);
182 1.1 jruoho }
183 1.1 jruoho
184 1.1 jruoho /* Validate the SpaceID */
185 1.1 jruoho
186 1.1 jruoho if ((Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
187 1.1 jruoho (Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_IO))
188 1.1 jruoho {
189 1.1 jruoho ACPI_ERROR ((AE_INFO,
190 1.1 jruoho "Unsupported address space: 0x%X", Reg->SpaceId));
191 1.1 jruoho return (AE_SUPPORT);
192 1.1 jruoho }
193 1.1 jruoho
194 1.1 jruoho /* Validate the BitWidth */
195 1.1 jruoho
196 1.1 jruoho if ((Reg->BitWidth != 8) &&
197 1.1 jruoho (Reg->BitWidth != 16) &&
198 1.1 jruoho (Reg->BitWidth != 32) &&
199 1.1 jruoho (Reg->BitWidth != MaxBitWidth))
200 1.1 jruoho {
201 1.1 jruoho ACPI_ERROR ((AE_INFO,
202 1.1 jruoho "Unsupported register bit width: 0x%X", Reg->BitWidth));
203 1.1 jruoho return (AE_SUPPORT);
204 1.1 jruoho }
205 1.1 jruoho
206 1.1 jruoho /* Validate the BitOffset. Just a warning for now. */
207 1.1 jruoho
208 1.1 jruoho if (Reg->BitOffset != 0)
209 1.1 jruoho {
210 1.1 jruoho ACPI_WARNING ((AE_INFO,
211 1.1 jruoho "Unsupported register bit offset: 0x%X", Reg->BitOffset));
212 1.1 jruoho }
213 1.1 jruoho
214 1.1 jruoho return (AE_OK);
215 1.1 jruoho }
216 1.1 jruoho
217 1.1 jruoho
218 1.1 jruoho /******************************************************************************
219 1.1 jruoho *
220 1.1 jruoho * FUNCTION: AcpiHwRead
221 1.1 jruoho *
222 1.1 jruoho * PARAMETERS: Value - Where the value is returned
223 1.1 jruoho * Reg - GAS register structure
224 1.1 jruoho *
225 1.1 jruoho * RETURN: Status
226 1.1 jruoho *
227 1.1 jruoho * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
228 1.1 jruoho * version of AcpiRead, used internally since the overhead of
229 1.1 jruoho * 64-bit values is not needed.
230 1.1 jruoho *
231 1.1 jruoho * LIMITATIONS: <These limitations also apply to AcpiHwWrite>
232 1.1 jruoho * BitWidth must be exactly 8, 16, or 32.
233 1.1 jruoho * SpaceID must be SystemMemory or SystemIO.
234 1.1 jruoho * BitOffset and AccessWidth are currently ignored, as there has
235 1.1 jruoho * not been a need to implement these.
236 1.1 jruoho *
237 1.1 jruoho ******************************************************************************/
238 1.1 jruoho
239 1.1 jruoho ACPI_STATUS
240 1.1 jruoho AcpiHwRead (
241 1.1 jruoho UINT32 *Value,
242 1.1 jruoho ACPI_GENERIC_ADDRESS *Reg)
243 1.1 jruoho {
244 1.1 jruoho UINT64 Address;
245 1.1 jruoho ACPI_STATUS Status;
246 1.1 jruoho
247 1.1 jruoho
248 1.1 jruoho ACPI_FUNCTION_NAME (HwRead);
249 1.1 jruoho
250 1.1 jruoho
251 1.1 jruoho /* Validate contents of the GAS register */
252 1.1 jruoho
253 1.1 jruoho Status = AcpiHwValidateRegister (Reg, 32, &Address);
254 1.1 jruoho if (ACPI_FAILURE (Status))
255 1.1 jruoho {
256 1.1 jruoho return (Status);
257 1.1 jruoho }
258 1.1 jruoho
259 1.1 jruoho /* Initialize entire 32-bit return value to zero */
260 1.1 jruoho
261 1.1 jruoho *Value = 0;
262 1.1 jruoho
263 1.1 jruoho /*
264 1.1 jruoho * Two address spaces supported: Memory or IO. PCI_Config is
265 1.1 jruoho * not supported here because the GAS structure is insufficient
266 1.1 jruoho */
267 1.1 jruoho if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
268 1.1 jruoho {
269 1.1 jruoho Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
270 1.1 jruoho Address, Value, Reg->BitWidth);
271 1.1 jruoho }
272 1.1 jruoho else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
273 1.1 jruoho {
274 1.1 jruoho Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
275 1.1 jruoho Address, Value, Reg->BitWidth);
276 1.1 jruoho }
277 1.1 jruoho
278 1.1 jruoho ACPI_DEBUG_PRINT ((ACPI_DB_IO,
279 1.1 jruoho "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
280 1.1 jruoho *Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
281 1.1 jruoho AcpiUtGetRegionName (Reg->SpaceId)));
282 1.1 jruoho
283 1.1 jruoho return (Status);
284 1.1 jruoho }
285 1.1 jruoho
286 1.1 jruoho
287 1.1 jruoho /******************************************************************************
288 1.1 jruoho *
289 1.1 jruoho * FUNCTION: AcpiHwWrite
290 1.1 jruoho *
291 1.1 jruoho * PARAMETERS: Value - Value to be written
292 1.1 jruoho * Reg - GAS register structure
293 1.1 jruoho *
294 1.1 jruoho * RETURN: Status
295 1.1 jruoho *
296 1.1 jruoho * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
297 1.1 jruoho * version of AcpiWrite, used internally since the overhead of
298 1.1 jruoho * 64-bit values is not needed.
299 1.1 jruoho *
300 1.1 jruoho ******************************************************************************/
301 1.1 jruoho
302 1.1 jruoho ACPI_STATUS
303 1.1 jruoho AcpiHwWrite (
304 1.1 jruoho UINT32 Value,
305 1.1 jruoho ACPI_GENERIC_ADDRESS *Reg)
306 1.1 jruoho {
307 1.1 jruoho UINT64 Address;
308 1.1 jruoho ACPI_STATUS Status;
309 1.1 jruoho
310 1.1 jruoho
311 1.1 jruoho ACPI_FUNCTION_NAME (HwWrite);
312 1.1 jruoho
313 1.1 jruoho
314 1.1 jruoho /* Validate contents of the GAS register */
315 1.1 jruoho
316 1.1 jruoho Status = AcpiHwValidateRegister (Reg, 32, &Address);
317 1.1 jruoho if (ACPI_FAILURE (Status))
318 1.1 jruoho {
319 1.1 jruoho return (Status);
320 1.1 jruoho }
321 1.1 jruoho
322 1.1 jruoho /*
323 1.1 jruoho * Two address spaces supported: Memory or IO. PCI_Config is
324 1.1 jruoho * not supported here because the GAS structure is insufficient
325 1.1 jruoho */
326 1.1 jruoho if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
327 1.1 jruoho {
328 1.1 jruoho Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
329 1.1 jruoho Address, Value, Reg->BitWidth);
330 1.1 jruoho }
331 1.1 jruoho else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
332 1.1 jruoho {
333 1.1 jruoho Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
334 1.1 jruoho Address, Value, Reg->BitWidth);
335 1.1 jruoho }
336 1.1 jruoho
337 1.1 jruoho ACPI_DEBUG_PRINT ((ACPI_DB_IO,
338 1.1 jruoho "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
339 1.1 jruoho Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
340 1.1 jruoho AcpiUtGetRegionName (Reg->SpaceId)));
341 1.1 jruoho
342 1.1 jruoho return (Status);
343 1.1 jruoho }
344 1.1 jruoho
345 1.1 jruoho
346 1.1 jruoho /*******************************************************************************
347 1.1 jruoho *
348 1.1 jruoho * FUNCTION: AcpiHwClearAcpiStatus
349 1.1 jruoho *
350 1.1 jruoho * PARAMETERS: None
351 1.1 jruoho *
352 1.1 jruoho * RETURN: Status
353 1.1 jruoho *
354 1.1 jruoho * DESCRIPTION: Clears all fixed and general purpose status bits
355 1.1 jruoho *
356 1.1 jruoho ******************************************************************************/
357 1.1 jruoho
358 1.1 jruoho ACPI_STATUS
359 1.1 jruoho AcpiHwClearAcpiStatus (
360 1.1 jruoho void)
361 1.1 jruoho {
362 1.1 jruoho ACPI_STATUS Status;
363 1.1 jruoho ACPI_CPU_FLAGS LockFlags = 0;
364 1.1 jruoho
365 1.1 jruoho
366 1.1 jruoho ACPI_FUNCTION_TRACE (HwClearAcpiStatus);
367 1.1 jruoho
368 1.1 jruoho
369 1.1 jruoho ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
370 1.1 jruoho ACPI_BITMASK_ALL_FIXED_STATUS,
371 1.1 jruoho ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus.Address)));
372 1.1 jruoho
373 1.1 jruoho LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
374 1.1 jruoho
375 1.1 jruoho /* Clear the fixed events in PM1 A/B */
376 1.1 jruoho
377 1.1 jruoho Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
378 1.1 jruoho ACPI_BITMASK_ALL_FIXED_STATUS);
379 1.1 jruoho if (ACPI_FAILURE (Status))
380 1.1 jruoho {
381 1.1 jruoho goto UnlockAndExit;
382 1.1 jruoho }
383 1.1 jruoho
384 1.1 jruoho /* Clear the GPE Bits in all GPE registers in all GPE blocks */
385 1.1 jruoho
386 1.1 jruoho Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL);
387 1.1 jruoho
388 1.1 jruoho UnlockAndExit:
389 1.1 jruoho AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
390 1.1 jruoho return_ACPI_STATUS (Status);
391 1.1 jruoho }
392 1.1 jruoho
393 1.1 jruoho
394 1.1 jruoho /*******************************************************************************
395 1.1 jruoho *
396 1.1 jruoho * FUNCTION: AcpiHwGetRegisterBitMask
397 1.1 jruoho *
398 1.1 jruoho * PARAMETERS: RegisterId - Index of ACPI Register to access
399 1.1 jruoho *
400 1.1 jruoho * RETURN: The bitmask to be used when accessing the register
401 1.1 jruoho *
402 1.1 jruoho * DESCRIPTION: Map RegisterId into a register bitmask.
403 1.1 jruoho *
404 1.1 jruoho ******************************************************************************/
405 1.1 jruoho
406 1.1 jruoho ACPI_BIT_REGISTER_INFO *
407 1.1 jruoho AcpiHwGetBitRegisterInfo (
408 1.1 jruoho UINT32 RegisterId)
409 1.1 jruoho {
410 1.1 jruoho ACPI_FUNCTION_ENTRY ();
411 1.1 jruoho
412 1.1 jruoho
413 1.1 jruoho if (RegisterId > ACPI_BITREG_MAX)
414 1.1 jruoho {
415 1.1 jruoho ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: 0x%X", RegisterId));
416 1.1 jruoho return (NULL);
417 1.1 jruoho }
418 1.1 jruoho
419 1.1 jruoho return (&AcpiGbl_BitRegisterInfo[RegisterId]);
420 1.1 jruoho }
421 1.1 jruoho
422 1.1 jruoho
423 1.1 jruoho /******************************************************************************
424 1.1 jruoho *
425 1.1 jruoho * FUNCTION: AcpiHwWritePm1Control
426 1.1 jruoho *
427 1.1 jruoho * PARAMETERS: Pm1aControl - Value to be written to PM1A control
428 1.1 jruoho * Pm1bControl - Value to be written to PM1B control
429 1.1 jruoho *
430 1.1 jruoho * RETURN: Status
431 1.1 jruoho *
432 1.1 jruoho * DESCRIPTION: Write the PM1 A/B control registers. These registers are
433 1.1 jruoho * different than than the PM1 A/B status and enable registers
434 1.1 jruoho * in that different values can be written to the A/B registers.
435 1.1 jruoho * Most notably, the SLP_TYP bits can be different, as per the
436 1.1 jruoho * values returned from the _Sx predefined methods.
437 1.1 jruoho *
438 1.1 jruoho ******************************************************************************/
439 1.1 jruoho
440 1.1 jruoho ACPI_STATUS
441 1.1 jruoho AcpiHwWritePm1Control (
442 1.1 jruoho UINT32 Pm1aControl,
443 1.1 jruoho UINT32 Pm1bControl)
444 1.1 jruoho {
445 1.1 jruoho ACPI_STATUS Status;
446 1.1 jruoho
447 1.1 jruoho
448 1.1 jruoho ACPI_FUNCTION_TRACE (HwWritePm1Control);
449 1.1 jruoho
450 1.1 jruoho
451 1.1 jruoho Status = AcpiHwWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock);
452 1.1 jruoho if (ACPI_FAILURE (Status))
453 1.1 jruoho {
454 1.1 jruoho return_ACPI_STATUS (Status);
455 1.1 jruoho }
456 1.1 jruoho
457 1.1 jruoho if (AcpiGbl_FADT.XPm1bControlBlock.Address)
458 1.1 jruoho {
459 1.1 jruoho Status = AcpiHwWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock);
460 1.1 jruoho }
461 1.1 jruoho return_ACPI_STATUS (Status);
462 1.1 jruoho }
463 1.1 jruoho
464 1.1 jruoho
465 1.1 jruoho /******************************************************************************
466 1.1 jruoho *
467 1.1 jruoho * FUNCTION: AcpiHwRegisterRead
468 1.1 jruoho *
469 1.1 jruoho * PARAMETERS: RegisterId - ACPI Register ID
470 1.1 jruoho * ReturnValue - Where the register value is returned
471 1.1 jruoho *
472 1.1 jruoho * RETURN: Status and the value read.
473 1.1 jruoho *
474 1.1 jruoho * DESCRIPTION: Read from the specified ACPI register
475 1.1 jruoho *
476 1.1 jruoho ******************************************************************************/
477 1.1 jruoho
478 1.1 jruoho ACPI_STATUS
479 1.1 jruoho AcpiHwRegisterRead (
480 1.1 jruoho UINT32 RegisterId,
481 1.1 jruoho UINT32 *ReturnValue)
482 1.1 jruoho {
483 1.1 jruoho UINT32 Value = 0;
484 1.1 jruoho ACPI_STATUS Status;
485 1.1 jruoho
486 1.1 jruoho
487 1.1 jruoho ACPI_FUNCTION_TRACE (HwRegisterRead);
488 1.1 jruoho
489 1.1 jruoho
490 1.1 jruoho switch (RegisterId)
491 1.1 jruoho {
492 1.1 jruoho case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
493 1.1 jruoho
494 1.1 jruoho Status = AcpiHwReadMultiple (&Value,
495 1.1 jruoho &AcpiGbl_XPm1aStatus,
496 1.1 jruoho &AcpiGbl_XPm1bStatus);
497 1.1 jruoho break;
498 1.1 jruoho
499 1.1 jruoho
500 1.1 jruoho case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
501 1.1 jruoho
502 1.1 jruoho Status = AcpiHwReadMultiple (&Value,
503 1.1 jruoho &AcpiGbl_XPm1aEnable,
504 1.1 jruoho &AcpiGbl_XPm1bEnable);
505 1.1 jruoho break;
506 1.1 jruoho
507 1.1 jruoho
508 1.1 jruoho case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
509 1.1 jruoho
510 1.1 jruoho Status = AcpiHwReadMultiple (&Value,
511 1.1 jruoho &AcpiGbl_FADT.XPm1aControlBlock,
512 1.1 jruoho &AcpiGbl_FADT.XPm1bControlBlock);
513 1.1 jruoho
514 1.1 jruoho /*
515 1.1 jruoho * Zero the write-only bits. From the ACPI specification, "Hardware
516 1.1 jruoho * Write-Only Bits": "Upon reads to registers with write-only bits,
517 1.1 jruoho * software masks out all write-only bits."
518 1.1 jruoho */
519 1.1 jruoho Value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
520 1.1 jruoho break;
521 1.1 jruoho
522 1.1 jruoho
523 1.1 jruoho case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
524 1.1 jruoho
525 1.1 jruoho Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock);
526 1.1 jruoho break;
527 1.1 jruoho
528 1.1 jruoho
529 1.1 jruoho case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
530 1.1 jruoho
531 1.1 jruoho Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPmTimerBlock);
532 1.1 jruoho break;
533 1.1 jruoho
534 1.1 jruoho
535 1.1 jruoho case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
536 1.1 jruoho
537 1.1 jruoho Status = AcpiHwReadPort (AcpiGbl_FADT.SmiCommand, &Value, 8);
538 1.1 jruoho break;
539 1.1 jruoho
540 1.1 jruoho
541 1.1 jruoho default:
542 1.1 jruoho ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
543 1.1 jruoho RegisterId));
544 1.1 jruoho Status = AE_BAD_PARAMETER;
545 1.1 jruoho break;
546 1.1 jruoho }
547 1.1 jruoho
548 1.1 jruoho if (ACPI_SUCCESS (Status))
549 1.1 jruoho {
550 1.1 jruoho *ReturnValue = Value;
551 1.1 jruoho }
552 1.1 jruoho
553 1.1 jruoho return_ACPI_STATUS (Status);
554 1.1 jruoho }
555 1.1 jruoho
556 1.1 jruoho
557 1.1 jruoho /******************************************************************************
558 1.1 jruoho *
559 1.1 jruoho * FUNCTION: AcpiHwRegisterWrite
560 1.1 jruoho *
561 1.1 jruoho * PARAMETERS: RegisterId - ACPI Register ID
562 1.1 jruoho * Value - The value to write
563 1.1 jruoho *
564 1.1 jruoho * RETURN: Status
565 1.1 jruoho *
566 1.1 jruoho * DESCRIPTION: Write to the specified ACPI register
567 1.1 jruoho *
568 1.1 jruoho * NOTE: In accordance with the ACPI specification, this function automatically
569 1.1 jruoho * preserves the value of the following bits, meaning that these bits cannot be
570 1.1 jruoho * changed via this interface:
571 1.1 jruoho *
572 1.1 jruoho * PM1_CONTROL[0] = SCI_EN
573 1.1 jruoho * PM1_CONTROL[9]
574 1.1 jruoho * PM1_STATUS[11]
575 1.1 jruoho *
576 1.1 jruoho * ACPI References:
577 1.1 jruoho * 1) Hardware Ignored Bits: When software writes to a register with ignored
578 1.1 jruoho * bit fields, it preserves the ignored bit fields
579 1.1 jruoho * 2) SCI_EN: OSPM always preserves this bit position
580 1.1 jruoho *
581 1.1 jruoho ******************************************************************************/
582 1.1 jruoho
583 1.1 jruoho ACPI_STATUS
584 1.1 jruoho AcpiHwRegisterWrite (
585 1.1 jruoho UINT32 RegisterId,
586 1.1 jruoho UINT32 Value)
587 1.1 jruoho {
588 1.1 jruoho ACPI_STATUS Status;
589 1.1 jruoho UINT32 ReadValue;
590 1.1 jruoho
591 1.1 jruoho
592 1.1 jruoho ACPI_FUNCTION_TRACE (HwRegisterWrite);
593 1.1 jruoho
594 1.1 jruoho
595 1.1 jruoho switch (RegisterId)
596 1.1 jruoho {
597 1.1 jruoho case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
598 1.1 jruoho /*
599 1.1 jruoho * Handle the "ignored" bit in PM1 Status. According to the ACPI
600 1.1 jruoho * specification, ignored bits are to be preserved when writing.
601 1.1 jruoho * Normally, this would mean a read/modify/write sequence. However,
602 1.1 jruoho * preserving a bit in the status register is different. Writing a
603 1.1 jruoho * one clears the status, and writing a zero preserves the status.
604 1.1 jruoho * Therefore, we must always write zero to the ignored bit.
605 1.1 jruoho *
606 1.1 jruoho * This behavior is clarified in the ACPI 4.0 specification.
607 1.1 jruoho */
608 1.1 jruoho Value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
609 1.1 jruoho
610 1.1 jruoho Status = AcpiHwWriteMultiple (Value,
611 1.1 jruoho &AcpiGbl_XPm1aStatus,
612 1.1 jruoho &AcpiGbl_XPm1bStatus);
613 1.1 jruoho break;
614 1.1 jruoho
615 1.1 jruoho
616 1.1 jruoho case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
617 1.1 jruoho
618 1.1 jruoho Status = AcpiHwWriteMultiple (Value,
619 1.1 jruoho &AcpiGbl_XPm1aEnable,
620 1.1 jruoho &AcpiGbl_XPm1bEnable);
621 1.1 jruoho break;
622 1.1 jruoho
623 1.1 jruoho
624 1.1 jruoho case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
625 1.1 jruoho
626 1.1 jruoho /*
627 1.1 jruoho * Perform a read first to preserve certain bits (per ACPI spec)
628 1.1 jruoho * Note: This includes SCI_EN, we never want to change this bit
629 1.1 jruoho */
630 1.1 jruoho Status = AcpiHwReadMultiple (&ReadValue,
631 1.1 jruoho &AcpiGbl_FADT.XPm1aControlBlock,
632 1.1 jruoho &AcpiGbl_FADT.XPm1bControlBlock);
633 1.1 jruoho if (ACPI_FAILURE (Status))
634 1.1 jruoho {
635 1.1 jruoho goto Exit;
636 1.1 jruoho }
637 1.1 jruoho
638 1.1 jruoho /* Insert the bits to be preserved */
639 1.1 jruoho
640 1.1 jruoho ACPI_INSERT_BITS (Value, ACPI_PM1_CONTROL_PRESERVED_BITS, ReadValue);
641 1.1 jruoho
642 1.1 jruoho /* Now we can write the data */
643 1.1 jruoho
644 1.1 jruoho Status = AcpiHwWriteMultiple (Value,
645 1.1 jruoho &AcpiGbl_FADT.XPm1aControlBlock,
646 1.1 jruoho &AcpiGbl_FADT.XPm1bControlBlock);
647 1.1 jruoho break;
648 1.1 jruoho
649 1.1 jruoho
650 1.1 jruoho case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
651 1.1 jruoho
652 1.1 jruoho /*
653 1.1 jruoho * For control registers, all reserved bits must be preserved,
654 1.1 jruoho * as per the ACPI spec.
655 1.1 jruoho */
656 1.1 jruoho Status = AcpiHwRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock);
657 1.1 jruoho if (ACPI_FAILURE (Status))
658 1.1 jruoho {
659 1.1 jruoho goto Exit;
660 1.1 jruoho }
661 1.1 jruoho
662 1.1 jruoho /* Insert the bits to be preserved */
663 1.1 jruoho
664 1.1 jruoho ACPI_INSERT_BITS (Value, ACPI_PM2_CONTROL_PRESERVED_BITS, ReadValue);
665 1.1 jruoho
666 1.1 jruoho Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock);
667 1.1 jruoho break;
668 1.1 jruoho
669 1.1 jruoho
670 1.1 jruoho case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
671 1.1 jruoho
672 1.1 jruoho Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPmTimerBlock);
673 1.1 jruoho break;
674 1.1 jruoho
675 1.1 jruoho
676 1.1 jruoho case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
677 1.1 jruoho
678 1.1 jruoho /* SMI_CMD is currently always in IO space */
679 1.1 jruoho
680 1.1 jruoho Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, Value, 8);
681 1.1 jruoho break;
682 1.1 jruoho
683 1.1 jruoho
684 1.1 jruoho default:
685 1.1 jruoho ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
686 1.1 jruoho RegisterId));
687 1.1 jruoho Status = AE_BAD_PARAMETER;
688 1.1 jruoho break;
689 1.1 jruoho }
690 1.1 jruoho
691 1.1 jruoho Exit:
692 1.1 jruoho return_ACPI_STATUS (Status);
693 1.1 jruoho }
694 1.1 jruoho
695 1.1 jruoho
696 1.1 jruoho /******************************************************************************
697 1.1 jruoho *
698 1.1 jruoho * FUNCTION: AcpiHwReadMultiple
699 1.1 jruoho *
700 1.1 jruoho * PARAMETERS: Value - Where the register value is returned
701 1.1 jruoho * RegisterA - First ACPI register (required)
702 1.1 jruoho * RegisterB - Second ACPI register (optional)
703 1.1 jruoho *
704 1.1 jruoho * RETURN: Status
705 1.1 jruoho *
706 1.1 jruoho * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
707 1.1 jruoho *
708 1.1 jruoho ******************************************************************************/
709 1.1 jruoho
710 1.1 jruoho static ACPI_STATUS
711 1.1 jruoho AcpiHwReadMultiple (
712 1.1 jruoho UINT32 *Value,
713 1.1 jruoho ACPI_GENERIC_ADDRESS *RegisterA,
714 1.1 jruoho ACPI_GENERIC_ADDRESS *RegisterB)
715 1.1 jruoho {
716 1.1 jruoho UINT32 ValueA = 0;
717 1.1 jruoho UINT32 ValueB = 0;
718 1.1 jruoho ACPI_STATUS Status;
719 1.1 jruoho
720 1.1 jruoho
721 1.1 jruoho /* The first register is always required */
722 1.1 jruoho
723 1.1 jruoho Status = AcpiHwRead (&ValueA, RegisterA);
724 1.1 jruoho if (ACPI_FAILURE (Status))
725 1.1 jruoho {
726 1.1 jruoho return (Status);
727 1.1 jruoho }
728 1.1 jruoho
729 1.1 jruoho /* Second register is optional */
730 1.1 jruoho
731 1.1 jruoho if (RegisterB->Address)
732 1.1 jruoho {
733 1.1 jruoho Status = AcpiHwRead (&ValueB, RegisterB);
734 1.1 jruoho if (ACPI_FAILURE (Status))
735 1.1 jruoho {
736 1.1 jruoho return (Status);
737 1.1 jruoho }
738 1.1 jruoho }
739 1.1 jruoho
740 1.1 jruoho /*
741 1.1 jruoho * OR the two return values together. No shifting or masking is necessary,
742 1.1 jruoho * because of how the PM1 registers are defined in the ACPI specification:
743 1.1 jruoho *
744 1.1 jruoho * "Although the bits can be split between the two register blocks (each
745 1.1 jruoho * register block has a unique pointer within the FADT), the bit positions
746 1.1 jruoho * are maintained. The register block with unimplemented bits (that is,
747 1.1 jruoho * those implemented in the other register block) always returns zeros,
748 1.1 jruoho * and writes have no side effects"
749 1.1 jruoho */
750 1.1 jruoho *Value = (ValueA | ValueB);
751 1.1 jruoho return (AE_OK);
752 1.1 jruoho }
753 1.1 jruoho
754 1.1 jruoho
755 1.1 jruoho /******************************************************************************
756 1.1 jruoho *
757 1.1 jruoho * FUNCTION: AcpiHwWriteMultiple
758 1.1 jruoho *
759 1.1 jruoho * PARAMETERS: Value - The value to write
760 1.1 jruoho * RegisterA - First ACPI register (required)
761 1.1 jruoho * RegisterB - Second ACPI register (optional)
762 1.1 jruoho *
763 1.1 jruoho * RETURN: Status
764 1.1 jruoho *
765 1.1 jruoho * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
766 1.1 jruoho *
767 1.1 jruoho ******************************************************************************/
768 1.1 jruoho
769 1.1 jruoho static ACPI_STATUS
770 1.1 jruoho AcpiHwWriteMultiple (
771 1.1 jruoho UINT32 Value,
772 1.1 jruoho ACPI_GENERIC_ADDRESS *RegisterA,
773 1.1 jruoho ACPI_GENERIC_ADDRESS *RegisterB)
774 1.1 jruoho {
775 1.1 jruoho ACPI_STATUS Status;
776 1.1 jruoho
777 1.1 jruoho
778 1.1 jruoho /* The first register is always required */
779 1.1 jruoho
780 1.1 jruoho Status = AcpiHwWrite (Value, RegisterA);
781 1.1 jruoho if (ACPI_FAILURE (Status))
782 1.1 jruoho {
783 1.1 jruoho return (Status);
784 1.1 jruoho }
785 1.1 jruoho
786 1.1 jruoho /*
787 1.1 jruoho * Second register is optional
788 1.1 jruoho *
789 1.1 jruoho * No bit shifting or clearing is necessary, because of how the PM1
790 1.1 jruoho * registers are defined in the ACPI specification:
791 1.1 jruoho *
792 1.1 jruoho * "Although the bits can be split between the two register blocks (each
793 1.1 jruoho * register block has a unique pointer within the FADT), the bit positions
794 1.1 jruoho * are maintained. The register block with unimplemented bits (that is,
795 1.1 jruoho * those implemented in the other register block) always returns zeros,
796 1.1 jruoho * and writes have no side effects"
797 1.1 jruoho */
798 1.1 jruoho if (RegisterB->Address)
799 1.1 jruoho {
800 1.1 jruoho Status = AcpiHwWrite (Value, RegisterB);
801 1.1 jruoho }
802 1.1 jruoho
803 1.1 jruoho return (Status);
804 1.1 jruoho }
805 1.1 jruoho
806