machine/stdarg provides __va* macros, not va* macros, use <stdarg.h> instead
[dragonfly.git] / sys / contrib / dev / acpica / evgpeblk.c
1 /******************************************************************************
2  *
3  * Module Name: evgpeblk - GPE block creation and initialization.
4  *              $Revision: 4 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116 /* $DragonFly: src/sys/contrib/dev/acpica/Attic/evgpeblk.c,v 1.1 2003/09/24 03:32:15 drhodus Exp $                                                               */
117
118 #include "acpi.h"
119 #include "acevents.h"
120 #include "acnamesp.h"
121
122 #define _COMPONENT          ACPI_EVENTS
123         ACPI_MODULE_NAME    ("evgpe")
124
125
126 /*******************************************************************************
127  *
128  * FUNCTION:    AcpiEvSaveMethodInfo
129  *
130  * PARAMETERS:  Callback from WalkNamespace
131  *
132  * RETURN:      None
133  *
134  * DESCRIPTION: Called from AcpiWalkNamespace.  Expects each object to be a
135  *              control method under the _GPE portion of the namespace.
136  *              Extract the name and GPE type from the object, saving this
137  *              information for quick lookup during GPE dispatch
138  *
139  *              The name of each GPE control method is of the form:
140  *                  "_Lnn" or "_Enn"
141  *              Where:
142  *                  L      - means that the GPE is level triggered
143  *                  E      - means that the GPE is edge triggered
144  *                  nn     - is the GPE number [in HEX]
145  *
146  ******************************************************************************/
147
148 static ACPI_STATUS
149 AcpiEvSaveMethodInfo (
150     ACPI_HANDLE             ObjHandle,
151     UINT32                  Level,
152     void                    *ObjDesc,
153     void                    **ReturnValue)
154 {
155     ACPI_GPE_BLOCK_INFO     *GpeBlock = (void *) ObjDesc;
156     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
157     UINT32                  GpeNumber;
158     char                    Name[ACPI_NAME_SIZE + 1];
159     UINT8                   Type;
160     ACPI_STATUS             Status;
161
162
163     ACPI_FUNCTION_NAME ("EvSaveMethodInfo");
164
165
166     /* Extract the name from the object and convert to a string */
167
168     ACPI_MOVE_UNALIGNED32_TO_32 (Name,
169                 &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer);
170     Name[ACPI_NAME_SIZE] = 0;
171
172     /*
173      * Edge/Level determination is based on the 2nd character of the method name
174      */
175     switch (Name[1])
176     {
177     case 'L':
178         Type = ACPI_EVENT_LEVEL_TRIGGERED;
179         break;
180
181     case 'E':
182         Type = ACPI_EVENT_EDGE_TRIGGERED;
183         break;
184
185     default:
186         /* Unknown method type, just ignore it! */
187
188         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
189             "Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n",
190             Name));
191         return (AE_OK);
192     }
193
194     /* Convert the last two characters of the name to the GPE Number */
195
196     GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
197     if (GpeNumber == ACPI_UINT32_MAX)
198     {
199         /* Conversion failed; invalid method, just ignore it */
200
201         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
202             "Could not extract GPE number from name: %s (name is not of form _Lnn or _Enn)\n",
203             Name));
204         return (AE_OK);
205     }
206
207     /* Ensure that we have a valid GPE number for this GPE block */
208
209     if ((GpeNumber < GpeBlock->BlockBaseNumber) ||
210         (GpeNumber - GpeBlock->BlockBaseNumber >= (GpeBlock->RegisterCount * 8)))
211     {
212         /* Not valid, all we can do here is ignore it */
213
214         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
215             "GPE number associated with method %s is not valid\n", Name));
216         return (AE_OK);
217     }
218
219     /*
220      * Now we can add this information to the GpeEventInfo block
221      * for use during dispatch of this GPE.
222      */
223     GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];
224
225     GpeEventInfo->Type       = Type;
226     GpeEventInfo->MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle;
227
228     /*
229      * Enable the GPE (SCIs should be disabled at this point)
230      */
231     Status = AcpiHwEnableGpe (GpeEventInfo);
232     if (ACPI_FAILURE (Status))
233     {
234         return (Status);
235     }
236
237     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %2.2X\n",
238         Name, GpeNumber));
239     return (AE_OK);
240 }
241
242
243 /*******************************************************************************
244  *
245  * FUNCTION:    AcpiEvInstallGpeBlock
246  *
247  * PARAMETERS:  GpeBlock    - New GPE block
248  *
249  * RETURN:      Status
250  *
251  * DESCRIPTION: Install new GPE block with mutex support
252  *
253  ******************************************************************************/
254
255 ACPI_STATUS
256 AcpiEvInstallGpeBlock (
257     ACPI_GPE_BLOCK_INFO     *GpeBlock)
258 {
259     ACPI_GPE_BLOCK_INFO     *NextGpeBlock;
260     ACPI_STATUS             Status;
261
262
263     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
264     if (ACPI_FAILURE (Status))
265     {
266         return (Status);
267     }
268
269     /* Install the new block at the end of the global list */
270
271     if (AcpiGbl_GpeBlockListHead)
272     {
273         NextGpeBlock = AcpiGbl_GpeBlockListHead;
274         while (NextGpeBlock->Next)
275         {
276             NextGpeBlock = NextGpeBlock->Next;
277         }
278
279         NextGpeBlock->Next = GpeBlock;
280         GpeBlock->Previous = NextGpeBlock;
281     }
282     else
283     {
284         AcpiGbl_GpeBlockListHead = GpeBlock;
285     }
286
287     Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
288     return (Status);
289 }
290
291
292 /*******************************************************************************
293  *
294  * FUNCTION:    AcpiEvCreateGpeInfoBlocks
295  *
296  * PARAMETERS:  GpeBlock    - New GPE block
297  *
298  * RETURN:      Status
299  *
300  * DESCRIPTION: Create the RegisterInfo and EventInfo blocks for this GPE block
301  *
302  ******************************************************************************/
303
304 ACPI_STATUS
305 AcpiEvCreateGpeInfoBlocks (
306     ACPI_GPE_BLOCK_INFO     *GpeBlock)
307 {
308     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo = NULL;
309     ACPI_GPE_EVENT_INFO     *GpeEventInfo = NULL;
310     ACPI_GPE_EVENT_INFO     *ThisEvent;
311     ACPI_GPE_REGISTER_INFO  *ThisRegister;
312     ACPI_NATIVE_UINT        i;
313     ACPI_NATIVE_UINT        j;
314     ACPI_STATUS             Status;
315
316
317     ACPI_FUNCTION_TRACE ("EvCreateGpeInfoBlocks");
318
319
320     /* Allocate the GPE register information block */
321
322     GpeRegisterInfo = ACPI_MEM_CALLOCATE (
323                                 (ACPI_SIZE) GpeBlock->RegisterCount *
324                                 sizeof (ACPI_GPE_REGISTER_INFO));
325     if (!GpeRegisterInfo)
326     {
327         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
328             "Could not allocate the GpeRegisterInfo table\n"));
329         return_ACPI_STATUS (AE_NO_MEMORY);
330     }
331
332     /*
333      * Allocate the GPE EventInfo block.  There are eight distinct GPEs
334      * per register.  Initialization to zeros is sufficient.
335      */
336     GpeEventInfo = ACPI_MEM_CALLOCATE (
337                         ((ACPI_SIZE) GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) *
338                         sizeof (ACPI_GPE_EVENT_INFO));
339     if (!GpeEventInfo)
340     {
341         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the GpeEventInfo table\n"));
342         Status = AE_NO_MEMORY;
343         goto ErrorExit;
344     }
345
346     /*
347      * Initialize the GPE Register and Event structures.  A goal of these
348      * tables is to hide the fact that there are two separate GPE register sets
349      * in a given gpe hardware block, the status registers occupy the first half,
350      * and the enable registers occupy the second half.  Another goal is to hide
351      * the fact that there may be multiple GPE hardware blocks.
352      */
353     ThisRegister = GpeRegisterInfo;
354     ThisEvent    = GpeEventInfo;
355
356     for (i = 0; i < GpeBlock->RegisterCount; i++)
357     {
358         /* Init the RegisterInfo for this GPE register (8 GPEs) */
359
360         ThisRegister->BaseGpeNumber = (UINT8) (GpeBlock->BlockBaseNumber +
361                                                  (i * ACPI_GPE_REGISTER_WIDTH));
362
363         ACPI_STORE_ADDRESS (ThisRegister->StatusAddress.Address,
364                                 (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address)
365                                 + i));
366
367         ACPI_STORE_ADDRESS (ThisRegister->EnableAddress.Address,
368                                 (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address)
369                                 + i
370                                 + GpeBlock->RegisterCount));
371
372         ThisRegister->StatusAddress.AddressSpaceId    = GpeBlock->BlockAddress.AddressSpaceId;
373         ThisRegister->EnableAddress.AddressSpaceId    = GpeBlock->BlockAddress.AddressSpaceId;
374         ThisRegister->StatusAddress.RegisterBitWidth  = ACPI_GPE_REGISTER_WIDTH;
375         ThisRegister->EnableAddress.RegisterBitWidth  = ACPI_GPE_REGISTER_WIDTH;
376         ThisRegister->StatusAddress.RegisterBitOffset = ACPI_GPE_REGISTER_WIDTH;
377         ThisRegister->EnableAddress.RegisterBitOffset = ACPI_GPE_REGISTER_WIDTH;
378
379         /* Init the EventInfo for each GPE within this register */
380
381         for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
382         {
383             ThisEvent->BitMask = AcpiGbl_DecodeTo8bit[j];
384             ThisEvent->RegisterInfo = ThisRegister;
385             ThisEvent++;
386         }
387
388         /*
389          * Clear the status/enable registers.  Note that status registers
390          * are cleared by writing a '1', while enable registers are cleared
391          * by writing a '0'.
392          */
393         Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0x00,
394                     &ThisRegister->EnableAddress, 0);
395         if (ACPI_FAILURE (Status))
396         {
397             goto ErrorExit;
398         }
399
400         Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0xFF,
401                     &ThisRegister->StatusAddress, 0);
402         if (ACPI_FAILURE (Status))
403         {
404             goto ErrorExit;
405         }
406
407         ThisRegister++;
408     }
409
410     GpeBlock->RegisterInfo = GpeRegisterInfo;
411     GpeBlock->EventInfo    = GpeEventInfo;
412
413     return_ACPI_STATUS (AE_OK);
414
415
416 ErrorExit:
417
418     if (GpeRegisterInfo)
419     {
420         ACPI_MEM_FREE (GpeRegisterInfo);
421     }
422     if (GpeEventInfo)
423     {
424         ACPI_MEM_FREE (GpeEventInfo);
425     }
426
427     return_ACPI_STATUS (AE_OK);
428 }
429
430
431 /*******************************************************************************
432  *
433  * FUNCTION:    AcpiEvCreateGpeBlock
434  *
435  * PARAMETERS:  TBD
436  *
437  * RETURN:      Status
438  *
439  * DESCRIPTION: Create and Install a block of GPE registers
440  *
441  ******************************************************************************/
442
443 ACPI_STATUS
444 AcpiEvCreateGpeBlock (
445     char                    *Pathname,
446     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
447     UINT32                  RegisterCount,
448     UINT8                   GpeBlockBaseNumber,
449     UINT32                  InterruptLevel)
450 {
451     ACPI_GPE_BLOCK_INFO     *GpeBlock;
452     ACPI_STATUS             Status;
453     ACPI_HANDLE             ObjHandle;
454
455
456     ACPI_FUNCTION_TRACE ("EvCreateGpeBlock");
457
458
459     if (!RegisterCount)
460     {
461         return_ACPI_STATUS (AE_OK);
462     }
463
464     /* Get a handle to the parent object for this GPE block */
465
466     Status = AcpiGetHandle (NULL, Pathname, &ObjHandle);
467     if (ACPI_FAILURE (Status))
468     {
469         return_ACPI_STATUS (Status);
470     }
471
472     /* Allocate a new GPE block */
473
474     GpeBlock = ACPI_MEM_CALLOCATE (sizeof (ACPI_GPE_BLOCK_INFO));
475     if (!GpeBlock)
476     {
477         return_ACPI_STATUS (AE_NO_MEMORY);
478     }
479
480     /* Initialize the new GPE block */
481
482     GpeBlock->RegisterCount   = RegisterCount;
483     GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
484
485     ACPI_MEMCPY (&GpeBlock->BlockAddress, GpeBlockAddress, sizeof (ACPI_GENERIC_ADDRESS));
486
487     /* Create the RegisterInfo and EventInfo sub-structures */
488
489     Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);
490     if (ACPI_FAILURE (Status))
491     {
492         ACPI_MEM_FREE (GpeBlock);
493         return_ACPI_STATUS (Status);
494     }
495
496     /* Install the new block in the global list(s) */
497     /* TBD: Install block in the interrupt handler list */
498
499     Status = AcpiEvInstallGpeBlock (GpeBlock);
500     if (ACPI_FAILURE (Status))
501     {
502         ACPI_MEM_FREE (GpeBlock);
503         return_ACPI_STATUS (Status);
504     }
505
506     /* Dump info about this GPE block */
507
508     ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block: %X registers at %8.8X%8.8X\n",
509         GpeBlock->RegisterCount,
510         ACPI_HIDWORD (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address)),
511         ACPI_LODWORD (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address))));
512
513     ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block defined as GPE%d to GPE%d\n",
514         GpeBlock->BlockBaseNumber,
515         (UINT32) (GpeBlock->BlockBaseNumber +
516                 ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1))));
517
518     /* Find all GPE methods (_Lxx, _Exx) for this block */
519
520     Status = AcpiWalkNamespace (ACPI_TYPE_METHOD, ObjHandle,
521                                 ACPI_UINT32_MAX, AcpiEvSaveMethodInfo,
522                                 GpeBlock, NULL);
523
524     return_ACPI_STATUS (AE_OK);
525 }
526
527
528 /*******************************************************************************
529  *
530  * FUNCTION:    AcpiEvGpeInitialize
531  *
532  * PARAMETERS:  None
533  *
534  * RETURN:      Status
535  *
536  * DESCRIPTION: Initialize the GPE data structures
537  *
538  ******************************************************************************/
539
540 ACPI_STATUS
541 AcpiEvGpeInitialize (void)
542 {
543     UINT32                  RegisterCount0 = 0;
544     UINT32                  RegisterCount1 = 0;
545     UINT32                  GpeNumberMax = 0;
546
547
548     ACPI_FUNCTION_TRACE ("EvGpeInitialize");
549
550
551     /*
552      * Initialize the GPE Blocks defined in the FADT
553      *
554      * Why the GPE register block lengths are divided by 2:  From the ACPI Spec,
555      * section "General-Purpose Event Registers", we have:
556      *
557      * "Each register block contains two registers of equal length
558      *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
559      *  GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
560      *  The length of the GPE1_STS and GPE1_EN registers is equal to
561      *  half the GPE1_LEN. If a generic register block is not supported
562      *  then its respective block pointer and block length values in the
563      *  FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
564      *  to be the same size."
565      */
566
567     /*
568      * Determine the maximum GPE number for this machine.
569      *
570      * Note: both GPE0 and GPE1 are optional, and either can exist without
571      * the other.
572      * If EITHER the register length OR the block address are zero, then that
573      * particular block is not supported.
574      */
575     if (AcpiGbl_FADT->Gpe0BlkLen &&
576         ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address))
577     {
578         /* GPE block 0 exists (has both length and address > 0) */
579
580         RegisterCount0 = (UINT16) (AcpiGbl_FADT->Gpe0BlkLen / 2);
581
582         GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1;
583
584         AcpiEvCreateGpeBlock ("\\_GPE", &AcpiGbl_FADT->XGpe0Blk,
585             RegisterCount0, 0, AcpiGbl_FADT->SciInt);
586     }
587
588     if (AcpiGbl_FADT->Gpe1BlkLen &&
589         ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address))
590     {
591         /* GPE block 1 exists (has both length and address > 0) */
592
593         RegisterCount1 = (UINT16) (AcpiGbl_FADT->Gpe1BlkLen / 2);
594
595         /* Check for GPE0/GPE1 overlap (if both banks exist) */
596
597         if ((RegisterCount0) &&
598             (GpeNumberMax >= AcpiGbl_FADT->Gpe1Base))
599         {
600             ACPI_REPORT_ERROR ((
601                 "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n",
602                 GpeNumberMax, AcpiGbl_FADT->Gpe1Base,
603                 AcpiGbl_FADT->Gpe1Base +
604                 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
605
606             /* Ignore GPE1 block by setting the register count to zero */
607
608             RegisterCount1 = 0;
609         }
610         else
611         {
612             AcpiEvCreateGpeBlock ("\\_GPE", &AcpiGbl_FADT->XGpe1Blk,
613                 RegisterCount1, AcpiGbl_FADT->Gpe1Base, AcpiGbl_FADT->SciInt);
614
615             /*
616              * GPE0 and GPE1 do not have to be contiguous in the GPE number space,
617              * But, GPE0 always starts at zero.
618              */
619             GpeNumberMax = AcpiGbl_FADT->Gpe1Base +
620                                 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1);
621         }
622     }
623
624     /* Exit if there are no GPE registers */
625
626     if ((RegisterCount0 + RegisterCount1) == 0)
627     {
628         /* GPEs are not required by ACPI, this is OK */
629
630         ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n"));
631         return_ACPI_STATUS (AE_OK);
632     }
633
634     /* Check for Max GPE number out-of-range */
635
636     if (GpeNumberMax > ACPI_GPE_MAX)
637     {
638         ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
639             GpeNumberMax));
640         return_ACPI_STATUS (AE_BAD_VALUE);
641     }
642
643     return_ACPI_STATUS (AE_OK);
644 }
645
646