Subversion Repositories Kolibri OS

Rev

Rev 1498 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/******************************************************************************
2
 *
3
 * Module Name: aehandlers - Various handlers for acpiexec
4
 *
5
 *****************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
2216 Serge 11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 12
 * All rights reserved.
13
 *
14
 * 2. License
15
 *
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
17
 * rights.  You may have additional license terms from the party that provided
18
 * you this software, covering your right to use that party's intellectual
19
 * property rights.
20
 *
21
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
 * copy of the source code appearing in this file ("Covered Code") an
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * make derivatives, distribute, use and display any portion of the Covered
26
 * Code in any form, with the right to sublicense such rights; and
27
 *
28
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
 * license (with the right to sublicense), under only those claims of Intel
30
 * patents that are infringed by the Original Intel Code, to make, use, sell,
31
 * offer to sell, and import the Covered Code and derivative works thereof
32
 * solely to the minimum extent necessary to exercise the above copyright
33
 * license, and in no event shall the patent license extend to any additions
34
 * to or modifications of the Original Intel Code.  No other license or right
35
 * is granted directly or by implication, estoppel or otherwise;
36
 *
37
 * The above copyright and patent license is granted only if the following
38
 * conditions are met:
39
 *
40
 * 3. Conditions
41
 *
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * Redistribution of source code of any substantial portion of the Covered
44
 * Code or modification with rights to further distribute source must include
45
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * Licensee must cause all Covered Code to which Licensee contributes to
48
 * contain a file documenting the changes Licensee made to create that Covered
49
 * Code and the date of any change.  Licensee must include in that file the
50
 * documentation of any changes made by any predecessor Licensee.  Licensee
51
 * must include a prominent statement that the modification is derived,
52
 * directly or indirectly, from Original Intel Code.
53
 *
54
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
 * Redistribution of source code of any substantial portion of the Covered
56
 * Code or modification without rights to further distribute source must
57
 * include the following Disclaimer and Export Compliance provision in the
58
 * documentation and/or other materials provided with distribution.  In
59
 * addition, Licensee may not authorize further sublicense of source of any
60
 * portion of the Covered Code, and must include terms to the effect that the
61
 * license from Licensee to its licensee is limited to the intellectual
62
 * property embodied in the software Licensee provides to its licensee, and
63
 * not to intellectual property embodied in modifications its licensee may
64
 * make.
65
 *
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * substantial portion of the Covered Code or modification must reproduce the
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * provision in the documentation and/or other materials provided with the
70
 * distribution.
71
 *
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * Intel Code.
74
 *
75
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
 * Intel shall be used in advertising or otherwise to promote the sale, use or
77
 * other dealings in products derived from or relating to the Covered Code
78
 * without prior written authorization from Intel.
79
 *
80
 * 4. Disclaimer and Export Compliance
81
 *
82
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * PARTICULAR PURPOSE.
89
 *
90
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * LIMITED REMEDY.
98
 *
99
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100
 * software or system incorporating such software without first obtaining any
101
 * required license or other approval from the U. S. Department of Commerce or
102
 * any other agency or department of the United States Government.  In the
103
 * event Licensee exports any such software from the United States or
104
 * re-exports any such software from a foreign destination, Licensee shall
105
 * ensure that the distribution and export/re-export of the software is in
106
 * compliance with all laws, regulations, orders, or other restrictions of the
107
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
 * any of its subsidiaries will export/re-export any technical data, process,
109
 * software, or service, directly or indirectly, to any country for which the
110
 * United States government or any agency thereof requires an export license,
111
 * other governmental approval, or letter of assurance, without first obtaining
112
 * such license, approval or letter.
113
 *
114
 *****************************************************************************/
115
 
116
#include "aecommon.h"
117
 
118
#define _COMPONENT          ACPI_TOOLS
119
        ACPI_MODULE_NAME    ("aehandlers")
120
 
121
/* Local prototypes */
122
 
2216 Serge 123
static void
1498 serge 124
AeNotifyHandler (
125
    ACPI_HANDLE             Device,
126
    UINT32                  Value,
127
    void                    *Context);
128
 
2216 Serge 129
static void
1498 serge 130
AeDeviceNotifyHandler (
131
    ACPI_HANDLE             Device,
132
    UINT32                  Value,
133
    void                    *Context);
134
 
2216 Serge 135
static ACPI_STATUS
1498 serge 136
AeExceptionHandler (
137
    ACPI_STATUS             AmlStatus,
138
    ACPI_NAME               Name,
139
    UINT16                  Opcode,
140
    UINT32                  AmlOffset,
141
    void                    *Context);
142
 
2216 Serge 143
static ACPI_STATUS
1498 serge 144
AeTableHandler (
145
    UINT32                  Event,
146
    void                    *Table,
147
    void                    *Context);
