1
2 /******************************************************************************
3 *
4 * Module Name: hwxface - Public ACPICA hardware interfaces
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45 #include "acpi.h"
46 #include "accommon.h"
47 #include "acnamesp.h"
48
49 #define _COMPONENT ACPI_HARDWARE
50 ACPI_MODULE_NAME ("hwxface")
51
52
53 /******************************************************************************
54 *
55 * FUNCTION: AcpiReset
56 *
57 * PARAMETERS: None
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
62 * support reset register in PCI config space, this must be
63 * handled separately.
64 *
74
75 ACPI_FUNCTION_TRACE (AcpiReset);
76
77
78 ResetReg = &AcpiGbl_FADT.ResetRegister;
79
80 /* Check if the reset register is supported */
81
82 if (!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) ||
83 !ResetReg->Address)
84 {
85 return_ACPI_STATUS (AE_NOT_EXIST);
86 }
87
88 if (ResetReg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
89 {
90 /*
91 * For I/O space, write directly to the OSL. This bypasses the port
92 * validation mechanism, which may block a valid write to the reset
93 * register.
94 */
95 Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
96 AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
97 }
98 else
99 {
100 /* Write the reset value to the reset register */
101
102 Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg);
103 }
104
105 return_ACPI_STATUS (Status);
106 }
107
108 ACPI_EXPORT_SYMBOL (AcpiReset)
109
110
111 /******************************************************************************
112 *
113 * FUNCTION: AcpiRead
114 *
115 * PARAMETERS: Value - Where the value is returned
116 * Reg - GAS register structure
117 *
118 * RETURN: Status
119 *
120 * DESCRIPTION: Read from either memory or IO space.
121 *
122 * LIMITATIONS: <These limitations also apply to AcpiWrite>
123 * BitWidth must be exactly 8, 16, 32, or 64.
124 * SpaceID must be SystemMemory or SystemIO.
125 * BitOffset and AccessWidth are currently ignored, as there has
126 * not been a need to implement these.
127 *
128 ******************************************************************************/
129
130 ACPI_STATUS
131 AcpiRead (
132 UINT64 *ReturnValue,
133 ACPI_GENERIC_ADDRESS *Reg)
134 {
135 UINT32 Value;
136 UINT32 Width;
137 UINT64 Address;
138 ACPI_STATUS Status;
139
140
141 ACPI_FUNCTION_NAME (AcpiRead);
142
143
144 if (!ReturnValue)
145 {
146 return (AE_BAD_PARAMETER);
147 }
148
149 /* Validate contents of the GAS register. Allow 64-bit transfers */
150
151 Status = AcpiHwValidateRegister (Reg, 64, &Address);
152 if (ACPI_FAILURE (Status))
153 {
154 return (Status);
155 }
156
157 Width = Reg->BitWidth;
158 if (Width == 64)
159 {
160 Width = 32; /* Break into two 32-bit transfers */
161 }
162
163 /* Initialize entire 64-bit return value to zero */
164
165 *ReturnValue = 0;
166 Value = 0;
167
168 /*
169 * Two address spaces supported: Memory or IO. PCI_Config is
170 * not supported here because the GAS structure is insufficient
171 */
172 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
173 {
174 Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
175 Address, &Value, Width);
176 if (ACPI_FAILURE (Status))
177 {
178 return (Status);
179 }
180 *ReturnValue = Value;
181
182 if (Reg->BitWidth == 64)
183 {
184 /* Read the top 32 bits */
185
186 Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
187 (Address + 4), &Value, 32);
188 if (ACPI_FAILURE (Status))
189 {
190 return (Status);
191 }
192 *ReturnValue |= ((UINT64) Value << 32);
193 }
194 }
195 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
196 {
197 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
198 Address, &Value, Width);
199 if (ACPI_FAILURE (Status))
200 {
201 return (Status);
202 }
203 *ReturnValue = Value;
204
205 if (Reg->BitWidth == 64)
206 {
207 /* Read the top 32 bits */
208
209 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
210 (Address + 4), &Value, 32);
211 if (ACPI_FAILURE (Status))
212 {
213 return (Status);
214 }
215 *ReturnValue |= ((UINT64) Value << 32);
216 }
217 }
218
219 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
220 "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
221 ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
222 ACPI_FORMAT_UINT64 (Address),
223 AcpiUtGetRegionName (Reg->SpaceId)));
224
225 return (Status);
226 }
227
228 ACPI_EXPORT_SYMBOL (AcpiRead)
229
230
231 /******************************************************************************
232 *
233 * FUNCTION: AcpiWrite
234 *
235 * PARAMETERS: Value - Value to be written
236 * Reg - GAS register structure
237 *
238 * RETURN: Status
239 *
240 * DESCRIPTION: Write to either memory or IO space.
241 *
242 ******************************************************************************/
243
244 ACPI_STATUS
245 AcpiWrite (
246 UINT64 Value,
247 ACPI_GENERIC_ADDRESS *Reg)
248 {
249 UINT32 Width;
250 UINT64 Address;
251 ACPI_STATUS Status;
252
253
254 ACPI_FUNCTION_NAME (AcpiWrite);
255
256
257 /* Validate contents of the GAS register. Allow 64-bit transfers */
258
259 Status = AcpiHwValidateRegister (Reg, 64, &Address);
260 if (ACPI_FAILURE (Status))
261 {
262 return (Status);
263 }
264
265 Width = Reg->BitWidth;
266 if (Width == 64)
267 {
268 Width = 32; /* Break into two 32-bit transfers */
269 }
270
271 /*
272 * Two address spaces supported: Memory or IO. PCI_Config is
273 * not supported here because the GAS structure is insufficient
274 */
275 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
276 {
277 Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
278 Address, ACPI_LODWORD (Value), Width);
279 if (ACPI_FAILURE (Status))
280 {
281 return (Status);
282 }
283
284 if (Reg->BitWidth == 64)
285 {
286 Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
287 (Address + 4), ACPI_HIDWORD (Value), 32);
288 if (ACPI_FAILURE (Status))
289 {
290 return (Status);
291 }
292 }
293 }
294 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
295 {
296 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
297 Address, ACPI_LODWORD (Value), Width);
298 if (ACPI_FAILURE (Status))
299 {
300 return (Status);
301 }
302
303 if (Reg->BitWidth == 64)
304 {
305 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
306 (Address + 4), ACPI_HIDWORD (Value), 32);
307 if (ACPI_FAILURE (Status))
308 {
309 return (Status);
310 }
311 }
312 }
313
314 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
315 "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n",
316 ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
317 ACPI_FORMAT_UINT64 (Address),
318 AcpiUtGetRegionName (Reg->SpaceId)));
319
320 return (Status);
321 }
322
323 ACPI_EXPORT_SYMBOL (AcpiWrite)
324
325
326 /*******************************************************************************
327 *
328 * FUNCTION: AcpiReadBitRegister
329 *
330 * PARAMETERS: RegisterId - ID of ACPI Bit Register to access
331 * ReturnValue - Value that was read from the register,
332 * normalized to bit position zero.
333 *
334 * RETURN: Status and the value read from the specified Register. Value
335 * returned is normalized to bit0 (is shifted all the way right)
336 *
337 * DESCRIPTION: ACPI BitRegister read function. Does not acquire the HW lock.
338 *
339 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
340 * PM2 Control.
341 *
342 * Note: The hardware lock is not required when reading the ACPI bit registers
343 * since almost all of them are single bit and it does not matter that
344 * the parent hardware register can be split across two physical
345 * registers. The only multi-bit field is SLP_TYP in the PM1 control
384 Value = ((RegisterValue & BitRegInfo->AccessBitMask)
385 >> BitRegInfo->BitPosition);
386
387 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
388 "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
389 RegisterId, BitRegInfo->ParentRegister, RegisterValue, Value));
390
391 *ReturnValue = Value;
392 return_ACPI_STATUS (AE_OK);
393 }
394
395 ACPI_EXPORT_SYMBOL (AcpiReadBitRegister)
396
397
398 /*******************************************************************************
399 *
400 * FUNCTION: AcpiWriteBitRegister
401 *
402 * PARAMETERS: RegisterId - ID of ACPI Bit Register to access
403 * Value - Value to write to the register, in bit
404 * position zero. The bit is automaticallly
405 * shifted to the correct position.
406 *
407 * RETURN: Status
408 *
409 * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
410 * since most operations require a read/modify/write sequence.
411 *
412 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
413 * PM2 Control.
414 *
415 * Note that at this level, the fact that there may be actually two
416 * hardware registers (A and B - and B may not exist) is abstracted.
417 *
418 ******************************************************************************/
419
420 ACPI_STATUS
421 AcpiWriteBitRegister (
422 UINT32 RegisterId,
423 UINT32 Value)
424 {
488 if (RegisterValue)
489 {
490 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
491 RegisterValue);
492 }
493 }
494
495 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
496 "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
497 RegisterId, BitRegInfo->ParentRegister, Value, RegisterValue));
498
499
500 UnlockAndExit:
501
502 AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
503 return_ACPI_STATUS (Status);
504 }
505
506 ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister)
507
508
509 /*******************************************************************************
510 *
511 * FUNCTION: AcpiGetSleepTypeData
512 *
513 * PARAMETERS: SleepState - Numeric sleep state
514 * *SleepTypeA - Where SLP_TYPa is returned
515 * *SleepTypeB - Where SLP_TYPb is returned
516 *
517 * RETURN: Status - ACPI status
518 *
519 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
520 * state.
521 *
522 ******************************************************************************/
523
524 ACPI_STATUS
525 AcpiGetSleepTypeData (
526 UINT8 SleepState,
527 UINT8 *SleepTypeA,
528 UINT8 *SleepTypeB)
529 {
530 ACPI_STATUS Status = AE_OK;
531 ACPI_EVALUATE_INFO *Info;
532
533
534 ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
535
536
537 /* Validate parameters */
538
539 if ((SleepState > ACPI_S_STATES_MAX) ||
540 !SleepTypeA ||
541 !SleepTypeB)
542 {
543 return_ACPI_STATUS (AE_BAD_PARAMETER);
544 }
545
546 /* Allocate the evaluation information block */
547
548 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
549 if (!Info)
550 {
551 return_ACPI_STATUS (AE_NO_MEMORY);
552 }
553
554 Info->Pathname = ACPI_CAST_PTR (char, AcpiGbl_SleepStateNames[SleepState]);
555
556 /* Evaluate the namespace object containing the values for this state */
557
558 Status = AcpiNsEvaluate (Info);
559 if (ACPI_FAILURE (Status))
560 {
561 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
562 "%s while evaluating SleepState [%s]\n",
563 AcpiFormatException (Status), Info->Pathname));
564
565 goto Cleanup;
566 }
567
568 /* Must have a return object */
569
570 if (!Info->ReturnObject)
571 {
572 ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
573 Info->Pathname));
574 Status = AE_NOT_EXIST;
575 }
576
577 /* It must be of type Package */
578
579 else if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
580 {
581 ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package"));
582 Status = AE_AML_OPERAND_TYPE;
583 }
584
585 /*
586 * The package must have at least two elements. NOTE (March 2005): This
587 * goes against the current ACPI spec which defines this object as a
588 * package with one encoded DWORD element. However, existing practice
589 * by BIOS vendors seems to be to have 2 or more elements, at least
590 * one per sleep type (A/B).
591 */
592 else if (Info->ReturnObject->Package.Count < 2)
593 {
594 ACPI_ERROR ((AE_INFO,
595 "Sleep State return package does not have at least two elements"));
596 Status = AE_AML_NO_OPERAND;
597 }
598
599 /* The first two elements must both be of type Integer */
600
601 else if (((Info->ReturnObject->Package.Elements[0])->Common.Type
602 != ACPI_TYPE_INTEGER) ||
603 ((Info->ReturnObject->Package.Elements[1])->Common.Type
604 != ACPI_TYPE_INTEGER))
605 {
606 ACPI_ERROR ((AE_INFO,
607 "Sleep State return package elements are not both Integers "
608 "(%s, %s)",
609 AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[0]),
610 AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[1])));
611 Status = AE_AML_OPERAND_TYPE;
612 }
613 else
614 {
615 /* Valid _Sx_ package size, type, and value */
616
617 *SleepTypeA = (UINT8)
618 (Info->ReturnObject->Package.Elements[0])->Integer.Value;
619 *SleepTypeB = (UINT8)
620 (Info->ReturnObject->Package.Elements[1])->Integer.Value;
621 }
622
623 if (ACPI_FAILURE (Status))
624 {
625 ACPI_EXCEPTION ((AE_INFO, Status,
626 "While evaluating SleepState [%s], bad Sleep object %p type %s",
627 Info->Pathname, Info->ReturnObject,
628 AcpiUtGetObjectTypeName (Info->ReturnObject)));
629 }
630
631 AcpiUtRemoveReference (Info->ReturnObject);
632
633 Cleanup:
634 ACPI_FREE (Info);
635 return_ACPI_STATUS (Status);
636 }
637
638 ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)
|
1 /******************************************************************************
2 *
3 * Module Name: hwxface - Public ACPICA hardware interfaces
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2014, 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 #define EXPORT_ACPI_INTERFACES
45
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "acnamesp.h"
49
50 #define _COMPONENT ACPI_HARDWARE
51 ACPI_MODULE_NAME ("hwxface")
52
53
54 /******************************************************************************
55 *
56 * FUNCTION: AcpiReset
57 *
58 * PARAMETERS: None
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
63 * support reset register in PCI config space, this must be
64 * handled separately.
65 *
75
76 ACPI_FUNCTION_TRACE (AcpiReset);
77
78
79 ResetReg = &AcpiGbl_FADT.ResetRegister;
80
81 /* Check if the reset register is supported */
82
83 if (!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) ||
84 !ResetReg->Address)
85 {
86 return_ACPI_STATUS (AE_NOT_EXIST);
87 }
88
89 if (ResetReg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
90 {
91 /*
92 * For I/O space, write directly to the OSL. This bypasses the port
93 * validation mechanism, which may block a valid write to the reset
94 * register.
95 *
96 * NOTE:
97 * The ACPI spec requires the reset register width to be 8, so we
98 * hardcode it here and ignore the FADT value. This maintains
99 * compatibility with other ACPI implementations that have allowed
100 * BIOS code with bad register width values to go unnoticed.
101 */
102 Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
103 AcpiGbl_FADT.ResetValue, ACPI_RESET_REGISTER_WIDTH);
104 }
105 else
106 {
107 /* Write the reset value to the reset register */
108
109 Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg);
110 }
111
112 return_ACPI_STATUS (Status);
113 }
114
115 ACPI_EXPORT_SYMBOL (AcpiReset)
116
117
118 /******************************************************************************
119 *
120 * FUNCTION: AcpiRead
121 *
122 * PARAMETERS: Value - Where the value is returned
123 * Reg - GAS register structure
124 *
125 * RETURN: Status
126 *
127 * DESCRIPTION: Read from either memory or IO space.
128 *
129 * LIMITATIONS: <These limitations also apply to AcpiWrite>
130 * BitWidth must be exactly 8, 16, 32, or 64.
131 * SpaceID must be SystemMemory or SystemIO.
132 * BitOffset and AccessWidth are currently ignored, as there has
133 * not been a need to implement these.
134 *
135 ******************************************************************************/
136
137 ACPI_STATUS
138 AcpiRead (
139 UINT64 *ReturnValue,
140 ACPI_GENERIC_ADDRESS *Reg)
141 {
142 UINT32 ValueLo;
143 UINT32 ValueHi;
144 UINT32 Width;
145 UINT64 Address;
146 ACPI_STATUS Status;
147
148
149 ACPI_FUNCTION_NAME (AcpiRead);
150
151
152 if (!ReturnValue)
153 {
154 return (AE_BAD_PARAMETER);
155 }
156
157 /* Validate contents of the GAS register. Allow 64-bit transfers */
158
159 Status = AcpiHwValidateRegister (Reg, 64, &Address);
160 if (ACPI_FAILURE (Status))
161 {
162 return (Status);
163 }
164
165 /*
166 * Two address spaces supported: Memory or I/O. PCI_Config is
167 * not supported here because the GAS structure is insufficient
168 */
169 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
170 {
171 Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
172 Address, ReturnValue, Reg->BitWidth);
173 if (ACPI_FAILURE (Status))
174 {
175 return (Status);
176 }
177 }
178 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
179 {
180 ValueLo = 0;
181 ValueHi = 0;
182
183 Width = Reg->BitWidth;
184 if (Width == 64)
185 {
186 Width = 32; /* Break into two 32-bit transfers */
187 }
188
189 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
190 Address, &ValueLo, Width);
191 if (ACPI_FAILURE (Status))
192 {
193 return (Status);
194 }
195
196 if (Reg->BitWidth == 64)
197 {
198 /* Read the top 32 bits */
199
200 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
201 (Address + 4), &ValueHi, 32);
202 if (ACPI_FAILURE (Status))
203 {
204 return (Status);
205 }
206 }
207
208 /* Set the return value only if status is AE_OK */
209
210 *ReturnValue = (ValueLo | ((UINT64) ValueHi << 32));
211 }
212
213 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
214 "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
215 ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
216 ACPI_FORMAT_UINT64 (Address),
217 AcpiUtGetRegionName (Reg->SpaceId)));
218
219 return (AE_OK);
220 }
221
222 ACPI_EXPORT_SYMBOL (AcpiRead)
223
224
225 /******************************************************************************
226 *
227 * FUNCTION: AcpiWrite
228 *
229 * PARAMETERS: Value - Value to be written
230 * Reg - GAS register structure
231 *
232 * RETURN: Status
233 *
234 * DESCRIPTION: Write to either memory or IO space.
235 *
236 ******************************************************************************/
237
238 ACPI_STATUS
239 AcpiWrite (
240 UINT64 Value,
241 ACPI_GENERIC_ADDRESS *Reg)
242 {
243 UINT32 Width;
244 UINT64 Address;
245 ACPI_STATUS Status;
246
247
248 ACPI_FUNCTION_NAME (AcpiWrite);
249
250
251 /* Validate contents of the GAS register. Allow 64-bit transfers */
252
253 Status = AcpiHwValidateRegister (Reg, 64, &Address);
254 if (ACPI_FAILURE (Status))
255 {
256 return (Status);
257 }
258
259 /*
260 * Two address spaces supported: Memory or IO. PCI_Config is
261 * not supported here because the GAS structure is insufficient
262 */
263 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
264 {
265 Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
266 Address, Value, Reg->BitWidth);
267 if (ACPI_FAILURE (Status))
268 {
269 return (Status);
270 }
271 }
272 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
273 {
274 Width = Reg->BitWidth;
275 if (Width == 64)
276 {
277 Width = 32; /* Break into two 32-bit transfers */
278 }
279
280 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
281 Address, ACPI_LODWORD (Value), Width);
282 if (ACPI_FAILURE (Status))
283 {
284 return (Status);
285 }
286
287 if (Reg->BitWidth == 64)
288 {
289 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
290 (Address + 4), ACPI_HIDWORD (Value), 32);
291 if (ACPI_FAILURE (Status))
292 {
293 return (Status);
294 }
295 }
296 }
297
298 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
299 "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n",
300 ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
301 ACPI_FORMAT_UINT64 (Address),
302 AcpiUtGetRegionName (Reg->SpaceId)));
303
304 return (Status);
305 }
306
307 ACPI_EXPORT_SYMBOL (AcpiWrite)
308
309
310 #if (!ACPI_REDUCED_HARDWARE)
311 /*******************************************************************************
312 *
313 * FUNCTION: AcpiReadBitRegister
314 *
315 * PARAMETERS: RegisterId - ID of ACPI Bit Register to access
316 * ReturnValue - Value that was read from the register,
317 * normalized to bit position zero.
318 *
319 * RETURN: Status and the value read from the specified Register. Value
320 * returned is normalized to bit0 (is shifted all the way right)
321 *
322 * DESCRIPTION: ACPI BitRegister read function. Does not acquire the HW lock.
323 *
324 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
325 * PM2 Control.
326 *
327 * Note: The hardware lock is not required when reading the ACPI bit registers
328 * since almost all of them are single bit and it does not matter that
329 * the parent hardware register can be split across two physical
330 * registers. The only multi-bit field is SLP_TYP in the PM1 control
369 Value = ((RegisterValue & BitRegInfo->AccessBitMask)
370 >> BitRegInfo->BitPosition);
371
372 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
373 "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
374 RegisterId, BitRegInfo->ParentRegister, RegisterValue, Value));
375
376 *ReturnValue = Value;
377 return_ACPI_STATUS (AE_OK);
378 }
379
380 ACPI_EXPORT_SYMBOL (AcpiReadBitRegister)
381
382
383 /*******************************************************************************
384 *
385 * FUNCTION: AcpiWriteBitRegister
386 *
387 * PARAMETERS: RegisterId - ID of ACPI Bit Register to access
388 * Value - Value to write to the register, in bit
389 * position zero. The bit is automatically
390 * shifted to the correct position.
391 *
392 * RETURN: Status
393 *
394 * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
395 * since most operations require a read/modify/write sequence.
396 *
397 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
398 * PM2 Control.
399 *
400 * Note that at this level, the fact that there may be actually two
401 * hardware registers (A and B - and B may not exist) is abstracted.
402 *
403 ******************************************************************************/
404
405 ACPI_STATUS
406 AcpiWriteBitRegister (
407 UINT32 RegisterId,
408 UINT32 Value)
409 {
473 if (RegisterValue)
474 {
475 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
476 RegisterValue);
477 }
478 }
479
480 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
481 "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
482 RegisterId, BitRegInfo->ParentRegister, Value, RegisterValue));
483
484
485 UnlockAndExit:
486
487 AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
488 return_ACPI_STATUS (Status);
489 }
490
491 ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister)
492
493 #endif /* !ACPI_REDUCED_HARDWARE */
494
495
496 /*******************************************************************************
497 *
498 * FUNCTION: AcpiGetSleepTypeData
499 *
500 * PARAMETERS: SleepState - Numeric sleep state
501 * *SleepTypeA - Where SLP_TYPa is returned
502 * *SleepTypeB - Where SLP_TYPb is returned
503 *
504 * RETURN: Status
505 *
506 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested
507 * sleep state via the appropriate \_Sx object.
508 *
509 * The sleep state package returned from the corresponding \_Sx_ object
510 * must contain at least one integer.
511 *
512 * March 2005:
513 * Added support for a package that contains two integers. This
514 * goes against the ACPI specification which defines this object as a
515 * package with one encoded DWORD integer. However, existing practice
516 * by many BIOS vendors is to return a package with 2 or more integer
517 * elements, at least one per sleep type (A/B).
518 *
519 * January 2013:
520 * Therefore, we must be prepared to accept a package with either a
521 * single integer or multiple integers.
522 *
523 * The single integer DWORD format is as follows:
524 * BYTE 0 - Value for the PM1A SLP_TYP register
525 * BYTE 1 - Value for the PM1B SLP_TYP register
526 * BYTE 2-3 - Reserved
527 *
528 * The dual integer format is as follows:
529 * Integer 0 - Value for the PM1A SLP_TYP register
530 * Integer 1 - Value for the PM1A SLP_TYP register
531 *
532 ******************************************************************************/
533
534 ACPI_STATUS
535 AcpiGetSleepTypeData (
536 UINT8 SleepState,
537 UINT8 *SleepTypeA,
538 UINT8 *SleepTypeB)
539 {
540 ACPI_STATUS Status;
541 ACPI_EVALUATE_INFO *Info;
542 ACPI_OPERAND_OBJECT **Elements;
543
544
545 ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
546
547
548 /* Validate parameters */
549
550 if ((SleepState > ACPI_S_STATES_MAX) ||
551 !SleepTypeA || !SleepTypeB)
552 {
553 return_ACPI_STATUS (AE_BAD_PARAMETER);
554 }
555
556 /* Allocate the evaluation information block */
557
558 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
559 if (!Info)
560 {
561 return_ACPI_STATUS (AE_NO_MEMORY);
562 }
563
564 /*
565 * Evaluate the \_Sx namespace object containing the register values
566 * for this state
567 */
568 Info->RelativePathname = ACPI_CAST_PTR (
569 char, AcpiGbl_SleepStateNames[SleepState]);
570 Status = AcpiNsEvaluate (Info);
571 if (ACPI_FAILURE (Status))
572 {
573 goto Cleanup;
574 }
575
576 /* Must have a return object */
577
578 if (!Info->ReturnObject)
579 {
580 ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
581 Info->RelativePathname));
582 Status = AE_AML_NO_RETURN_VALUE;
583 goto Cleanup;
584 }
585
586 /* Return object must be of type Package */
587
588 if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
589 {
590 ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package"));
591 Status = AE_AML_OPERAND_TYPE;
592 goto Cleanup1;
593 }
594
595 /*
596 * Any warnings about the package length or the object types have
597 * already been issued by the predefined name module -- there is no
598 * need to repeat them here.
599 */
600 Elements = Info->ReturnObject->Package.Elements;
601 switch (Info->ReturnObject->Package.Count)
602 {
603 case 0:
604
605 Status = AE_AML_PACKAGE_LIMIT;
606 break;
607
608 case 1:
609
610 if (Elements[0]->Common.Type != ACPI_TYPE_INTEGER)
611 {
612 Status = AE_AML_OPERAND_TYPE;
613 break;
614 }
615
616 /* A valid _Sx_ package with one integer */
617
618 *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
619 *SleepTypeB = (UINT8) (Elements[0]->Integer.Value >> 8);
620 break;
621
622 case 2:
623 default:
624
625 if ((Elements[0]->Common.Type != ACPI_TYPE_INTEGER) ||
626 (Elements[1]->Common.Type != ACPI_TYPE_INTEGER))
627 {
628 Status = AE_AML_OPERAND_TYPE;
629 break;
630 }
631
632 /* A valid _Sx_ package with two integers */
633
634 *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
635 *SleepTypeB = (UINT8) Elements[1]->Integer.Value;
636 break;
637 }
638
639 Cleanup1:
640 AcpiUtRemoveReference (Info->ReturnObject);
641
642 Cleanup:
643 if (ACPI_FAILURE (Status))
644 {
645 ACPI_EXCEPTION ((AE_INFO, Status,
646 "While evaluating Sleep State [%s]", Info->RelativePathname));
647 }
648
649 ACPI_FREE (Info);
650 return_ACPI_STATUS (Status);
651 }
652
653 ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)
|