Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
 
2
 *
3
 * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
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
119
 
120
        ACPI_MODULE_NAME    ("hwsleep")
121
122
 
123
 
124
 *
125
 * FUNCTION:    AcpiSetFirmwareWakingVector
126
 *
127
 * PARAMETERS:  PhysicalAddress     - 32-bit physical address of ACPI real mode
128
 *                                    entry point.
129
 *
130
 * RETURN:      Status
131
 *
132
 * DESCRIPTION: Sets the 32-bit FirmwareWakingVector field of the FACS
133
 *
134
 ******************************************************************************/
135
136
 
137
AcpiSetFirmwareWakingVector (
138
    UINT32                  PhysicalAddress)
139
{
140
    ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector);
141
142
 
143
 
144
145
 
146
147
 
148
149
 
150
    {
151
        AcpiGbl_FACS->XFirmwareWakingVector = 0;
152
    }
153
154
 
155
}
156
157
 
158
159
 
160
 
161
/*******************************************************************************
162
 *
163
 * FUNCTION:    AcpiSetFirmwareWakingVector64
164
 *
165
 * PARAMETERS:  PhysicalAddress     - 64-bit physical address of ACPI protected
166
 *                                    mode entry point.
167
 *
168
 * RETURN:      Status
169
 *
170
 * DESCRIPTION: Sets the 64-bit X_FirmwareWakingVector field of the FACS, if
171
 *              it exists in the table. This function is intended for use with
172
 *              64-bit host operating systems.
173
 *
174
 ******************************************************************************/
175
176
 
177
AcpiSetFirmwareWakingVector64 (
178
    UINT64                  PhysicalAddress)
179
{
180
    ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector64);
181
182
 
183
 
184
185
 
186
    {
187
        return_ACPI_STATUS (AE_NOT_EXIST);
188
    }
189
190
 
191
192
 
193
    AcpiGbl_FACS->XFirmwareWakingVector = PhysicalAddress;
194
    return_ACPI_STATUS (AE_OK);
195
}
196
197
 
198
#endif
199
200
 
201
 *
202
 * FUNCTION:    AcpiEnterSleepStatePrep
203
 *
204
 * PARAMETERS:  SleepState          - Which sleep state to enter
205
 *
206
 * RETURN:      Status
207
 *
208
 * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231)
209
 *              This function must execute with interrupts enabled.
210
 *              We break sleeping into 2 stages so that OSPM can handle
211
 *              various OS-specific tasks between the two steps.
212
 *
213
 ******************************************************************************/
214
215
 
216
AcpiEnterSleepStatePrep (
217
    UINT8                   SleepState)
218
{
219
    ACPI_STATUS             Status;
220
    ACPI_OBJECT_LIST        ArgList;
221
    ACPI_OBJECT             Arg;
222
223
 
224
 
225
226
 
227
 
228
229
 
230
                    &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);
231
    if (ACPI_FAILURE (Status))
232
    {
233
        return_ACPI_STATUS (Status);
234
    }
235
236
 
237
238
 
239
    ArgList.Pointer = &Arg;
240
    Arg.Type = ACPI_TYPE_INTEGER;
241
    Arg.Integer.Value = SleepState;
242
243
 
244
    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
245
    {
246
        return_ACPI_STATUS (Status);
247
    }
248
249
 
250
251
 
252
    {
253
    case ACPI_STATE_S0:
254
        Arg.Integer.Value = ACPI_SST_WORKING;
255
        break;
256
257
 
258
    case ACPI_STATE_S2:
259
    case ACPI_STATE_S3:
260
        Arg.Integer.Value = ACPI_SST_SLEEPING;
261
        break;
262
263
 
264
        Arg.Integer.Value = ACPI_SST_SLEEP_CONTEXT;
265
        break;
266
267
 
268
        Arg.Integer.Value = ACPI_SST_INDICATOR_OFF; /* Default is off */
269
        break;
270
    }
271
272
 
273
     * Set the system indicators to show the desired sleep state.
274
     * _SST is an optional method (return no error if not found)
275
     */
276
    Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);
277
    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
278
    {
279
        ACPI_EXCEPTION ((AE_INFO, Status, "While executing method _SST"));
280
    }
281
282
 
283
}
284
285
 
286
287
 
288
 
289
 *
290
 * FUNCTION:    AcpiEnterSleepState
291
 *
292
 * PARAMETERS:  SleepState          - Which sleep state to enter
293
 *
294
 * RETURN:      Status
295
 *
296
 * DESCRIPTION: Enter a system sleep state
297
 *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
298
 *
299
 ******************************************************************************/
300
301
 
302
AcpiEnterSleepState (
303
    UINT8                   SleepState)