148
 
2216 Serge 149
static ACPI_STATUS
1498 serge 150
AeRegionInit (
151
    ACPI_HANDLE             RegionHandle,
152
    UINT32                  Function,
153
    void                    *HandlerContext,
154
    void                    **RegionContext);
155
 
2216 Serge 156
static void
1498 serge 157
AeAttachedDataHandler (
158
    ACPI_HANDLE             Object,
159
    void                    *Data);
160
 
2216 Serge 161
static UINT32
162
AeInterfaceHandler (
163
    ACPI_STRING             InterfaceName,
164
    UINT32                  Supported);
1498 serge 165
 
2216 Serge 166
static UINT32
167
AeEventHandler (
168
    void                    *Context);
1498 serge 169
 
2216 Serge 170
static UINT32               SigintCount = 0;
171
static AE_DEBUG_REGIONS     AeRegions;
172
 
173
 
174
/*
175
 * We will override some of the default region handlers, especially the
176
 * SystemMemory handler, which must be implemented locally. Do not override
177
 * the PCI_Config handler since we would like to exercise the default handler
178
 * code. These handlers are installed "early" - before any _REG methods
179
 * are executed - since they are special in the sense that tha ACPI spec
180
 * declares that they must "always be available". Cannot override the
181
 * DataTable region handler either -- needed for test execution.
182
 */
183
static ACPI_ADR_SPACE_TYPE  DefaultSpaceIdList[] = {
184
    ACPI_ADR_SPACE_SYSTEM_MEMORY,
185
    ACPI_ADR_SPACE_SYSTEM_IO
186
};
187
 
188
/*
189
 * We will install handlers for some of the various address space IDs
190
 * Test one user-defined address space (used by aslts.)
191
 */
192
#define ACPI_ADR_SPACE_USER_DEFINED     0x80
193
 
194
static ACPI_ADR_SPACE_TYPE  SpaceIdList[] = {
195
    ACPI_ADR_SPACE_EC,
196
    ACPI_ADR_SPACE_SMBUS,
197
    ACPI_ADR_SPACE_PCI_BAR_TARGET,
198
    ACPI_ADR_SPACE_IPMI,
199
    ACPI_ADR_SPACE_FIXED_HARDWARE,
200
    ACPI_ADR_SPACE_USER_DEFINED
201
};
202
 
203
 
1498 serge 204
/******************************************************************************
205
 *
206
 * FUNCTION:    AeCtrlCHandler
207
 *
208
 * PARAMETERS:  Sig
209
 *
210
 * RETURN:      none
211
 *
212
 * DESCRIPTION: Control-C handler.  Abort running control method if any.
213
 *
214
 *****************************************************************************/
215
 
2216 Serge 216
void ACPI_SYSTEM_XFACE
1498 serge 217
AeCtrlCHandler (
218
    int                     Sig)
219
{
220
 
221
    signal (SIGINT, SIG_IGN);
222
    SigintCount++;
223
 
224
    AcpiOsPrintf ("Caught a ctrl-c (#%u)\n\n", SigintCount);
225
 
226
    if (AcpiGbl_MethodExecuting)
227
    {
228
        AcpiGbl_AbortMethod = TRUE;
229
        signal (SIGINT, AeCtrlCHandler);
230
 
231
        if (SigintCount < 10)
232
        {
233
            return;
234
        }
235
    }
236
 
237
    exit (0);
238
}
239
 
240
 
241
/******************************************************************************
242
 *
243
 * FUNCTION:    AeNotifyHandler
244
 *
245
 * PARAMETERS:  Standard notify handler parameters
246
 *
247
 * RETURN:      Status
248
 *
249
 * DESCRIPTION: System notify handler for AcpiExec utility.  Used by the ASL
250
 *              test suite(s) to communicate errors and other information to
251
 *              this utility via the Notify() operator.
252
 *
253
 *****************************************************************************/
254
 
2216 Serge 255
static void
1498 serge 256
AeNotifyHandler (
257
    ACPI_HANDLE                 Device,
258
    UINT32                      Value,
259
    void                        *Context)
