Raise WARNS to 6:
[dragonfly.git] / sys / contrib / dev / acpica / hwregs.c
1 /* $DragonFly: src/sys/contrib/dev/acpica/Attic/hwregs.c,v 1.2 2004/06/02 11:46:11 joerg Exp $                                                               */
2 /*******************************************************************************
3  *
4  * Module Name: hwregs - Read/write access functions for the various ACPI
5  *                       control and status registers.
6  *              $Revision: 142 $
7  *
8  ******************************************************************************/
9
10 /******************************************************************************
11  *
12  * 1. Copyright Notice
13  *
14  * Some or all of this work - Copyright (c) 1999 - 2003, 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
124 #define _COMPONENT          ACPI_HARDWARE
125         ACPI_MODULE_NAME    ("hwregs")
126
127
128 /*******************************************************************************
129  *
130  * FUNCTION:    AcpiHwClearAcpiStatus
131  *
132  * PARAMETERS:  none
133  *
134  * RETURN:      none
135  *
136  * DESCRIPTION: Clears all fixed and general purpose status bits
137  *
138  ******************************************************************************/
139
140 ACPI_STATUS
141 AcpiHwClearAcpiStatus (void)
142 {
143     ACPI_NATIVE_UINT        i;
144     ACPI_STATUS             Status;
145     ACPI_GPE_BLOCK_INFO     *GpeBlock;
146
147
148     ACPI_FUNCTION_TRACE ("HwClearAcpiStatus");
149
150
151     ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
152         ACPI_BITMASK_ALL_FIXED_STATUS,
153         (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address)));
154
155
156     Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
157     if (ACPI_FAILURE (Status))
158     {
159         return_ACPI_STATUS (Status);
160     }
161
162     Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
163                     ACPI_BITMASK_ALL_FIXED_STATUS);
164     if (ACPI_FAILURE (Status))
165     {
166         goto UnlockAndExit;
167     }
168
169     /* Clear the fixed events */
170
171     if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address))
172     {
173         Status = AcpiHwLowLevelWrite (16, ACPI_BITMASK_ALL_FIXED_STATUS,
174                     &AcpiGbl_FADT->XPm1bEvtBlk, 0);
175         if (ACPI_FAILURE (Status))
176         {
177             goto UnlockAndExit;
178         }
179     }
180
181     /* Clear the GPE Bits in all GPE registers in all GPE blocks */
182
183     GpeBlock = AcpiGbl_GpeBlockListHead;
184     while (GpeBlock)
185     {
186         for (i = 0; i < GpeBlock->RegisterCount; i++)
187         {
188             Status = AcpiHwLowLevelWrite (8, 0xFF,
189                         &GpeBlock->RegisterInfo[i].StatusAddress, (UINT32) 0);
190             if (ACPI_FAILURE (Status))
191             {
192                 goto UnlockAndExit;
193             }
194         }
195
196         GpeBlock = GpeBlock->Next;
197     }
198
199 UnlockAndExit:
200     (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
201     return_ACPI_STATUS (Status);
202 }
203
204
205 /*******************************************************************************
206  *
207  * FUNCTION:    AcpiGetSleepTypeData
208  *
209  * PARAMETERS:  SleepState          - Numeric sleep state
210  *              *SleepTypeA         - Where SLP_TYPa is returned
211  *              *SleepTypeB         - Where SLP_TYPb is returned
212  *
213  * RETURN:      Status - ACPI status
214  *
215  * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
216  *              state.
217  *
218  ******************************************************************************/
219
220 ACPI_STATUS
221 AcpiGetSleepTypeData (
222     UINT8                   SleepState,
223     UINT8                   *SleepTypeA,
224     UINT8                   *SleepTypeB)
225 {
226     ACPI_STATUS             Status = AE_OK;
227     ACPI_OPERAND_OBJECT     *ObjDesc;
228
229
230     ACPI_FUNCTION_TRACE ("AcpiGetSleepTypeData");
231
232
233     /*
234      * Validate parameters
235      */
236     if ((SleepState > ACPI_S_STATES_MAX) ||
237         !SleepTypeA || !SleepTypeB)
238     {
239         return_ACPI_STATUS (AE_BAD_PARAMETER);
240     }
241
242     /*
243      * Evaluate the namespace object containing the values for this state
244      */
245     Status = AcpiNsEvaluateByName (
246         __DECONST(char *, AcpiGbl_DbSleepStates[SleepState]), NULL, &ObjDesc);
247     if (ACPI_FAILURE (Status))
248     {
249         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating SleepState [%s]\n",
250             AcpiFormatException (Status), AcpiGbl_DbSleepStates[SleepState]));
251
252         return_ACPI_STATUS (Status);
253     }
254
255     /* Must have a return object */
256
257     if (!ObjDesc)
258     {
259         ACPI_REPORT_ERROR (("Missing Sleep State object\n"));
260         Status = AE_NOT_EXIST;
261     }
262
263     /* It must be of type Package */
264
265     else if (ACPI_GET_OBJECT_TYPE (ObjDesc) != ACPI_TYPE_PACKAGE)
266     {
267         ACPI_REPORT_ERROR (("Sleep State object not a Package\n"));
268         Status = AE_AML_OPERAND_TYPE;
269     }
270
271     /* The package must have at least two elements */
272
273     else if (ObjDesc->Package.Count < 2)
274     {
275         ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
276         Status = AE_AML_NO_OPERAND;
277     }
278
279     /* The first two elements must both be of type Integer */
280
281     else if ((ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[0]) != ACPI_TYPE_INTEGER) ||
282              (ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[1]) != ACPI_TYPE_INTEGER))
283     {
284         ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n",
285             AcpiUtGetObjectTypeName (ObjDesc->Package.Elements[0]),
286             AcpiUtGetObjectTypeName (ObjDesc->Package.Elements[1])));
287         Status = AE_AML_OPERAND_TYPE;
288     }
289     else
290     {
291         /*
292          * Valid _Sx_ package size, type, and value
293          */
294         *SleepTypeA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value;
295         *SleepTypeB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value;
296     }
297
298     if (ACPI_FAILURE (Status))
299     {
300         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating SleepState [%s], bad Sleep object %p type %s\n",
301             AcpiGbl_DbSleepStates[SleepState], ObjDesc, AcpiUtGetObjectTypeName (ObjDesc)));
302     }
303
304     AcpiUtRemoveReference (ObjDesc);
305     return_ACPI_STATUS (Status);
306 }
307
308
309 /*******************************************************************************
310  *
311  * FUNCTION:    AcpiHwGetRegisterBitMask
312  *
313  * PARAMETERS:  RegisterId          - Index of ACPI Register to access
314  *
315  * RETURN:      The bit mask to be used when accessing the register
316  *
317  * DESCRIPTION: Map RegisterId into a register bit mask.
318  *
319  ******************************************************************************/
320
321 ACPI_BIT_REGISTER_INFO *
322 AcpiHwGetBitRegisterInfo (
323     UINT32                  RegisterId)
324 {
325     ACPI_FUNCTION_NAME ("HwGetBitRegisterInfo");
326
327
328     if (RegisterId > ACPI_BITREG_MAX)
329     {
330         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid BitRegister ID: %X\n", RegisterId));
331         return (NULL);
332     }
333
334     return (&AcpiGbl_BitRegisterInfo[RegisterId]);
335 }
336
337
338 /*******************************************************************************
339  *
340  * FUNCTION:    AcpiGetRegister
341  *
342  * PARAMETERS:  RegisterId          - Index of ACPI Register to access
343  *              UseLock             - Lock the hardware
344  *
345  * RETURN:      Value is read from specified Register.  Value returned is
346  *              normalized to bit0 (is shifted all the way right)
347  *
348  * DESCRIPTION: ACPI BitRegister read function.
349  *
350  ******************************************************************************/
351
352 ACPI_STATUS
353 AcpiGetRegister (
354     UINT32                  RegisterId,
355     UINT32                  *ReturnValue,
356     UINT32                  Flags)
357 {
358     UINT32                  RegisterValue = 0;
359     ACPI_BIT_REGISTER_INFO  *BitRegInfo;
360     ACPI_STATUS             Status;
361
362
363     ACPI_FUNCTION_TRACE ("AcpiGetRegister");
364
365
366     /* Get the info structure corresponding to the requested ACPI Register */
367
368     BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
369     if (!BitRegInfo)
370     {
371         return_ACPI_STATUS (AE_BAD_PARAMETER);
372     }
373
374     if (Flags & ACPI_MTX_LOCK)
375     {
376         Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
377         if (ACPI_FAILURE (Status))
378         {
379             return_ACPI_STATUS (Status);
380         }
381     }
382
383     Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
384                     BitRegInfo->ParentRegister, &RegisterValue);
385
386     if (Flags & ACPI_MTX_LOCK)
387     {
388         (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
389     }
390
391     if (ACPI_SUCCESS (Status))
392     {
393         /* Normalize the value that was read */
394
395         RegisterValue = ((RegisterValue & BitRegInfo->AccessBitMask)
396                             >> BitRegInfo->BitPosition);
397
398         *ReturnValue = RegisterValue;
399
400         ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read value %X\n", RegisterValue));
401     }
402
403     return_ACPI_STATUS (Status);
404 }
405
406
407 /*******************************************************************************
408  *
409  * FUNCTION:    AcpiSetRegister
410  *
411  * PARAMETERS:  RegisterId      - ID of ACPI BitRegister to access
412  *              Value           - (only used on write) value to write to the
413  *                                Register, NOT pre-normalized to the bit pos.
414  *              Flags           - Lock the hardware or not
415  *
416  * RETURN:      None
417  *
418  * DESCRIPTION: ACPI Bit Register write function.
419  *
420  ******************************************************************************/
421
422 ACPI_STATUS
423 AcpiSetRegister (
424     UINT32                  RegisterId,
425     UINT32                  Value,
426     UINT32                  Flags)
427 {
428     UINT32                  RegisterValue = 0;
429     ACPI_BIT_REGISTER_INFO  *BitRegInfo;
430     ACPI_STATUS             Status;
431
432
433     ACPI_FUNCTION_TRACE_U32 ("AcpiSetRegister", RegisterId);
434
435
436     /* Get the info structure corresponding to the requested ACPI Register */
437
438     BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
439     if (!BitRegInfo)
440     {
441         ACPI_REPORT_ERROR (("Bad ACPI HW RegisterId: %X\n", RegisterId));
442         return_ACPI_STATUS (AE_BAD_PARAMETER);
443     }
444
445     if (Flags & ACPI_MTX_LOCK)
446     {
447         Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
448         if (ACPI_FAILURE (Status))
449         {
450             return_ACPI_STATUS (Status);
451         }
452     }
453
454     /* Always do a register read first so we can insert the new bits  */
455
456     Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
457                     BitRegInfo->ParentRegister, &RegisterValue);
458     if (ACPI_FAILURE (Status))
459     {
460         goto UnlockAndExit;
461     }
462
463     /*
464      * Decode the Register ID
465      * Register id = Register block id | bit id
466      *
467      * Check bit id to fine locate Register offset.
468      * Check Mask to determine Register offset, and then read-write.
469      */
470     switch (BitRegInfo->ParentRegister)
471     {
472     case ACPI_REGISTER_PM1_STATUS:
473
474         /*
475          * Status Registers are different from the rest.  Clear by
476          * writing 1, writing 0 has no effect.  So, the only relevant
477          * information is the single bit we're interested in, all others should
478          * be written as 0 so they will be left unchanged
479          */
480         Value = ACPI_REGISTER_PREPARE_BITS (Value,
481                     BitRegInfo->BitPosition, BitRegInfo->AccessBitMask);
482         if (Value)
483         {
484             Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
485                         ACPI_REGISTER_PM1_STATUS, (UINT16) Value);
486             RegisterValue = 0;
487         }
488         break;
489
490
491     case ACPI_REGISTER_PM1_ENABLE:
492
493         ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
494                 BitRegInfo->AccessBitMask, Value);
495
496         Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
497                         ACPI_REGISTER_PM1_ENABLE, (UINT16) RegisterValue);
498         break;
499
500
501     case ACPI_REGISTER_PM1_CONTROL:
502
503         /*
504          * Read the PM1 Control register.
505          * Note that at this level, the fact that there are actually TWO
506          * registers (A and B - and that B may not exist) is abstracted.
507          */
508         ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", RegisterValue));
509
510         ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
511                 BitRegInfo->AccessBitMask, Value);
512
513         Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
514                 ACPI_REGISTER_PM1_CONTROL, (UINT16) RegisterValue);
515         break;
516
517
518     case ACPI_REGISTER_PM2_CONTROL:
519
520         Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
521                     ACPI_REGISTER_PM2_CONTROL, &RegisterValue);
522         if (ACPI_FAILURE (Status))
523         {
524             goto UnlockAndExit;
525         }
526
527         ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n",
528             RegisterValue,
529             ACPI_HIDWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)),
530             ACPI_LODWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address))));
531
532         ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
533                 BitRegInfo->AccessBitMask, Value);
534
535         ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n",
536             RegisterValue,
537             ACPI_HIDWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)),
538             ACPI_LODWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address))));
539
540         Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
541                             ACPI_REGISTER_PM2_CONTROL, (UINT8) (RegisterValue));
542         break;
543
544
545     default:
546         break;
547     }
548
549
550 UnlockAndExit:
551
552     if (Flags & ACPI_MTX_LOCK)
553     {
554         (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
555     }
556
557     /* Normalize the value that was read */
558
559     ACPI_DEBUG_EXEC (RegisterValue = ((RegisterValue & BitRegInfo->AccessBitMask) >> BitRegInfo->BitPosition));
560
561     ACPI_DEBUG_PRINT ((ACPI_DB_IO, "ACPI Register Write actual %X\n", RegisterValue));
562     return_ACPI_STATUS (Status);
563 }
564
565
566 /******************************************************************************
567  *
568  * FUNCTION:    AcpiHwRegisterRead
569  *
570  * PARAMETERS:  UseLock                - Mutex hw access.
571  *              RegisterId             - RegisterID + Offset.
572  *
573  * RETURN:      Value read or written.
574  *
575  * DESCRIPTION: Acpi register read function.  Registers are read at the
576  *              given offset.
577  *
578  ******************************************************************************/
579
580 ACPI_STATUS
581 AcpiHwRegisterRead (
582     BOOLEAN                 UseLock,
583     UINT32                  RegisterId,
584     UINT32                  *ReturnValue)
585 {
586     UINT32                  Value1 = 0;
587     UINT32                  Value2 = 0;
588     UINT32                  BankOffset;
589     ACPI_STATUS             Status;
590
591
592     ACPI_FUNCTION_TRACE ("HwRegisterRead");
593
594
595     if (ACPI_MTX_LOCK == UseLock)
596     {
597         Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
598         if (ACPI_FAILURE (Status))
599         {
600             return_ACPI_STATUS (Status);
601         }
602     }
603
604     switch (RegisterId)
605     {
606     case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
607
608         Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
609         if (ACPI_FAILURE (Status))
610         {
611             goto UnlockAndExit;
612         }
613
614         Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
615         Value1 |= Value2;
616         break;
617
618
619     case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access*/
620
621         BankOffset  = ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
622         Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
623         if (ACPI_FAILURE (Status))
624         {
625             goto UnlockAndExit;
626         }
627
628         Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
629         Value1 |= Value2;
630         break;
631
632
633     case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
634
635         Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aCntBlk, 0);
636         if (ACPI_FAILURE (Status))
637         {
638             goto UnlockAndExit;
639         }
640
641         Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bCntBlk, 0);
642         Value1 |= Value2;
643         break;
644
645
646     case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
647
648         Status = AcpiHwLowLevelRead (8, &Value1, &AcpiGbl_FADT->XPm2CntBlk, 0);
649         break;
650
651
652     case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
653
654         Status = AcpiHwLowLevelRead (32, &Value1, &AcpiGbl_FADT->XPmTmrBlk, 0);
655         break;
656
657     case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
658
659         Status = AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value1, 8);
660         break;
661
662     default:
663         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", RegisterId));
664         Status = AE_BAD_PARAMETER;
665         break;
666     }
667
668 UnlockAndExit:
669     if (ACPI_MTX_LOCK == UseLock)
670     {
671         (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
672     }
673
674     if (ACPI_SUCCESS (Status))
675     {
676         *ReturnValue = Value1;
677     }
678
679     return_ACPI_STATUS (Status);
680 }
681
682
683 /******************************************************************************
684  *
685  * FUNCTION:    AcpiHwRegisterWrite
686  *
687  * PARAMETERS:  UseLock                - Mutex hw access.
688  *              RegisterId             - RegisterID + Offset.
689  *
690  * RETURN:      Value read or written.
691  *
692  * DESCRIPTION: Acpi register Write function.  Registers are written at the
693  *              given offset.
694  *
695  ******************************************************************************/
696
697 ACPI_STATUS
698 AcpiHwRegisterWrite (
699     BOOLEAN                 UseLock,
700     UINT32                  RegisterId,
701     UINT32                  Value)
702 {
703     UINT32                  BankOffset;
704     ACPI_STATUS             Status;
705
706
707     ACPI_FUNCTION_TRACE ("HwRegisterWrite");
708
709
710     if (ACPI_MTX_LOCK == UseLock)
711     {
712         Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
713         if (ACPI_FAILURE (Status))
714         {
715             return_ACPI_STATUS (Status);
716         }
717     }
718
719     switch (RegisterId)
720     {
721     case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
722
723         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
724         if (ACPI_FAILURE (Status))
725         {
726             goto UnlockAndExit;
727         }
728
729         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
730         break;
731
732
733     case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access*/
734
735         BankOffset = ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
736         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
737         if (ACPI_FAILURE (Status))
738         {
739             goto UnlockAndExit;
740         }
741
742         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
743         break;
744
745
746     case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
747
748         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
749         if (ACPI_FAILURE (Status))
750         {
751             goto UnlockAndExit;
752         }
753
754         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
755         break;
756
757
758     case ACPI_REGISTER_PM1A_CONTROL:         /* 16-bit access */
759
760         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
761         break;
762
763
764     case ACPI_REGISTER_PM1B_CONTROL:         /* 16-bit access */
765
766         Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
767         break;
768
769
770     case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
771
772         Status = AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0);
773         break;
774
775
776     case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
777
778         Status = AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0);
779         break;
780
781
782     case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
783
784         /* SMI_CMD is currently always in IO space */
785
786         Status = AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, (ACPI_INTEGER) Value, 8);
787         break;
788
789
790     default:
791         Status = AE_BAD_PARAMETER;
792         break;
793     }
794
795 UnlockAndExit:
796     if (ACPI_MTX_LOCK == UseLock)
797     {
798         (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
799     }
800
801     return_ACPI_STATUS (Status);
802 }
803
804
805 /******************************************************************************
806  *
807  * FUNCTION:    AcpiHwLowLevelRead
808  *
809  * PARAMETERS:  Register            - GAS register structure
810  *              Offset              - Offset from the base address in the GAS
811  *              Width               - 8, 16, or 32
812  *
813  * RETURN:      Value read
814  *
815  * DESCRIPTION: Read from either memory, IO, or PCI config space.
816  *
817  ******************************************************************************/
818
819 ACPI_STATUS
820 AcpiHwLowLevelRead (
821     UINT32                  Width,
822     UINT32                  *Value,
823     ACPI_GENERIC_ADDRESS    *Reg,
824     UINT32                  Offset)
825 {
826     ACPI_PHYSICAL_ADDRESS   MemAddress;
827     ACPI_IO_ADDRESS         IoAddress;
828     ACPI_PCI_ID             PciId;
829     UINT16                  PciRegister;
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         (!ACPI_VALID_ADDRESS (Reg->Address)))
843     {
844         return (AE_OK);
845     }
846     *Value = 0;
847
848     /*
849      * Three address spaces supported:
850      * Memory, Io, or PCI config.
851      */
852     switch (Reg->AddressSpaceId)
853     {
854     case ACPI_ADR_SPACE_SYSTEM_MEMORY:
855
856         MemAddress = (ACPI_GET_ADDRESS (Reg->Address)
857                         + (ACPI_PHYSICAL_ADDRESS) Offset);
858
859         Status = AcpiOsReadMemory (MemAddress, Value, Width);
860         break;
861
862
863     case ACPI_ADR_SPACE_SYSTEM_IO:
864
865         IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address)
866                                         + (ACPI_PHYSICAL_ADDRESS) Offset);
867
868         Status = AcpiOsReadPort (IoAddress, Value, Width);
869         break;
870
871
872     case ACPI_ADR_SPACE_PCI_CONFIG:
873
874         PciId.Segment  = 0;
875         PciId.Bus      = 0;
876         PciId.Device   = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
877         PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
878         PciRegister    = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address))
879                                     + Offset);
880
881         Status = AcpiOsReadPciConfiguration  (&PciId, PciRegister, Value, Width);
882         break;
883
884
885     default:
886         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", Reg->AddressSpaceId));
887         Status = AE_BAD_PARAMETER;
888         break;
889     }
890
891     return (Status);
892 }
893
894
895 /******************************************************************************
896  *
897  * FUNCTION:    AcpiHwLowLevelWrite
898  *
899  * PARAMETERS:  Width               - 8, 16, or 32
900  *              Value               - To be written
901  *              Register            - GAS register structure
902  *              Offset              - Offset from the base address in the GAS
903  *
904  *
905  * RETURN:      Value read
906  *
907  * DESCRIPTION: Read from either memory, IO, or PCI config space.
908  *
909  ******************************************************************************/
910
911 ACPI_STATUS
912 AcpiHwLowLevelWrite (
913     UINT32                  Width,
914     UINT32                  Value,
915     ACPI_GENERIC_ADDRESS    *Reg,
916     UINT32                  Offset)
917 {
918     ACPI_PHYSICAL_ADDRESS   MemAddress;
919     ACPI_IO_ADDRESS         IoAddress;
920     ACPI_PCI_ID             PciId;
921     UINT16                  PciRegister;
922     ACPI_STATUS             Status;
923
924
925     ACPI_FUNCTION_NAME ("HwLowLevelWrite");
926
927
928     /*
929      * Must have a valid pointer to a GAS structure, and
930      * a non-zero address within. However, don't return an error
931      * because the PM1A/B code must not fail if B isn't present.
932      */
933     if ((!Reg) ||
934         (!ACPI_VALID_ADDRESS (Reg->Address)))
935     {
936         return (AE_OK);
937     }
938     /*
939      * Three address spaces supported:
940      * Memory, Io, or PCI config.
941      */
942     switch (Reg->AddressSpaceId)
943     {
944     case ACPI_ADR_SPACE_SYSTEM_MEMORY:
945
946         MemAddress = (ACPI_GET_ADDRESS (Reg->Address)
947                         + (ACPI_PHYSICAL_ADDRESS) Offset);
948
949         Status = AcpiOsWriteMemory (MemAddress, (ACPI_INTEGER) Value, Width);
950         break;
951
952
953     case ACPI_ADR_SPACE_SYSTEM_IO:
954
955         IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address)
956                                         + (ACPI_PHYSICAL_ADDRESS) Offset);
957
958         Status = AcpiOsWritePort (IoAddress, (ACPI_INTEGER) Value, Width);
959         break;
960
961
962     case ACPI_ADR_SPACE_PCI_CONFIG:
963
964         PciId.Segment  = 0;
965         PciId.Bus      = 0;
966         PciId.Device   = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
967         PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
968         PciRegister    = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address))
969                                     + Offset);
970
971         Status = AcpiOsWritePciConfiguration (&PciId, PciRegister, (ACPI_INTEGER) Value, Width);
972         break;
973
974
975     default:
976         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", Reg->AddressSpaceId));
977         Status = AE_BAD_PARAMETER;
978         break;
979     }
980
981     return (Status);
982 }