304
{
305
    UINT32                  Pm1aControl;
306
    UINT32                  Pm1bControl;
307
    ACPI_BIT_REGISTER_INFO  *SleepTypeRegInfo;
308
    ACPI_BIT_REGISTER_INFO  *SleepEnableRegInfo;
309
    UINT32                  InValue;
310
    ACPI_OBJECT_LIST        ArgList;
311
    ACPI_OBJECT             Arg;
312
    ACPI_STATUS             Status;
313
314
 
315
 
316
317
 
318
 
319
        (AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX))
320
    {
321
        ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
322
            AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB));
323
        return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
324
    }
325
326
 
327
    SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
328
329
 
330
331
 
332
    if (ACPI_FAILURE (Status))
333
    {
334
        return_ACPI_STATUS (Status);
335
    }
336
337
 
338
339
 
340
    if (ACPI_FAILURE (Status))
341
    {
342
        return_ACPI_STATUS (Status);
343
    }
344
345
 
346
    {
347
        /*
348
         * Disable BM arbitration. This feature is contained within an
349
         * optional register (PM2 Control), so ignore a BAD_ADDRESS
350
         * exception.
351
         */
352
        Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 1);
353
        if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS))
354
        {
355
            return_ACPI_STATUS (Status);
356
        }
357
    }
358
359
 
360
     * 1) Disable/Clear all GPEs
361
     * 2) Enable all wakeup GPEs
362
     */
363
    Status = AcpiHwDisableAllGpes ();
364
    if (ACPI_FAILURE (Status))
365
    {
366
        return_ACPI_STATUS (Status);
367
    }
368
    AcpiGbl_SystemAwakeAndRunning = FALSE;
369
370
 
371
    if (ACPI_FAILURE (Status))
372
    {
373
        return_ACPI_STATUS (Status);
374
    }
375
376
 
377
378
 
379
    ArgList.Pointer = &Arg;
380
    Arg.Type = ACPI_TYPE_INTEGER;
381
    Arg.Integer.Value = SleepState;
382
383
 
384
    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
385
    {
386
        return_ACPI_STATUS (Status);
387
    }
388
389
 
390
391
 
392
                &Pm1aControl);
393
    if (ACPI_FAILURE (Status))
394
    {
395
        return_ACPI_STATUS (Status);
396
    }
397
    ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
398
        "Entering sleep state [S%u]\n", SleepState));
399
400
 
401
402
 
403
                     SleepEnableRegInfo->AccessBitMask);
404
    Pm1bControl = Pm1aControl;
405
406
 
407
408
 
409
    Pm1bControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition);
410
411
 
412
     * We split the writes of SLP_TYP and SLP_EN to workaround
413
     * poorly implemented hardware.
414
     */
415
416
 
417
418
 
419
    if (ACPI_FAILURE (Status))
420
    {
421
        return_ACPI_STATUS (Status);
422
    }
423
424
 
425
426
 
427
    Pm1bControl |= SleepEnableRegInfo->AccessBitMask;
428
429
 
430
431
 
432
433
 
434
435
 
436
    if (ACPI_FAILURE (Status))
437
    {
438
        return_ACPI_STATUS (Status);
439
    }
440
441
 
442
    {
443
        /*
444
         * We wanted to sleep > S3, but it didn't happen (by virtue of the
445
         * fact that we are still executing!)
446
         *
447
         * Wait ten seconds, then try again. This is to get S4/S5 to work on
448
         * all machines.
449
         *
450
         * We wait so long to allow chipsets that poll this reg very slowly
451
         * to still read the right value. Ideally, this block would go
452
         * away entirely.
453
         */
454
        AcpiOsStall (10000000);
455
456
 
457
                    SleepEnableRegInfo->AccessBitMask);
458
        if (ACPI_FAILURE (Status))
459
        {
460
            return_ACPI_STATUS (Status);
461
        }
462
    }
463
464
 
465
466
 
467
    {
468
        Status = AcpiReadBitRegister (ACPI_BITREG_WAKE_STATUS, &InValue);
469
        if (ACPI_FAILURE (Status))
470
        {
471
            return_ACPI_STATUS (Status);
472
        }
473
474
 
475
476
 
477
478
 
479
}
480
481
 
482
483
 
484
 
485
 *
486
 * FUNCTION:    AcpiEnterSleepStateS4bios
487
 *
488
 * PARAMETERS:  None
489
 *
490
 * RETURN:      Status
491
 *
492
 * DESCRIPTION: Perform a S4 bios request.
493
 *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
494
 *
495
 ******************************************************************************/
496
497
 
498
AcpiEnterSleepStateS4bios (
499
    void)
500
{
501
    UINT32                  InValue;
502
    ACPI_STATUS             Status;
503
504
 
505
 
506
507
 
508
 
509
510
 
511
    if (ACPI_FAILURE (Status))
512
    {
513
        return_ACPI_STATUS (Status);
514
    }
515
516
 
517
    if (ACPI_FAILURE (Status))
518
    {
519
        return_ACPI_STATUS (Status);
520
    }
521
522
 
523
     * 1) Disable/Clear all GPEs