260
{
261
 
262
    switch (Value)
263
    {
264
#if 0
265
    case 0:
266
        printf ("[AcpiExec] Method Error 0x%X: Results not equal\n", Value);
267
        if (AcpiGbl_DebugFile)
268
        {
269
            AcpiOsPrintf ("[AcpiExec] Method Error: Results not equal\n");
270
        }
271
        break;
272
 
273
 
274
    case 1:
275
        printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
276
        if (AcpiGbl_DebugFile)
277
        {
278
            AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
279
        }
280
        break;
281
 
282
 
283
    case 2:
284
        printf ("[AcpiExec] Method Error: An operand was overwritten\n");
285
        if (AcpiGbl_DebugFile)
286
        {
287
            AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
288
        }
289
        break;
290
 
291
#endif
292
 
293
    default:
294
        printf ("[AcpiExec] Received a System Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
295
            AcpiUtGetNodeName (Device), Device, Value,
296
            AcpiUtGetNotifyName (Value));
297
        if (AcpiGbl_DebugFile)
298
        {
299
            AcpiOsPrintf ("[AcpiExec] Received a system notify, Value 0x%2.2X\n", Value);
300
        }
301
 
302
        (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
303
        break;
304
    }
305
}
306
 
307
 
308
/******************************************************************************
309
 *
310
 * FUNCTION:    AeDeviceNotifyHandler
311
 *
312
 * PARAMETERS:  Standard notify handler parameters
313
 *
314
 * RETURN:      Status
315
 *
316
 * DESCRIPTION: Device notify handler for AcpiExec utility.  Used by the ASL
317
 *              test suite(s) to communicate errors and other information to
318
 *              this utility via the Notify() operator.
319
 *
320
 *****************************************************************************/
321
 
2216 Serge 322
static void
1498 serge 323
AeDeviceNotifyHandler (
324
    ACPI_HANDLE                 Device,
325
    UINT32                      Value,
326
    void                        *Context)
327
{
328
 
329
    printf ("[AcpiExec] Received a Device Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
330
        AcpiUtGetNodeName (Device), Device, Value,
331
        AcpiUtGetNotifyName (Value));
332
    if (AcpiGbl_DebugFile)
333
    {
334
        AcpiOsPrintf ("[AcpiExec] Received a device notify, Value 0x%2.2X\n", Value);
335
    }
336
 
337
    (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
338
}
339
 
340
 
341
/******************************************************************************
342
 *
343
 * FUNCTION:    AeExceptionHandler
344
 *
345
 * PARAMETERS:  Standard exception handler parameters
346
 *
347
 * RETURN:      Status
348
 *
349
 * DESCRIPTION: System exception handler for AcpiExec utility.
350
 *
351
 *****************************************************************************/
352
 
2216 Serge 353
static ACPI_STATUS
1498 serge 354
AeExceptionHandler (
355
    ACPI_STATUS             AmlStatus,
356
    ACPI_NAME               Name,
357
    UINT16                  Opcode,
358
    UINT32                  AmlOffset,
359
    void                    *Context)
360
{
361
    ACPI_STATUS             NewAmlStatus = AmlStatus;
362
    ACPI_STATUS             Status;
363
    ACPI_BUFFER             ReturnObj;
364
    ACPI_OBJECT_LIST        ArgList;
365
    ACPI_OBJECT             Arg[3];
366
    const char              *Exception;
367
 
368
 
369
    Exception = AcpiFormatException (AmlStatus);
370
    AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception);
371
    if (Name)
372
    {
373
        AcpiOsPrintf ("of method [%4.4s]", (char *) &Name);
374
    }
375
    else
376
    {
377
        AcpiOsPrintf ("at module level (table load)");
378
    }
379
    AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset);
380
 
381
    /*
382
     * Invoke the _ERR method if present
383
     *
384
     * Setup parameter object
385
     */
386
    ArgList.Count = 3;
387
    ArgList.Pointer = Arg;
388
 
389
    Arg[0].Type = ACPI_TYPE_INTEGER;
390
    Arg[0].Integer.Value = AmlStatus;
391
 
392
    Arg[1].Type = ACPI_TYPE_STRING;
393
    Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception);
394
    Arg[1].String.Length = ACPI_STRLEN (Exception);
395
 
396
    Arg[2].Type = ACPI_TYPE_INTEGER;
2216 Serge 397
    Arg[2].Integer.Value = AcpiOsGetThreadId();
1498 serge 398
 
399
    /* Setup return buffer */
400
 
401
    ReturnObj.Pointer = NULL;
402
    ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
403
 
404
    Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj);
405
    if (ACPI_SUCCESS (Status))
406
    {
407
        if (ReturnObj.Pointer)
408
        {
409
            /* Override original status */
410
 
411
            NewAmlStatus = (ACPI_STATUS)
412
                ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value;
413
 
414
            AcpiOsFree (ReturnObj.Pointer);
415
        }
416
    }
417
    else if (Status != AE_NOT_FOUND)
418
    {
419
        AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n",
420
            AcpiFormatException (Status));
421
    }
422
 
423
    /* Global override */
424
 
425
    if (AcpiGbl_IgnoreErrors)
426
    {
427
        NewAmlStatus = AE_OK;
428
    }
429
 
430
    if (NewAmlStatus != AmlStatus)
431
    {
432
        AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n",
433
            AcpiFormatException (NewAmlStatus));
