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: hwxface - Public ACPICA hardware interfaces
4
 *
5
 *****************************************************************************/
6
7
 
8
 *
9
 * 1. Copyright Notice
10
 *
11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
2216 Serge 12
 * All rights reserved.
1498 serge 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
 
117
#include "accommon.h"
118
#include "acnamesp.h"
119
120
 
121
        ACPI_MODULE_NAME    ("hwxface")
122
123
 
124
 
125
 *
126
 * FUNCTION:    AcpiReset
127
 *
128
 * PARAMETERS:  None
129
 *
130
 * RETURN:      Status
131
 *
132
 * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
133
 *              support reset register in PCI config space, this must be
134
 *              handled separately.
135
 *
136
 ******************************************************************************/
137
138
 
139
AcpiReset (
140
    void)
141
{
142
    ACPI_GENERIC_ADDRESS    *ResetReg;
143
    ACPI_STATUS             Status;
144
145
 
146
 
147
148
 
149
 
150
151
 
152
153
 
154
        !ResetReg->Address)
155
    {
156
        return_ACPI_STATUS (AE_NOT_EXIST);
157
    }
158
159
 
160
    {
161
        /*
162
         * For I/O space, write directly to the OSL. This bypasses the port
163
         * validation mechanism, which may block a valid write to the reset
164
         * register.
165
         */
166
        Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
167
                    AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
168
    }
169
    else
170
    {
171
        /* Write the reset value to the reset register */
172
173
 
174
    }
175
176
 
177
}
178
179
 
180
181
 
182
 
183
 *
184
 * FUNCTION:    AcpiRead
185
 *
186
 * PARAMETERS:  Value               - Where the value is returned
187
 *              Reg                 - GAS register structure
188
 *
189
 * RETURN:      Status
190
 *
191
 * DESCRIPTION: Read from either memory or IO space.
192
 *
193
 * LIMITATIONS: 
194
 *      BitWidth must be exactly 8, 16, 32, or 64.
195
 *      SpaceID must be SystemMemory or SystemIO.
196
 *      BitOffset and AccessWidth are currently ignored, as there has
197
 *          not been a need to implement these.
198
 *
199
 ******************************************************************************/
200
201
 
202
AcpiRead (
203
    UINT64                  *ReturnValue,
204
    ACPI_GENERIC_ADDRESS    *Reg)
205
{
206
    UINT32                  Value;
207
    UINT32                  Width;
208
    UINT64                  Address;
209
    ACPI_STATUS             Status;
210
211
 
212
 
213
214
 
215
 
216
    {
217
        return (AE_BAD_PARAMETER);
218
    }
219
220
 
221
222
 
223
    if (ACPI_FAILURE (Status))
224
    {
225
        return (Status);
226
    }
227
228
 
229
    if (Width == 64)
230
    {
231
        Width = 32; /* Break into two 32-bit transfers */
232
    }
233
234
 
235
236
 
237
    Value = 0;
238
239
 
240
     * Two address spaces supported: Memory or IO. PCI_Config is
241
     * not supported here because the GAS structure is insufficient
242
     */
243
    if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
244
    {
245
        Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
246
                    Address, &Value, Width);
247
        if (ACPI_FAILURE (Status))
248
        {
249
            return (Status);
250
        }
251
        *ReturnValue = Value;
252
253
 
254
        {
255
            /* Read the top 32 bits */
256
257
 
258
                        (Address + 4), &Value, 32);
259
            if (ACPI_FAILURE (Status))
260
            {
261
                return (Status);
262
            }
263
            *ReturnValue |= ((UINT64) Value << 32);
264
        }
265
    }
266
    else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
267
    {
268
        Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
269
                    Address, &Value, Width);
270
        if (ACPI_FAILURE (Status))
271
        {
272
            return (Status);
273
        }
274
        *ReturnValue = Value;
275
276
 
277
        {
278
            /* Read the top 32 bits */
279
280
 
281
                        (Address + 4), &Value, 32);
282
            if (ACPI_FAILURE (Status))
283
            {
284
                return (Status);
285
            }
286
            *ReturnValue |= ((UINT64) Value << 32);
287
        }
288
    }
289
290
 
291
        "Read:  %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
292
        ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
293
        ACPI_FORMAT_UINT64 (Address),
294
        AcpiUtGetRegionName (Reg->SpaceId)));
295
296
 
297
}
298
299
 
300
301
 
302
 
303
 *
304
 * FUNCTION:    AcpiWrite
305
 *
306
 * PARAMETERS:  Value               - Value to be written
307
 *              Reg                 - GAS register structure
308
 *
309
 * RETURN:      Status
310
 *
311
 * DESCRIPTION: Write to either memory or IO space.
312
 *
313
 ******************************************************************************/
314
315
 
316
AcpiWrite (
317
    UINT64                  Value,
318
    ACPI_GENERIC_ADDRESS    *Reg)