524
     * 2) Enable all wakeup GPEs
525
     */
526
    Status = AcpiHwDisableAllGpes ();
527
    if (ACPI_FAILURE (Status))
528
    {
529
        return_ACPI_STATUS (Status);
530
    }
531
    AcpiGbl_SystemAwakeAndRunning = FALSE;
532
533
 
534
    if (ACPI_FAILURE (Status))
535
    {
536
        return_ACPI_STATUS (Status);
537
    }
538
539
 
540
541
 
542
                (UINT32) AcpiGbl_FADT.S4BiosRequest, 8);
543
544
 
545
        AcpiOsStall(1000);
546
        Status = AcpiReadBitRegister (ACPI_BITREG_WAKE_STATUS, &InValue);
547
        if (ACPI_FAILURE (Status))
548
        {
549
            return_ACPI_STATUS (Status);
550
        }
551
    } while (!InValue);
552
553
 
554
}
555
556
 
557
558
 
559
 
560
 *
561
 * FUNCTION:    AcpiLeaveSleepState
562
 *
563
 * PARAMETERS:  SleepState          - Which sleep state we just exited
564
 *
565
 * RETURN:      Status
566
 *
567
 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
568
 *              Called with interrupts ENABLED.
569
 *
570
 ******************************************************************************/
571
572
 
573
AcpiLeaveSleepState (
574
    UINT8                   SleepState)
575
{
576
    ACPI_OBJECT_LIST        ArgList;
577
    ACPI_OBJECT             Arg;
578
    ACPI_STATUS             Status;
579
    ACPI_BIT_REGISTER_INFO  *SleepTypeRegInfo;
580
    ACPI_BIT_REGISTER_INFO  *SleepEnableRegInfo;
581
    UINT32                  Pm1aControl;
582
    UINT32                  Pm1bControl;
583
584
 
585
 
586
587
 
588
 
589
     * Set SLP_TYPE and SLP_EN to state S0.
590
     * This is unclear from the ACPI Spec, but it is required
591
     * by some machines.
592
     */
593
    Status = AcpiGetSleepTypeData (ACPI_STATE_S0,
594
                    &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);
595
    if (ACPI_SUCCESS (Status))
596
    {
597
        SleepTypeRegInfo =
598
            AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE);
599
        SleepEnableRegInfo =
600
            AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
601
602
 
603
604
 
605
                    &Pm1aControl);
606
        if (ACPI_SUCCESS (Status))
607
        {
608
            /* Clear the SLP_EN and SLP_TYP fields */
609
610
 
611
                SleepEnableRegInfo->AccessBitMask);
612
            Pm1bControl = Pm1aControl;
613
614
 
615
616
 
617
                SleepTypeRegInfo->BitPosition);
618
            Pm1bControl |= (AcpiGbl_SleepTypeB <<
619
                SleepTypeRegInfo->BitPosition);
620
621
 
622
623
 
624
        }
625
    }
626
627
 
628
629
 
630
631
 
632
633
 
634
    ArgList.Pointer = &Arg;
635
    Arg.Type = ACPI_TYPE_INTEGER;
636
637
 
638
639
 
640
    Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);
641
    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
642
    {
643
        ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST"));
644
    }
645
646
 
647
    Status = AcpiEvaluateObject (NULL, METHOD_NAME__BFS, &ArgList, NULL);
648
    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
649
    {
650
        ACPI_EXCEPTION ((AE_INFO, Status, "During Method _BFS"));
651
    }
652
653
 
654
    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
655
    {
656
        ACPI_EXCEPTION ((AE_INFO, Status, "During Method _WAK"));
657
    }
658
    /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
659
660
 
661
     * Restore the GPEs:
662
     * 1) Disable/Clear all GPEs
663
     * 2) Enable all runtime GPEs
664
     */
665
    Status = AcpiHwDisableAllGpes ();
666
    if (ACPI_FAILURE (Status))
667
    {
668
        return_ACPI_STATUS (Status);
669
    }
670
    AcpiGbl_SystemAwakeAndRunning = TRUE;
671
672
 
673
    if (ACPI_FAILURE (Status))
674
    {
675
        return_ACPI_STATUS (Status);
676
    }
677
678
 
679
680
 
681
            AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].EnableRegisterId,
682
            ACPI_ENABLE_EVENT);
683
684
 
685
            AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId,
686
            ACPI_CLEAR_STATUS);
687
688
 
689
     * Enable BM arbitration. This feature is contained within an
690
     * optional register (PM2 Control), so ignore a BAD_ADDRESS
691
     * exception.
692
     */
693
    Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 0);
694
    if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS))
695
    {
696
        return_ACPI_STATUS (Status);
697
    }
698
699
 
700
    Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);
701
    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
702
    {
703
        ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST"));
704
    }
705
706
 
707
}
708
709
 
710
>
711