434
    }
435
 
436
    return (NewAmlStatus);
437
}
438
 
439
 
440
/******************************************************************************
441
 *
442
 * FUNCTION:    AeTableHandler
443
 *
444
 * PARAMETERS:  Table handler
445
 *
446
 * RETURN:      Status
447
 *
448
 * DESCRIPTION: System table handler for AcpiExec utility.
449
 *
450
 *****************************************************************************/
451
 
2216 Serge 452
static char                *TableEvents[] =
1498 serge 453
{
454
    "LOAD",
455
    "UNLOAD",
456
    "UNKNOWN"
457
};
458
 
2216 Serge 459
static ACPI_STATUS
1498 serge 460
AeTableHandler (
461
    UINT32                  Event,
462
    void                    *Table,
463
    void                    *Context)
464
{
2216 Serge 465
    ACPI_STATUS             Status;
1498 serge 466
 
2216 Serge 467
 
1498 serge 468
    if (Event > ACPI_NUM_TABLE_EVENTS)
469
    {
470
        Event = ACPI_NUM_TABLE_EVENTS;
471
    }
472
 
2216 Serge 473
    /* Enable any GPEs associated with newly-loaded GPE methods */
1498 serge 474
 
2216 Serge 475
    Status = AcpiUpdateAllGpes ();
476
    AE_CHECK_OK (AcpiUpdateAllGpes, Status);
477
 
1498 serge 478
    printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
479
        TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
480
    return (AE_OK);
481
}
482
 
483
 
484
/******************************************************************************
485
 *
486
 * FUNCTION:    AeGpeHandler
487
 *
2216 Serge 488
 * DESCRIPTION: Common GPE handler for acpiexec
1498 serge 489
 *
490
 *****************************************************************************/
491
 
492
UINT32
493
AeGpeHandler (
2216 Serge 494
    ACPI_HANDLE             GpeDevice,
495
    UINT32                  GpeNumber,
1498 serge 496
    void                    *Context)
497
{
2216 Serge 498
    ACPI_NAMESPACE_NODE     *DeviceNode = (ACPI_NAMESPACE_NODE *) GpeDevice;
499
 
500
 
501
    AcpiOsPrintf ("[AcpiExec] GPE Handler received GPE%02X (GPE block %4.4s)\n",
502
        GpeNumber, GpeDevice ? DeviceNode->Name.Ascii : "FADT");
503
 
504
    return (ACPI_REENABLE_GPE);
1498 serge 505
}
506
 
507
 
508
/******************************************************************************
509
 *
2216 Serge 510
 * FUNCTION:    AeGlobalEventHandler
511
 *
512
 * DESCRIPTION: Global GPE/Fixed event handler
513
 *
514
 *****************************************************************************/
515
 
516
void
517
AeGlobalEventHandler (
518
    UINT32                  Type,
519
    ACPI_HANDLE             Device,
520
    UINT32                  EventNumber,
521
    void                    *Context)
522
{
523
    char                    *TypeName;
524
 
525
 
526
    switch (Type)
527
    {
528
    case ACPI_EVENT_TYPE_GPE:
529
        TypeName = "GPE";
530
        break;
531
 
532
    case ACPI_EVENT_TYPE_FIXED:
533
        TypeName = "FixedEvent";
534
        break;
535
 
536
    default:
537
        TypeName = "UNKNOWN";
538
        break;
539
    }
540
 
541
    AcpiOsPrintf ("[AcpiExec] Global Event Handler received: Type %s Number %.2X Dev %p\n",
542
        TypeName, EventNumber, Device);
543
}
544
 
545
 
546
/******************************************************************************
547
 *
1498 serge 548
 * FUNCTION:    AeAttachedDataHandler
549
 *
550
 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
551
 *              AcpiAttachData)
552
 *
553
 *****************************************************************************/
554
 
2216 Serge 555
static void
1498 serge 556
AeAttachedDataHandler (
557
    ACPI_HANDLE             Object,
558
    void                    *Data)
559
{
560
    ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
561
 
562
 
563
    AcpiOsPrintf ("Received an attached data deletion on %4.4s\n",
564
        Node->Name.Ascii);
565
}
566
 
567
 
568
/******************************************************************************
569
 *
2216 Serge 570
 * FUNCTION:    AeInterfaceHandler
571
 *
572
 * DESCRIPTION: Handler for _OSI invocations
573
 *
574
 *****************************************************************************/
575
 
576
static UINT32
577
AeInterfaceHandler (
578
    ACPI_STRING             InterfaceName,
579
    UINT32                  Supported)
580
{
581
    ACPI_FUNCTION_NAME (AeInterfaceHandler);
582
 
583
 
584
    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
585
        "Received _OSI (\"%s\"), is %ssupported\n",
586
        InterfaceName, Supported == 0 ? "not " : ""));
