Update ACPI build wrappers to use new ACPICA(20050309) code.
[dragonfly.git] / sys / contrib / dev / acpica-unix-20050211 / hardware / hwregs.c
1
2 /*******************************************************************************
3  *
4  * Module Name: hwregs - Read/write access functions for the various ACPI
5  *                       control and status registers.
6  *              $Revision: 163 $
7  *
8  ******************************************************************************/
9
10 /******************************************************************************
11  *
12  * 1. Copyright Notice
13  *
14  * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
15  * All rights reserved.
16  *
17  * 2. License
18  *
19  * 2.1. This is your license from Intel Corp. under its intellectual property
20  * rights.  You may have additional license terms from the party that provided
21  * you this software, covering your right to use that party's intellectual
22  * property rights.
23  *
24  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
25  * copy of the source code appearing in this file ("Covered Code") an
26  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
27  * base code distributed originally by Intel ("Original Intel Code") to copy,
28  * make derivatives, distribute, use and display any portion of the Covered
29  * Code in any form, with the right to sublicense such rights; and
30  *
31  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
32  * license (with the right to sublicense), under only those claims of Intel
33  * patents that are infringed by the Original Intel Code, to make, use, sell,
34  * offer to sell, and import the Covered Code and derivative works thereof
35  * solely to the minimum extent necessary to exercise the above copyright
36  * license, and in no event shall the patent license extend to any additions
37  * to or modifications of the Original Intel Code.  No other license or right
38  * is granted directly or by implication, estoppel or otherwise;
39  *
40  * The above copyright and patent license is granted only if the following
41  * conditions are met:
42  *
43  * 3. Conditions
44  *
45  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
46  * Redistribution of source code of any substantial portion of the Covered
47  * Code or modification with rights to further distribute source must include
48  * the above Copyright Notice, the above License, this list of Conditions,
49  * and the following Disclaimer and Export Compliance provision.  In addition,
50  * Licensee must cause all Covered Code to which Licensee contributes to
51  * contain a file documenting the changes Licensee made to create that Covered
52  * Code and the date of any change.  Licensee must include in that file the
53  * documentation of any changes made by any predecessor Licensee.  Licensee
54  * must include a prominent statement that the modification is derived,
55  * directly or indirectly, from Original Intel Code.
56  *
57  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
58  * Redistribution of source code of any substantial portion of the Covered
59  * Code or modification without rights to further distribute source must
60  * include the following Disclaimer and Export Compliance provision in the
61  * documentation and/or other materials provided with distribution.  In
62  * addition, Licensee may not authorize further sublicense of source of any
63  * portion of the Covered Code, and must include terms to the effect that the
64  * license from Licensee to its licensee is limited to the intellectual
65  * property embodied in the software Licensee provides to its licensee, and
66  * not to intellectual property embodied in modifications its licensee may
67  * make.
68  *
69  * 3.3. Redistribution of Executable. Redistribution in executable form of any
70  * substantial portion of the Covered Code or modification must reproduce the
71  * above Copyright Notice, and the following Disclaimer and Export Compliance
72  * provision in the documentation and/or other materials provided with the
73  * distribution.
74  *
75  * 3.4. Intel retains all right, title, and interest in and to the Original
76  * Intel Code.
77  *
78  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
79  * Intel shall be used in advertising or otherwise to promote the sale, use or
80  * other dealings in products derived from or relating to the Covered Code
81  * without prior written authorization from Intel.
82  *
83  * 4. Disclaimer and Export Compliance
84  *
85  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
86  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
87  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
88  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
89  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
90  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91  * PARTICULAR PURPOSE.
92  *
93  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
94  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
95  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
96  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
97  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
98  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
99  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100  * LIMITED REMEDY.
101  *
102  * 4.3. Licensee shall not export, either directly or indirectly, any of this
103  * software or system incorporating such software without first obtaining any
104  * required license or other approval from the U. S. Department of Commerce or
105  * any other agency or department of the United States Government.  In the
106  * event Licensee exports any such software from the United States or
107  * re-exports any such software from a foreign destination, Licensee shall
108  * ensure that the distribution and export/re-export of the software is in
109  * compliance with all laws, regulations, orders, or other restrictions of the
110  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
111  * any of its subsidiaries will export/re-export any technical data, process,
112  * software, or service, directly or indirectly, to any country for which the
113  * United States government or any agency thereof requires an export license,
114  * other governmental approval, or letter of assurance, without first obtaining
115  * such license, approval or letter.
116  *
117  *****************************************************************************/
118
119 #define __HWREGS_C__
120
121 #include "acpi.h"
122 #include "acnamesp.h"
123 #include "acevents.h"
124
125 #define _COMPONENT          ACPI_HARDWARE
126         ACPI_MODULE_NAME    ("hwregs")
127
128
129 /*******************************************************************************
130  *
131  * FUNCTION:    AcpiHwClearAcpiStatus
132  *
133  * PARAMETERS:  Flags           - Lock the hardware or not
134  *
135  * RETURN:      none
136  *
137  * DESCRIPTION: Clears all fixed and general purpose status bits
138  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
139  *
140  ******************************************************************************/
141
142 ACPI_STATUS
143 AcpiHwClearAcpiStatus (
144     UINT32                  Flags)
145 {
146     ACPI_STATUS             Status;
147
148
149     ACPI_FUNCTION_TRACE ("HwClearAcpiStatus");
150
151
152     ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
153         ACPI_BITMASK_ALL_FIXED_STATUS,
154         (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address)));
155
156     if (Flags & ACPI_MTX_LOCK)
157     {
158         Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
159         if (ACPI_FAILURE (Status))
160         {
161             return_ACPI_STATUS (Status);
162         }
163     }
164
165     Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
166                     ACPI_BITMASK_ALL_FIXED_STATUS);
167     if (ACPI_FAILURE (Status))
168     {
169         goto UnlockAndExit;
170     }
171
172     /* Clear the fixed events */
173
174     if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address))
175     {
176         Status = AcpiHwLowLevelWrite (16, ACPI_BITMASK_ALL_FIXED_STATUS,
177                     &AcpiGbl_FADT->XPm1bEvtBlk);
178         if (ACPI_FAILURE (Status))
179         {
180             goto UnlockAndExit;
181         }
182     }
183
184     /* Clear the GPE Bits in all GPE registers in all GPE blocks */
185
186     Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, ACPI_ISR);
187
188 UnlockAndExit:
189     if (Flags & ACPI_MTX_LOCK)
190     {
191         (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
192     }
193     return_ACPI_STATUS (Status);
194 }
195
196
197 /*******************************************************************************
198  *
199  * FUNCTION:    AcpiGetSleepTypeData
200  *
201  * PARAMETERS:  SleepState          - Numeric sleep state
202  *              *SleepTypeA         - Where SLP_TYPa is returned
203  *              *SleepTypeB         - Where SLP_TYPb is returned
204  *
205  * RETURN:      Status - ACPI status
206  *
207  * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
208  *              state.
209  *
210  ******************************************************************************/
211
212 ACPI_STATUS
213 AcpiGetSleepTypeData (
214     UINT8                   SleepState,
215     UINT8                   *SleepTypeA,
216     UINT8                   *SleepTypeB)
217 {
218     ACPI_STATUS             Status = AE_OK;
219     ACPI_PARAMETER_INFO     Info;
220
221
222     ACPI_FUNCTION_TRACE ("AcpiGetSleepTypeData");
223
224
225     /*
226      * Validate parameters
227      */
228     if ((SleepState > ACPI_S_STATES_MAX) ||
229         !SleepTypeA || !SleepTypeB)
230     {
231         return_ACPI_STATUS (AE_BAD_PARAMETER);
232     }
233
234     /*
235      * Evaluate the namespace object containing the values for this state
236      */
237     Info.Parameters = NULL;
238     Status = AcpiNsEvaluateByName ((char *) AcpiGbl_SleepStateNames[SleepState],
239                     &Info);
240     if (ACPI_FAILURE (Status))
241     {
242         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating SleepState [%s]\n",
243             AcpiFormatException (Status), AcpiGbl_SleepStateNames[SleepState]));
244
245         return_ACPI_STATUS (Status);
246     }
247
248     /* Must have a return object */
249
250     if (!Info.ReturnObject)
251     {
252         ACPI_REPORT_ERROR (("Missing Sleep State object\n"));
253         Status = AE_NOT_EXIST;
254     }
255
256     /* It must be of type Package */
257
258     else if (ACPI_GET_OBJECT_TYPE (Info.ReturnObject) != ACPI_TYPE_PACKAGE)
259     {
260         ACPI_REPORT_ERROR (("Sleep State object not a Package\n"));
261         Status = AE_AML_OPERAND_TYPE;
262     }
263
264     /* The package must have at least two elements */
265
266     else if (Info.ReturnObject->Package.Count < 2)
267     {
268         ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
269         Status = AE_AML_NO_OPERAND;
270     }
271
272     /* The first two elements must both be of type Integer */
273
274     else if ((ACPI_GET_OBJECT_TYPE (Info.ReturnObject->Package.Elements[0]) != ACPI_TYPE_INTEGER) ||
275              (ACPI_GET_OBJECT_TYPE (Info.ReturnObject->Package.Elements[1]) != ACPI_TYPE_INTEGER))
276     {
277         ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n",
278             AcpiUtGetObjectTypeName (Info.ReturnObject->Package.Elements[0]),
279             AcpiUtGetObjectTypeName (Info.ReturnObject->Package.Elements[1])));
280         Status = AE_AML_OPERAND_TYPE;
281     }
282     else
283     {
284         /*
285          * Valid _Sx_ package size, type, and value
286          */
287         *SleepTypeA = (UINT8) (Info.ReturnObject->Package.Elements[0])->Integer.Value;
288         *SleepTypeB = (UINT8) (Info.ReturnObject->Package.Elements[1])->Integer.Value;
289     }
290
291     if (ACPI_FAILURE (Status))
292     {
293         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
294             "While evaluating SleepState [%s], bad Sleep object %p type %s\n",
295             AcpiGbl_SleepStateNames[SleepState], Info.ReturnObject,
296             AcpiUtGetObjectTypeName (Info.ReturnObject)));
297     }
298
299     AcpiUtRemoveReference (Info.ReturnObject);
300     return_ACPI_STATUS (Status);
301 }
302
303
304 /*******************************************************************************
305  *
306  * FUNCTION:    AcpiHwGetRegisterBitMask
307  *
308  * PARAMETERS:  RegisterId          - Index of ACPI Register to access
309  *
310  * RETURN:      The bit mask to be used when accessing the register
311  *
312  * DESCRIPTION: Map RegisterId into a register bit mask.
313  *
314  ******************************************************************************/
315
316 ACPI_BIT_REGISTER_INFO *
317 AcpiHwGetBitRegisterInfo (
318     UINT32                  RegisterId)
319 {
320     ACPI_FUNCTION_NAME ("HwGetBitRegisterInfo");
321
322
323     if (RegisterId > ACPI_BITREG_MAX)
324     {
325         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid BitRegister ID: %X\n", RegisterId));
326         return (NULL);
327     }
328
329     return (&AcpiGbl_BitRegisterInfo[RegisterId]);
330 }
331
332
333 /*******************************************************************************
334  *
335  * FUNCTION:    AcpiGetRegister
336  *
337  * PARAMETERS:  RegisterId      - ID of ACPI BitRegister to access
338  *              ReturnValue     - Value that was read from the register
339  *              Flags           - Lock the hardware or not
340  *
341  * RETURN:      Status and the value read from specified Register.  Value
342  *              returned is normalized to bit0 (is shifted all the way right)
343  *
344  * DESCRIPTION: ACPI BitRegister read function.
345  *
346  ******************************************************************************/
347
348 ACPI_STATUS
349 AcpiGetRegister (
350     UINT32                  RegisterId,
351     UINT32                  *ReturnValue,
352     UINT32                  Flags)
353 {
354     UINT32                  RegisterValue = 0;
355     ACPI_BIT_REGISTER_INFO  *BitRegInfo;
356     ACPI_STATUS             Status;
357
358
359     ACPI_FUNCTION_TRACE ("AcpiGetRegister");
360
361
362     /* Get the info structure corresponding to the requested ACPI Register */
363
364     BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
365     if (!BitRegInfo)
366     {
367         return_ACPI_STATUS (AE_BAD_PARAMETER);
368     }
369
370     if (Flags & ACPI_MTX_LOCK)
371     {
372         Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
373         if (ACPI_FAILURE (Status))
374         {
375             return_ACPI_STATUS (Status);
376         }
377     }
378
379     /* Read from the register */
380
381     Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
382                     BitRegInfo->ParentRegister, &RegisterValue);
383
384     if (Flags & ACPI_MTX_LOCK)
385     {
386         (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
387     }
388
389     if (ACPI_SUCCESS (Status))
390     {
391         /* Normalize the value that was read */
392
393         RegisterValue = ((RegisterValue & BitRegInfo->AccessBitMask)
394                             >> BitRegInfo->BitPosition);
395
396         *ReturnValue = RegisterValue;
397
398         ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read value %8.8X register %X\n",
399                 RegisterValue, BitRegInfo->ParentRegister));
400     }
401
402     return_ACPI_STATUS (Status);
403 }
404
405
406 /*******************************************************************************
407  *
408  * FUNCTION:    AcpiSetRegister
409  *
410  * PARAMETERS:  RegisterId      - ID of ACPI BitRegister to access
411  *              Value           - (only used on write) value to write to the
412  *                                Register, NOT pre-normalized to the bit pos
413  *              Flags           - Lock the hardware or not
414  *
415  * RETURN:      Status
416  *
417  * DESCRIPTION: ACPI Bit Register write function.
418  *
419  ******************************************************************************/
420
421 ACPI_STATUS
422 AcpiSetRegister (
423     UINT32                  RegisterId,
424     UINT32                  Value,
425     UINT32                  Flags)
426 {
427     UINT32                  RegisterValue = 0;
428     ACPI_BIT_REGISTER_INFO  *BitRegInfo;
429     ACPI_STATUS             Status;
430
431
432     ACPI_FUNCTION_TRACE_U32 ("AcpiSetRegister", RegisterId);
433
434
435     /* Get the info structure corresponding to the requested ACPI Register */
436
437     BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
438     if (!BitRegInfo)
439     {
440         ACPI_REPORT_ERROR (("Bad ACPI HW RegisterId: %X\n", RegisterId));
441         return_ACPI_STATUS (AE_BAD_PARAMETER);
442     }
443
444     if (Flags & ACPI_MTX_LOCK)
445     {
446         Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
447         if (ACPI_FAILURE (Status))
448         {
449             return_ACPI_STATUS (Status);
450         }
451     }
452
453     /* Always do a register read first so we can insert the new bits  */
454
455     Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
456                     BitRegInfo->ParentRegister, &RegisterValue);
457     if (ACPI_FAILURE (Status))
458     {
459         goto UnlockAndExit;
460     }
461
462     /*
463      * Decode the Register ID
464      * Register ID = [Register block ID] | [bit ID]
465      *
466      * Check bit ID to fine locate Register offset.
467      * Check Mask to determine Register offset, and then read-write.
468      */
469     switch (BitRegInfo->ParentRegister)
470     {
471     case ACPI_REGISTER_PM1_STATUS:
472
473         /*
474          * Status Registers are different from the rest.  Clear by
475          * writing 1, and writing 0 has no effect.  So, the only relevant
476          * information is the single bit we're interested in, all others should
477          * be written as 0 so they will be left unchanged.
478          */
479         Value = ACPI_REGISTER_PREPARE_BITS (Value,
480                     BitRegInfo->BitPosition, BitRegInfo->AccessBitMask);
481         if (Value)
482         {
483             Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
484                         ACPI_REGISTER_PM1_STATUS, (UINT16) Value);
485             RegisterValue = 0;
486         }
487         break;
488
489
490     case ACPI_REGISTER_PM1_ENABLE:
491
492         ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
493                 BitRegInfo->AccessBitMask, Value);
494
495         Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
496                         ACPI_REGISTER_PM1_ENABLE, (UINT16) RegisterValue);
497         break;
498
499
500     case ACPI_REGISTER_PM1_CONTROL:
501
502         /*
503          * Write the PM1 Control register.
504          * Note that at this level, the fact that there are actually TWO
505          * registers (A and B - and B may not exist) is abstracted.
506          */
507         ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", RegisterValue));
508
509         ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
510                 BitRegInfo->AccessBitMask, Value);
511
512         Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
513                         ACPI_REGISTER_PM1_CONTROL, (UINT16) RegisterValue);
514         break;
515
516
517     case ACPI_REGISTER_PM2_CONTROL:
518
519         Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
520                     ACPI_REGISTER_PM2_CONTROL, &RegisterValue);
521         if (ACPI_FAILURE (Status))
522         {
523             goto UnlockAndExit;
524         }
525
526         ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n",
527             RegisterValue,
528             ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address))));
529
530         ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
531                 BitRegInfo->AccessBitMask, Value);
532
533         ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n",
534             RegisterValue,
535             ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address))));
536
537         Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
538                             ACPI_REGISTER_PM2_CONTROL, (UINT8) (RegisterValue));
539         break;
540
541
542     default:
543         break;
544     }
545
546
547 UnlockAndExit:
548
549     if (Flags & ACPI_MTX_LOCK)
550     {
551         (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
552     }
553
554     /* Normalize the value that was read */
555
556     ACPI_DEBUG_EXEC (RegisterValue = ((RegisterValue & BitRegInfo->AccessBitMask) >> BitRegInfo->BitPosition));
557
558     ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Set bits: %8.8X actual %8.8X register %X\n",
559             Value, RegisterValue, BitRegInfo->ParentRegister));
560     return_ACPI_STATUS (Status);
561 }
562
563
564 /******************************************************************************
565  *
566  * FUNCTION:    AcpiHwRegisterRead
567  *
568  * PARAMETERS:  UseLock             - Mutex hw access
569  *              RegisterId          - RegisterID + Offset
570  *              ReturnValue         - Value that was read from the register
571  *
572  * RETURN:      Status and the value read.
573  *
574  * DESCRIPTION: Acpi register read function.  Registers are read at the
575  *              given offset.
576  *
577  ******************************************************************************/
578
579 ACPI_STATUS
580 AcpiHwRegisterRead (
581     BOOLEAN                 UseLock,
582     UINT32                  RegisterId,
583     UINT32                  *ReturnValue)
584 {
585     UINT32                  Value1 = 0;
586     UINT32                  Value2 = 0;
587     ACPI_STATUS             Status;
588
589
590     ACPI_FUNCTION_TRACE ("HwRegisterRead");
591
592
593     if (ACPI_MTX_LOCK == UseLock)
594     {
595         Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
596         if (ACPI_FAILURE (Status))
597         {
598             return_ACPI_STATUS (Status);
599         }
600     }
601
602     switch (RegisterId)
603     {
604     case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
605
606         Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aEvtBlk);
607         if (ACPI_FAILURE (Status))
608         {
609             goto UnlockAndExit;
610         }
611
612         /* PM1B is optional */
613
614         Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bEvtBlk);
615         Value1 |= Value2;
616         break;
617
618
619     case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access */
620
621         Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_XPm1aEnable);
622         if (ACPI_FAILURE (Status))
623         {
624             goto UnlockAndExit;
625         }
626
627         /* PM1B is optional */
628
629         Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_XPm1bEnable);
630         Value1 |= Value2;
631         break;
632
633
634     case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
635
636         Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aCntBlk);
637         if (ACPI_FAILURE (Status))
638         {
639             goto UnlockAndExit;
640         }
641
642         Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bCntBlk);
643         Value1 |= Value2;
644         break;
645
646
647     case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
648
649         Status = AcpiHwLowLevelRead (8, &Value1, &AcpiGbl_FADT->XPm2CntBlk);
650         break;
651
652
653     case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
654
655         Status = AcpiHwLowLevelRead (32, &Value1, &AcpiGbl_FADT->XPmTmrBlk);
656         break;
657
658     case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
659
660         Status = AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value1, 8);
661         break;
662
663     default:
664         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", RegisterId));
665         Status = AE_BAD_PARAMETER;
666         break;
667     }
668
669 UnlockAndExit:
670     if (ACPI_MTX_LOCK == UseLock)
671     {
672         (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
673     }
674
675     if (ACPI_SUCCESS (Status))
676     {
677         *ReturnValue = Value1;
678     }
679
680     return_ACPI_STATUS (Status);
681 }
682
683
684 /******************************************************************************
685  *
686  * FUNCTION:    AcpiHwRegisterWrite
687  *
688  * PARAMETERS:  UseLock             - Mutex hw access
689  *              RegisterId          - RegisterID + Offset
690  *              Value               - The value to write
691  *
692  * RETURN:      Status
693  *
694  * DESCRIPTION: Acpi register Write function.  Registers are written at the
695  *              given offset.
696  *
697  ******************************************************************************/
698
699 ACPI_STATUS
700 AcpiHwRegisterWrite (
701     BOOLEAN                 UseLock,
702     UINT32                  RegisterId,
703     UINT32                  Value)
704 {
705     ACPI_STATUS             Status;
706
707
708     ACPI_FUNCTION_TRACE ("HwRegisterWrite");
709
710
711     if (ACPI_MTX_LOCK == UseLock)
712     {
713         Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
714         if (ACPI_FAILURE (Status))
715         {
716             return_ACPI_STATUS (Status);
717         }
718     }
719
720     switch (RegisterId)
721     {
722     case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
723
724         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk);
725         if (ACPI_FAILURE (Status))
726         {
727             goto UnlockAndExit;
728         }
729
730         /* PM1B is optional */
731
732         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk);
733         break;
734
735
736     case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access*/
737
738         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_XPm1aEnable);
739         if (ACPI_FAILURE (Status))
740         {
741             goto UnlockAndExit;
742         }
743
744         /* PM1B is optional */
745
746         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_XPm1bEnable);
747         break;
748
749
750     case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
751
752         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk);
753         if (ACPI_FAILURE (Status))
754         {
755             goto UnlockAndExit;
756         }
757
758         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk);
759         break;
760
761
762     case ACPI_REGISTER_PM1A_CONTROL:         /* 16-bit access */
763
764         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk);
765         break;
766
767
768     case ACPI_REGISTER_PM1B_CONTROL:         /* 16-bit access */
769
770         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk);
771         break;
772
773
774     case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
775
776         Status = AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk);
777         break;
778
779
780     case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
781
782         Status = AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk);
783         break;
784
785
786     case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
787
788         /* SMI_CMD is currently always in IO space */
789
790         Status = AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, Value, 8);
791         break;
792
793
794     default:
795         Status = AE_BAD_PARAMETER;
796         break;
797     }
798
799 UnlockAndExit:
800     if (ACPI_MTX_LOCK == UseLock)
801     {
802         (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
803     }
804
805     return_ACPI_STATUS (Status);
806 }
807
808
809 /******************************************************************************
810  *
811  * FUNCTION:    AcpiHwLowLevelRead
812  *
813  * PARAMETERS:  Width               - 8, 16, or 32
814  *              Value               - Where the value is returned
815  *              Reg                 - GAS register structure
816  *
817  * RETURN:      Status
818  *
819  * DESCRIPTION: Read from either memory or IO space.
820  *
821  ******************************************************************************/
822
823 ACPI_STATUS
824 AcpiHwLowLevelRead (
825     UINT32                  Width,
826     UINT32                  *Value,
827     ACPI_GENERIC_ADDRESS    *Reg)
828 {
829     UINT64                  Address;
830     ACPI_STATUS             Status;
831
832
833     ACPI_FUNCTION_NAME ("HwLowLevelRead");
834
835
836     /*
837      * Must have a valid pointer to a GAS structure, and
838      * a non-zero address within. However, don't return an error
839      * because the PM1A/B code must not fail if B isn't present.
840      */
841     if (!Reg)
842     {
843         return (AE_OK);
844     }
845
846     /* Get a local copy of the address.  Handles possible alignment issues */
847
848     ACPI_MOVE_64_TO_64 (&Address, &Reg->Address);
849     if (!ACPI_VALID_ADDRESS (Address))
850     {
851         return (AE_OK);
852     }
853     *Value = 0;
854
855     /*
856      * Two address spaces supported: Memory or IO.
857      * PCI_Config is not supported here because the GAS struct is insufficient
858      */
859     switch (Reg->AddressSpaceId)
860     {
861     case ACPI_ADR_SPACE_SYSTEM_MEMORY:
862
863         Status = AcpiOsReadMemory (
864                     (ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (Address),
865                     Value, Width);
866         break;
867
868
869     case ACPI_ADR_SPACE_SYSTEM_IO:
870
871         Status = AcpiOsReadPort ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (Address),
872                     Value, Width);
873         break;
874
875
876     default:
877         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
878             "Unsupported address space: %X\n", Reg->AddressSpaceId));
879         return (AE_BAD_PARAMETER);
880     }
881
882     ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
883             *Value, Width,
884             ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS (Address)),
885             AcpiUtGetRegionName (Reg->AddressSpaceId)));
886
887     return (Status);
888 }
889
890
891 /******************************************************************************
892  *
893  * FUNCTION:    AcpiHwLowLevelWrite
894  *
895  * PARAMETERS:  Width               - 8, 16, or 32
896  *              Value               - To be written
897  *              Reg                 - GAS register structure
898  *
899  * RETURN:      Status
900  *
901  * DESCRIPTION: Write to either memory or IO space.
902  *
903  ******************************************************************************/
904
905 ACPI_STATUS
906 AcpiHwLowLevelWrite (
907     UINT32                  Width,
908     UINT32                  Value,
909     ACPI_GENERIC_ADDRESS    *Reg)
910 {
911     UINT64                  Address;
912     ACPI_STATUS             Status;
913
914
915     ACPI_FUNCTION_NAME ("HwLowLevelWrite");
916
917
918     /*
919      * Must have a valid pointer to a GAS structure, and
920      * a non-zero address within. However, don't return an error
921      * because the PM1A/B code must not fail if B isn't present.
922      */
923     if (!Reg)
924     {
925         return (AE_OK);
926     }
927
928     /* Get a local copy of the address.  Handles possible alignment issues */
929
930     ACPI_MOVE_64_TO_64 (&Address, &Reg->Address);
931     if (!ACPI_VALID_ADDRESS (Address))
932     {
933         return (AE_OK);
934     }
935
936     /*
937      * Two address spaces supported: Memory or IO.
938      * PCI_Config is not supported here because the GAS struct is insufficient
939      */
940     switch (Reg->AddressSpaceId)
941     {
942     case ACPI_ADR_SPACE_SYSTEM_MEMORY:
943
944         Status = AcpiOsWriteMemory (
945                     (ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (Address),
946                     Value, Width);
947         break;
948
949
950     case ACPI_ADR_SPACE_SYSTEM_IO:
951
952         Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (Address),
953                     Value, Width);
954         break;
955
956
957     default:
958         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
959             "Unsupported address space: %X\n", Reg->AddressSpaceId));
960         return (AE_BAD_PARAMETER);
961     }
962
963     ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
964             Value, Width,
965             ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS (Address)),
966             AcpiUtGetRegionName (Reg->AddressSpaceId)));
967
968     return (Status);
969 }