319
{
320
    UINT32                  Width;
321
    UINT64                  Address;
322
    ACPI_STATUS             Status;
323
324
 
325
 
326
327
 
328
 
329
330
 
331
    if (ACPI_FAILURE (Status))
332
    {
333
        return (Status);
334
    }
335
336
 
337
    if (Width == 64)
338
    {
339
        Width = 32; /* Break into two 32-bit transfers */
340
    }
341
342
 
343
     * Two address spaces supported: Memory or IO. PCI_Config is
344
     * not supported here because the GAS structure is insufficient
345
     */
346
    if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
347
    {
348
        Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
349
                    Address, ACPI_LODWORD (Value), Width);
350
        if (ACPI_FAILURE (Status))
351
        {
352
            return (Status);
353
        }
354
355
 
356
        {
357
            Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
358
                        (Address + 4), ACPI_HIDWORD (Value), 32);
359
            if (ACPI_FAILURE (Status))
360
            {
361
                return (Status);
362
            }
363
        }
364
    }
365
    else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
366
    {
367
        Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
368
                    Address, ACPI_LODWORD (Value), Width);
369
        if (ACPI_FAILURE (Status))
370
        {
371
            return (Status);
372
        }
373
374
 
375
        {
376
            Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
377
                        (Address + 4), ACPI_HIDWORD (Value), 32);
378
            if (ACPI_FAILURE (Status))
379
            {
380
                return (Status);
381
            }
382
        }
383
    }
384
385
 
386
        "Wrote: %8.8X%8.8X width %2d   to %8.8X%8.8X (%s)\n",
387
        ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
388
        ACPI_FORMAT_UINT64 (Address),
389
        AcpiUtGetRegionName (Reg->SpaceId)));
390
391
 
392
}
393
394
 
395
396
 
397
 
398
 *
399
 * FUNCTION:    AcpiReadBitRegister
400
 *
401
 * PARAMETERS:  RegisterId      - ID of ACPI Bit Register to access
402
 *              ReturnValue     - Value that was read from the register,
403
 *                                normalized to bit position zero.
404
 *
405
 * RETURN:      Status and the value read from the specified Register. Value
406
 *              returned is normalized to bit0 (is shifted all the way right)
407
 *
408
 * DESCRIPTION: ACPI BitRegister read function. Does not acquire the HW lock.
409
 *
410
 * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
411
 *              PM2 Control.
412
 *
413
 * Note: The hardware lock is not required when reading the ACPI bit registers
414
 *       since almost all of them are single bit and it does not matter that
415
 *       the parent hardware register can be split across two physical
416
 *       registers. The only multi-bit field is SLP_TYP in the PM1 control
417
 *       register, but this field does not cross an 8-bit boundary (nor does
418
 *       it make much sense to actually read this field.)
419
 *
420
 ******************************************************************************/
421
422
 
423
AcpiReadBitRegister (
424
    UINT32                  RegisterId,
425
    UINT32                  *ReturnValue)
426
{
427
    ACPI_BIT_REGISTER_INFO  *BitRegInfo;
428
    UINT32                  RegisterValue;
429
    UINT32                  Value;
430
    ACPI_STATUS             Status;
431
432
 
433
 
434
435
 
436
 
437
438
 
439
    if (!BitRegInfo)
440
    {
441
        return_ACPI_STATUS (AE_BAD_PARAMETER);
442
    }
443
444
 
445
446
 
447
                &RegisterValue);
448
    if (ACPI_FAILURE (Status))
449
    {
450
        return_ACPI_STATUS (Status);
451
    }
452
453
 
454
455
 
456
                >> BitRegInfo->BitPosition);
457
458
 
459
        "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
460
        RegisterId, BitRegInfo->ParentRegister, RegisterValue, Value));
461
462
 
463
    return_ACPI_STATUS (AE_OK);
464
}
465
466
 
467
468
 
469
 
470
 *
471
 * FUNCTION:    AcpiWriteBitRegister
472
 *
473
 * PARAMETERS:  RegisterId      - ID of ACPI Bit Register to access
474
 *              Value           - Value to write to the register, in bit
475
 *                                position zero. The bit is automaticallly
476
 *                                shifted to the correct position.
477
 *
478
 * RETURN:      Status
479
 *
480
 * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
481
 *              since most operations require a read/modify/write sequence.
482
 *
483
 * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
484
 *              PM2 Control.
485
 *
486
 * Note that at this level, the fact that there may be actually two
487
 * hardware registers (A and B - and B may not exist) is abstracted.
488
 *
489
 ******************************************************************************/
490
491
 
492
AcpiWriteBitRegister (
493
    UINT32                  RegisterId,
494
    UINT32                  Value)
495
{
496
    ACPI_BIT_REGISTER_INFO  *BitRegInfo;
497
    ACPI_CPU_FLAGS          LockFlags;
498
    UINT32                  RegisterValue;
499
    ACPI_STATUS             Status = AE_OK;
500
501
 
502
 
503
504
 
505
 
506
507
 
508
    if (!BitRegInfo)
509
    {
510
        return_ACPI_STATUS (AE_BAD_PARAMETER);
511
    }
512
513
 
514
515
 
516
     * At this point, we know that the parent register is one of the
517
     * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
518
     */
519
    if (BitRegInfo->ParentRegister != ACPI_REGISTER_PM1_STATUS)
520
    {
521
        /*
522
         * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
523
         *
524
         * Perform a register read to preserve the bits that we are not
525
         * interested in
526
         */
527
        Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister,
528
                    &RegisterValue);
529
        if (ACPI_FAILURE (Status))
530
        {
531
            goto UnlockAndExit;
532
        }
533
534
 
535
         * Insert the input bit into the value that was just read
536
         * and write the register
537
         */
538
        ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
539
            BitRegInfo->AccessBitMask, Value);