587
 
588
    return (Supported);
589
}
590
 
591
 
592
/******************************************************************************
593
 *
594
 * FUNCTION:    AeEventHandler
595
 *
596
 * DESCRIPTION: Handler for Fixed Events
597
 *
598
 *****************************************************************************/
599
 
600
static UINT32
601
AeEventHandler (
602
    void                    *Context)
603
{
604
    return (0);
605
}
606
 
607
 
608
/******************************************************************************
609
 *
1498 serge 610
 * FUNCTION:    AeRegionInit
611
 *
612
 * PARAMETERS:  None
613
 *
614
 * RETURN:      Status
615
 *
616
 * DESCRIPTION: Opregion init function.
617
 *
618
 *****************************************************************************/
619
 
2216 Serge 620
static ACPI_STATUS
1498 serge 621
AeRegionInit (
622
    ACPI_HANDLE                 RegionHandle,
623
    UINT32                      Function,
624
    void                        *HandlerContext,
625
    void                        **RegionContext)
626
{
627
    /*
628
     * Real simple, set the RegionContext to the RegionHandle
629
     */
630
    *RegionContext = RegionHandle;
631
 
2216 Serge 632
    return (AE_OK);
1498 serge 633
}
634
 
635
 
636
/******************************************************************************
637
 *
2216 Serge 638
 * FUNCTION:    AeInstallLateHandlers
1498 serge 639
 *
640
 * PARAMETERS:  None
641
 *
642
 * RETURN:      Status
643
 *
644
 * DESCRIPTION: Install handlers for the AcpiExec utility.
645
 *
646
 *****************************************************************************/
647
 
2216 Serge 648
ACPI_STATUS
649
AeInstallLateHandlers (
650
    void)
651
{
652
    ACPI_STATUS             Status;
653
    UINT32                  i;
1498 serge 654
 
2216 Serge 655
 
656
    /* Install some fixed event handlers */
657
 
658
    Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL);
659
    AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
660
 
661
    Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL);
662
    AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
663
 
664
    /*
665
     * Install handlers for some of the "device driver" address spaces
666
     * such as EC, SMBus, etc.
667
     */
668
    for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
669
    {
670
        /* Install handler at the root object */
671
 
672
        Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode,
673
                        SpaceIdList[i], AeRegionHandler, AeRegionInit, NULL);
674
        if (ACPI_FAILURE (Status))
675
        {
676
            ACPI_EXCEPTION ((AE_INFO, Status,
677
                "Could not install an OpRegion handler for %s space(%u)",
678
                AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
679
            return (Status);
680
        }
681
    }
682
 
683
    return (AE_OK);
684
}
685
 
686
 
687
/******************************************************************************
688
 *
689
 * FUNCTION:    AeInstallEarlyHandlers
690
 *
691
 * PARAMETERS:  None
692
 *
693
 * RETURN:      Status
694
 *
695
 * DESCRIPTION: Install handlers for the AcpiExec utility.
696
 *
697
 * Notes:       Don't install handler for PCI_Config, we want to use the
698
 *              default handler to exercise that code.
699
 *
700
 *****************************************************************************/
701
 
1498 serge 702
ACPI_STATUS
2216 Serge 703
AeInstallEarlyHandlers (
704
    void)
1498 serge 705
{
706
    ACPI_STATUS             Status;
707
    UINT32                  i;
708
    ACPI_HANDLE             Handle;
709
 
710
 
711
    ACPI_FUNCTION_ENTRY ();
712
 
713
 
2216 Serge 714
    Status = AcpiInstallInterfaceHandler (AeInterfaceHandler);
715
    if (ACPI_FAILURE (Status))
716
    {
717
        printf ("Could not install interface handler, %s\n",
718
            AcpiFormatException (Status));
719
    }
720
 
1498 serge 721
    Status = AcpiInstallTableHandler (AeTableHandler, NULL);
722
    if (ACPI_FAILURE (Status))
723
    {
724
        printf ("Could not install table handler, %s\n",
725
            AcpiFormatException (Status));
726
    }
727
 
728
    Status = AcpiInstallExceptionHandler (AeExceptionHandler);
729
    if (ACPI_FAILURE (Status))
730
    {
731
        printf ("Could not install exception handler, %s\n",
732
            AcpiFormatException (Status));
733
    }
734
 
735
    /* Install global notify handler */
736
 
737
    Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
738
                                        AeNotifyHandler, NULL);
739
    if (ACPI_FAILURE (Status))
740
    {
741
        printf ("Could not install a global notify handler, %s\n",
742
            AcpiFormatException (Status));
743
    }
744
 
745
    Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
746
                                        AeDeviceNotifyHandler, NULL);
747
    if (ACPI_FAILURE (Status))
748
    {
749
        printf ("Could not install a global notify handler, %s\n",
750
            AcpiFormatException (Status));
751
    }
752
 
753
    Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
754
    if (ACPI_SUCCESS (Status))
755
    {
756
        Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
757
                                            AeNotifyHandler, NULL);
758
        if (ACPI_FAILURE (Status))
759
        {
760
            printf ("Could not install a notify handler, %s\n",
761
                AcpiFormatException (Status));
762
        }
763
 
764
        Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
765
                                            AeNotifyHandler);
766
        if (ACPI_FAILURE (Status))
767
        {
768
            printf ("Could not remove a notify handler, %s\n",
769
                AcpiFormatException (Status));
770
        }
771
 
772
        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
773
                                            AeNotifyHandler, NULL);
2216 Serge 774
        AE_CHECK_OK (AcpiInstallNotifyHandler, Status);
775
 
1498 serge 776
        Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
777
                                            AeNotifyHandler);
2216 Serge 778
        AE_CHECK_OK (AcpiRemoveNotifyHandler, Status);
779
 
1498 serge 780
        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
781
                                            AeNotifyHandler, NULL);
782
        if (ACPI_FAILURE (Status))
783
        {
784
            printf ("Could not install a notify handler, %s\n",
785
                AcpiFormatException (Status));
786
        }
787
 
788
        Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
2216 Serge 789
        AE_CHECK_OK (AcpiAttachData, Status);
790
 
1498 serge 791
        Status = AcpiDetachData (Handle, AeAttachedDataHandler);
2216 Serge 792
        AE_CHECK_OK (AcpiDetachData, Status);
793
 
1498 serge 794
        Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
2216 Serge 795
        AE_CHECK_OK (AcpiAttachData, Status);
1498 serge 796
    }
797
    else
798
    {
799
        printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
800
    }
801
 
802
 
2216 Serge 803
    /*
804
     * Install handlers that will override the default handlers for some of
805
     * the space IDs.
806
     */
807
    for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
1498 serge 808
    {
2216 Serge 809
        /* Install handler at the root object */
1498 serge 810
 
811
        Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode,
2216 Serge 812
                    DefaultSpaceIdList[i], AeRegionHandler,
813
                    AeRegionInit, NULL);
1498 serge 814
        if (ACPI_FAILURE (Status))
815
        {
816
            ACPI_EXCEPTION ((AE_INFO, Status,
2216 Serge 817
                "Could not install a default OpRegion handler for %s space(%u)",
818
                AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
819
                DefaultSpaceIdList[i]));
1498 serge 820
            return (Status);
821
        }
822
    }
823
 
824
    /*
825
     * Initialize the global Region Handler space
826
     * MCW 3/23/00
827
     */
828
    AeRegions.NumberOfRegions = 0;
829
    AeRegions.RegionList = NULL;
2216 Serge 830
    return (Status);
1498 serge 831
}
832
 
833
 
834
/******************************************************************************
835
 *
836
 * FUNCTION:    AeRegionHandler
837
 *
838
 * PARAMETERS:  Standard region handler parameters
839
 *
840
 * RETURN:      Status
841
 *
842
 * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
843
 *              be manipulated in Ring 3. Simulates actual reads and writes.
844
 *
845
 *****************************************************************************/
846
 
847
ACPI_STATUS
848
AeRegionHandler (
849
    UINT32                  Function,
850
    ACPI_PHYSICAL_ADDRESS   Address,
851
    UINT32                  BitWidth,
852
    UINT64                  *Value,
853
    void                    *HandlerContext,
854
    void                    *RegionContext)
855
{
856
 
857
    ACPI_OPERAND_OBJECT     *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
858
    UINT8                   *Buffer = ACPI_CAST_PTR (UINT8, Value);
859
    ACPI_PHYSICAL_ADDRESS   BaseAddress;
860
    ACPI_SIZE               Length;
861
    BOOLEAN                 BufferExists;
862
    AE_REGION               *RegionElement;
863
    void                    *BufferValue;
864
    ACPI_STATUS             Status;
865
    UINT32                  ByteWidth;
866
    UINT32                  i;
867
    UINT8                   SpaceId;
868
 
869
 
870
    ACPI_FUNCTION_NAME (AeRegionHandler);
871
 
872
    /*
873
     * If the object is not a region, simply return
874
     */
875
    if (RegionObject->Region.Type != ACPI_TYPE_REGION)
876
    {
2216 Serge 877
        return (AE_OK);
1498 serge 878
    }
879
 
880
    /*
881
     * Region support can be disabled with the -r option.
882
     * We use this to support dynamically loaded tables where we pass a valid
883
     * address to the AML.
884
     */
885
    if (AcpiGbl_DbOpt_NoRegionSupport)
886
    {
887
        BufferValue = ACPI_TO_POINTER (Address);
888
        ByteWidth = (BitWidth / 8);
889
 
890
        if (BitWidth % 8)
891
        {
892
            ByteWidth += 1;
893
        }
894
        goto DoFunction;
895
    }
896
 
897
    /*
898
     * Find the region's address space and length before searching
899
     * the linked list.
900
     */
901
    BaseAddress = RegionObject->Region.Address;
902
    Length = (ACPI_SIZE) RegionObject->Region.Length;
903
    SpaceId = RegionObject->Region.SpaceId;
904
 
905
    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
906
            AcpiUtGetRegionName (RegionObject->Region.SpaceId),
907
            (UINT32) Address));