540
541
 
542
                    RegisterValue);
543
    }
544
    else
545
    {
546
        /*
547
         * 2) Case for PM1 Status
548
         *
549
         * The Status register is different from the rest. Clear an event
550
         * by writing 1, writing 0 has no effect. So, the only relevant
551
         * information is the single bit we're interested in, all others
552
         * should be written as 0 so they will be left unchanged.
553
         */
554
        RegisterValue = ACPI_REGISTER_PREPARE_BITS (Value,
555
            BitRegInfo->BitPosition, BitRegInfo->AccessBitMask);
556
557
 
558
559
 
560
        {
561
            Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
562
                        RegisterValue);
563
        }
564
    }
565
566
 
567
        "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
568
        RegisterId, BitRegInfo->ParentRegister, Value, RegisterValue));
569
570
 
571
 
572
573
 
574
    return_ACPI_STATUS (Status);
575
}
576
577
 
578
579
 
580
 
581
 *
582
 * FUNCTION:    AcpiGetSleepTypeData
583
 *
584
 * PARAMETERS:  SleepState          - Numeric sleep state
585
 *              *SleepTypeA         - Where SLP_TYPa is returned
586
 *              *SleepTypeB         - Where SLP_TYPb is returned
587
 *
588
 * RETURN:      Status - ACPI status
589
 *
590
 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
591
 *              state.
592
 *
593
 ******************************************************************************/
594
595
 
596
AcpiGetSleepTypeData (
597
    UINT8                   SleepState,
598
    UINT8                   *SleepTypeA,
599
    UINT8                   *SleepTypeB)
600
{
601
    ACPI_STATUS             Status = AE_OK;
602
    ACPI_EVALUATE_INFO      *Info;
603
604
 
605
 
606
607
 
608
 
609
610
 
611
        !SleepTypeA ||
612
        !SleepTypeB)
613
    {
614
        return_ACPI_STATUS (AE_BAD_PARAMETER);
615
    }
616
617
 
618
619
 
620
    if (!Info)
621
    {
622
        return_ACPI_STATUS (AE_NO_MEMORY);
623
    }
624
625
 
626
627
 
628
629
 
630
    if (ACPI_FAILURE (Status))
631
    {
632
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
633
            "%s while evaluating SleepState [%s]\n",
634
            AcpiFormatException (Status), Info->Pathname));
635
636
 
637
    }
638
639
 
640
641
 
642
    {
643
        ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
644
            Info->Pathname));
645
        Status = AE_NOT_EXIST;
646
    }
647
648
 
649
650
 
651
    {
652
        ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package"));
653
        Status = AE_AML_OPERAND_TYPE;
654
    }
655
656
 
657
     * The package must have at least two elements. NOTE (March 2005): This
658
     * goes against the current ACPI spec which defines this object as a
659
     * package with one encoded DWORD element. However, existing practice
660
     * by BIOS vendors seems to be to have 2 or more elements, at least
661
     * one per sleep type (A/B).
662
     */
663
    else if (Info->ReturnObject->Package.Count < 2)
664
    {
665
        ACPI_ERROR ((AE_INFO,
666
            "Sleep State return package does not have at least two elements"));
667
        Status = AE_AML_NO_OPERAND;
668
    }
669
670
 
671
672
 
673
                != ACPI_TYPE_INTEGER) ||
674
             ((Info->ReturnObject->Package.Elements[1])->Common.Type
675
                != ACPI_TYPE_INTEGER))
676
    {
677
        ACPI_ERROR ((AE_INFO,
678
            "Sleep State return package elements are not both Integers "
679
            "(%s, %s)",
680
            AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[0]),
681
            AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[1])));
682
        Status = AE_AML_OPERAND_TYPE;
683
    }
684
    else
685
    {
686
        /* Valid _Sx_ package size, type, and value */
687
688
 
689
            (Info->ReturnObject->Package.Elements[0])->Integer.Value;
690
        *SleepTypeB = (UINT8)
691
            (Info->ReturnObject->Package.Elements[1])->Integer.Value;
692
    }
693
694
 
695
    {
696
        ACPI_EXCEPTION ((AE_INFO, Status,
697
            "While evaluating SleepState [%s], bad Sleep object %p type %s",
698
            Info->Pathname, Info->ReturnObject,
699
            AcpiUtGetObjectTypeName (Info->ReturnObject)));
700
    }
701
702
 
703
704
 
705
    ACPI_FREE (Info);
706
    return_ACPI_STATUS (Status);
707
}
708
709
 
710