908
 
909
    switch (SpaceId)
910
    {
911
    case ACPI_ADR_SPACE_SYSTEM_IO:
912
        /*
913
         * For I/O space, exercise the port validation
914
         */
915
        switch (Function & ACPI_IO_MASK)
916
        {
917
        case ACPI_READ:
918
            Status = AcpiHwReadPort (Address, (UINT32 *) Value, BitWidth);
2216 Serge 919
            AE_CHECK_OK (AcpiHwReadPort, Status);
1498 serge 920
            break;
921
 
922
        case ACPI_WRITE:
923
            Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
2216 Serge 924
            AE_CHECK_OK (AcpiHwWritePort, Status);
1498 serge 925
            break;
926
 
927
        default:
928
            Status = AE_BAD_PARAMETER;
929
            break;
930
        }
931
 
932
        if (ACPI_FAILURE (Status))
933
        {
934
            return (Status);
935
        }
936
 
937
        /* Now go ahead and simulate the hardware */
938
        break;
939
 
940
 
941
    case ACPI_ADR_SPACE_SMBUS:
942
 
943
        Length = 0;
944
 
945
        switch (Function & ACPI_IO_MASK)
946
        {
947
        case ACPI_READ:
948
            switch (Function >> 16)
949
            {
950
            case AML_FIELD_ATTRIB_SMB_QUICK:
951
            case AML_FIELD_ATTRIB_SMB_SEND_RCV:
952
            case AML_FIELD_ATTRIB_SMB_BYTE:
953
                Length = 1;
954
                break;
955
 
956
            case AML_FIELD_ATTRIB_SMB_WORD:
957
            case AML_FIELD_ATTRIB_SMB_WORD_CALL:
958
                Length = 2;
959
                break;
960
 
961
            case AML_FIELD_ATTRIB_SMB_BLOCK:
962
            case AML_FIELD_ATTRIB_SMB_BLOCK_CALL:
963
                Length = 32;
964
                break;
965
 
966
            default:
967
                break;
968
            }
969
            break;
970
 
971
        case ACPI_WRITE:
972
            switch (Function >> 16)
973
            {
974
            case AML_FIELD_ATTRIB_SMB_QUICK:
975
            case AML_FIELD_ATTRIB_SMB_SEND_RCV:
976
            case AML_FIELD_ATTRIB_SMB_BYTE:
977
            case AML_FIELD_ATTRIB_SMB_WORD:
978
            case AML_FIELD_ATTRIB_SMB_BLOCK:
979
                Length = 0;
980
                break;
981
 
982
            case AML_FIELD_ATTRIB_SMB_WORD_CALL:
983
                Length = 2;
984
                break;
985
 
986
            case AML_FIELD_ATTRIB_SMB_BLOCK_CALL:
987
                Length = 32;
988
                break;
989
 
990
            default:
991
                break;
992
            }
993
            break;
994
 
995
        default:
996
            break;
997
        }
998
 
999
        for (i = 0; i < Length; i++)
1000
        {
1001
            Buffer[i+2] = (UINT8) (0xA0 + i);
1002
        }
1003
 
1004
        Buffer[0] = 0x7A;
1005
        Buffer[1] = (UINT8) Length;
1006
        return (AE_OK);
1007
 
1008
 
1009
    case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
1010
 
1011
        AcpiOsPrintf ("AcpiExec: Received IPMI request: "
1012
            "Address %X BaseAddress %X Length %X Width %X BufferLength %u\n",
1013
            (UINT32) Address, (UINT32) BaseAddress,
1014
            Length, BitWidth, Buffer[1]);
1015
 
1016
        /*
1017
         * Regardless of a READ or WRITE, this handler is passed a 66-byte
1018
         * buffer in which to return the IPMI status/length/data.
1019
         *
1020
         * Return some example data to show use of the bidirectional buffer
1021
         */
1022
        Buffer[0] = 0;       /* Status byte */
1023
        Buffer[1] = 64;      /* Return buffer data length */
1024
        Buffer[2] = 0;       /* Completion code */
1025
        Buffer[3] = 0x34;    /* Power measurement */
1026
        Buffer[4] = 0x12;    /* Power measurement */
1027
        Buffer[65] = 0xEE;   /* last buffer byte */
1028
        return (AE_OK);
1029
 
1030
    default:
1031
        break;
1032
    }
1033
 
1034
    /*
1035
     * Search through the linked list for this region's buffer
1036
     */
1037
    BufferExists = FALSE;
1038
    RegionElement = AeRegions.RegionList;
1039
 
1040
    if (AeRegions.NumberOfRegions)
1041
    {
1042
        while (!BufferExists && RegionElement)
1043
        {
1044
            if (RegionElement->Address == BaseAddress &&
1045
                RegionElement->Length == Length &&
1046
                RegionElement->SpaceId == SpaceId)
1047
            {
1048
                BufferExists = TRUE;
1049
            }
1050
            else
1051
            {
1052
                RegionElement = RegionElement->NextRegion;
1053
            }
1054
        }
1055
    }
1056
 
1057
    /*
1058
     * If the Region buffer does not exist, create it now
1059
     */
1060
    if (!BufferExists)
1061
    {
1062
        /*
1063
         * Do the memory allocations first
1064
         */
1065
        RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
1066
        if (!RegionElement)
1067
        {
2216 Serge 1068
            return (AE_NO_MEMORY);
1498 serge 1069
        }
1070
 
1071
        RegionElement->Buffer = AcpiOsAllocate (Length);
1072
        if (!RegionElement->Buffer)
1073
        {
1074
            AcpiOsFree (RegionElement);
2216 Serge 1075
            return (AE_NO_MEMORY);
1498 serge 1076
        }
1077
 
1078
        /* Initialize the region with the default fill value */
1079
 
1080
        ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
1081
 
1082
        RegionElement->Address      = BaseAddress;
1083
        RegionElement->Length       = Length;
1084
        RegionElement->SpaceId      = SpaceId;
1085
        RegionElement->NextRegion   = NULL;
1086
 
1087
        /*
1088
         * Increment the number of regions and put this one
1089
         *  at the head of the list as it will probably get accessed
1090
         *  more often anyway.
1091
         */
1092
        AeRegions.NumberOfRegions += 1;
1093
 
1094
        if (AeRegions.RegionList)
1095
        {
1096
            RegionElement->NextRegion = AeRegions.RegionList;
1097
        }
1098
 
1099
        AeRegions.RegionList = RegionElement;
1100
    }
1101
 
1102
    /*
1103
     * Calculate the size of the memory copy
1104
     */
1105
    ByteWidth = (BitWidth / 8);
1106
 
1107
    if (BitWidth % 8)
1108
    {
1109
        ByteWidth += 1;
1110
    }
1111
 
1112
    /*
1113
     * The buffer exists and is pointed to by RegionElement.
1114
     * We now need to verify the request is valid and perform the operation.
1115
     *
1116
     * NOTE: RegionElement->Length is in bytes, therefore it we compare against
1117
     * ByteWidth (see above)
1118
     */
1119
    if (((UINT64) Address + ByteWidth) >
1120
        ((UINT64)(RegionElement->Address) + RegionElement->Length))
1121
    {
1122
        ACPI_WARNING ((AE_INFO,
1123
            "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
1124
            (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
1125
            ByteWidth, (UINT32)(RegionElement->Address),
1126
            RegionElement->Length));
1127
 
2216 Serge 1128
        return (AE_AML_REGION_LIMIT);
1498 serge 1129
    }
1130
 
1131
    /*
1132
     * Get BufferValue to point to the "address" in the buffer
1133
     */
1134
    BufferValue = ((UINT8 *) RegionElement->Buffer +
1135
                    ((UINT64) Address - (UINT64) RegionElement->Address));
1136
 
1137
DoFunction:
1138
 
1139
    /*
1140
     * Perform a read or write to the buffer space
1141
     */
1142
    switch (Function)
1143
    {
1144
    case ACPI_READ:
1145
        /*
1146
         * Set the pointer Value to whatever is in the buffer
1147
         */
1148
        ACPI_MEMCPY (Value, BufferValue, ByteWidth);
1149
        break;
1150
 
1151
    case ACPI_WRITE:
1152
        /*
1153
         * Write the contents of Value to the buffer
1154
         */
1155
        ACPI_MEMCPY (BufferValue, Value, ByteWidth);
1156
        break;
1157
 
1158
    default:
2216 Serge 1159
        return (AE_BAD_PARAMETER);
1498 serge 1160
    }
2216 Serge 1161
 
1162
    return (AE_OK);
1498 serge 1163
}
1164