Subversion Repositories Kolibri OS

Rev

Rev 1498 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1498 Rev 2216
1
/*******************************************************************************
1
/*******************************************************************************
2
 *
2
 *
3
 * Module Name: hwregs - Read/write access functions for the various ACPI
3
 * Module Name: hwregs - Read/write access functions for the various ACPI
4
 *                       control and status registers.
4
 *                       control and status registers.
5
 *
5
 *
6
 ******************************************************************************/
6
 ******************************************************************************/
7
 
7
 
8
/******************************************************************************
8
/******************************************************************************
9
 *
9
 *
10
 * 1. Copyright Notice
10
 * 1. Copyright Notice
11
 *
11
 *
12
 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
13
 * All rights reserved.
13
 * All rights reserved.
14
 *
14
 *
15
 * 2. License
15
 * 2. License
16
 *
16
 *
17
 * 2.1. This is your license from Intel Corp. under its intellectual property
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
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
19
 * you this software, covering your right to use that party's intellectual
20
 * property rights.
20
 * property rights.
21
 *
21
 *
22
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
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
23
 * copy of the source code appearing in this file ("Covered Code") an
24
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * base code distributed originally by Intel ("Original Intel Code") to copy,
26
 * make derivatives, distribute, use and display any portion of the Covered
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
27
 * Code in any form, with the right to sublicense such rights; and
28
 *
28
 *
29
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
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
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,
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
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
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
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
35
 * to or modifications of the Original Intel Code.  No other license or right
36
 * is granted directly or by implication, estoppel or otherwise;
36
 * is granted directly or by implication, estoppel or otherwise;
37
 *
37
 *
38
 * The above copyright and patent license is granted only if the following
38
 * The above copyright and patent license is granted only if the following
39
 * conditions are met:
39
 * conditions are met:
40
 *
40
 *
41
 * 3. Conditions
41
 * 3. Conditions
42
 *
42
 *
43
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44
 * Redistribution of source code of any substantial portion of the Covered
44
 * Redistribution of source code of any substantial portion of the Covered
45
 * Code or modification with rights to further distribute source must include
45
 * Code or modification with rights to further distribute source must include
46
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * the above Copyright Notice, the above License, this list of Conditions,
47
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * and the following Disclaimer and Export Compliance provision.  In addition,
48
 * Licensee must cause all Covered Code to which Licensee contributes to
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
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
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
51
 * documentation of any changes made by any predecessor Licensee.  Licensee
52
 * must include a prominent statement that the modification is derived,
52
 * must include a prominent statement that the modification is derived,
53
 * directly or indirectly, from Original Intel Code.
53
 * directly or indirectly, from Original Intel Code.
54
 *
54
 *
55
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
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
56
 * Redistribution of source code of any substantial portion of the Covered
57
 * Code or modification without rights to further distribute source must
57
 * Code or modification without rights to further distribute source must
58
 * include the following Disclaimer and Export Compliance provision in the
58
 * include the following Disclaimer and Export Compliance provision in the
59
 * documentation and/or other materials provided with distribution.  In
59
 * documentation and/or other materials provided with distribution.  In
60
 * addition, Licensee may not authorize further sublicense of source of any
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
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
62
 * license from Licensee to its licensee is limited to the intellectual
63
 * property embodied in the software Licensee provides to its licensee, and
63
 * property embodied in the software Licensee provides to its licensee, and
64
 * not to intellectual property embodied in modifications its licensee may
64
 * not to intellectual property embodied in modifications its licensee may
65
 * make.
65
 * make.
66
 *
66
 *
67
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68
 * substantial portion of the Covered Code or modification must reproduce the
68
 * substantial portion of the Covered Code or modification must reproduce the
69
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * above Copyright Notice, and the following Disclaimer and Export Compliance
70
 * provision in the documentation and/or other materials provided with the
70
 * provision in the documentation and/or other materials provided with the
71
 * distribution.
71
 * distribution.
72
 *
72
 *
73
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * 3.4. Intel retains all right, title, and interest in and to the Original
74
 * Intel Code.
74
 * Intel Code.
75
 *
75
 *
76
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
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
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
78
 * other dealings in products derived from or relating to the Covered Code
79
 * without prior written authorization from Intel.
79
 * without prior written authorization from Intel.
80
 *
80
 *
81
 * 4. Disclaimer and Export Compliance
81
 * 4. Disclaimer and Export Compliance
82
 *
82
 *
83
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
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
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,
85
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89
 * PARTICULAR PURPOSE.
89
 * PARTICULAR PURPOSE.
90
 *
90
 *
91
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
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
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,
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
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
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
96
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98
 * LIMITED REMEDY.
98
 * LIMITED REMEDY.
99
 *
99
 *
100
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
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
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
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
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
104
 * event Licensee exports any such software from the United States or
105
 * re-exports any such software from a foreign destination, Licensee shall
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
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
107
 * compliance with all laws, regulations, orders, or other restrictions of the
108
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
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,
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
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,
111
 * United States government or any agency thereof requires an export license,
112
 * other governmental approval, or letter of assurance, without first obtaining
112
 * other governmental approval, or letter of assurance, without first obtaining
113
 * such license, approval or letter.
113
 * such license, approval or letter.
114
 *
114
 *
115
 *****************************************************************************/
115
 *****************************************************************************/
116
 
116
 
117
#define __HWREGS_C__
117
#define __HWREGS_C__
118
 
118
 
119
#include "acpi.h"
119
#include "acpi.h"
120
#include "accommon.h"
120
#include "accommon.h"
121
#include "acevents.h"
121
#include "acevents.h"
122
 
122
 
123
#define _COMPONENT          ACPI_HARDWARE
123
#define _COMPONENT          ACPI_HARDWARE
124
        ACPI_MODULE_NAME    ("hwregs")
124
        ACPI_MODULE_NAME    ("hwregs")
125
 
125
 
126
 
126
 
127
/* Local Prototypes */
127
/* Local Prototypes */
128
 
128
 
129
static ACPI_STATUS
129
static ACPI_STATUS
130
AcpiHwReadMultiple (
130
AcpiHwReadMultiple (
131
    UINT32                  *Value,
131
    UINT32                  *Value,
132
    ACPI_GENERIC_ADDRESS    *RegisterA,
132
    ACPI_GENERIC_ADDRESS    *RegisterA,
133
    ACPI_GENERIC_ADDRESS    *RegisterB);
133
    ACPI_GENERIC_ADDRESS    *RegisterB);
134
 
134
 
135
static ACPI_STATUS
135
static ACPI_STATUS
136
AcpiHwWriteMultiple (
136
AcpiHwWriteMultiple (
137
    UINT32                  Value,
137
    UINT32                  Value,
138
    ACPI_GENERIC_ADDRESS    *RegisterA,
138
    ACPI_GENERIC_ADDRESS    *RegisterA,
139
    ACPI_GENERIC_ADDRESS    *RegisterB);
139
    ACPI_GENERIC_ADDRESS    *RegisterB);
140
 
140
 
141
 
141
 
142
/******************************************************************************
142
/******************************************************************************
143
 *
143
 *
144
 * FUNCTION:    AcpiHwValidateRegister
144
 * FUNCTION:    AcpiHwValidateRegister
145
 *
145
 *
146
 * PARAMETERS:  Reg                 - GAS register structure
146
 * PARAMETERS:  Reg                 - GAS register structure
147
 *              MaxBitWidth         - Max BitWidth supported (32 or 64)
147
 *              MaxBitWidth         - Max BitWidth supported (32 or 64)
148
 *              Address             - Pointer to where the gas->address
148
 *              Address             - Pointer to where the gas->address
149
 *                                    is returned
149
 *                                    is returned
150
 *
150
 *
151
 * RETURN:      Status
151
 * RETURN:      Status
152
 *
152
 *
153
 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS
153
 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS
154
 *              pointer, Address, SpaceId, BitWidth, and BitOffset.
154
 *              pointer, Address, SpaceId, BitWidth, and BitOffset.
155
 *
155
 *
156
 ******************************************************************************/
156
 ******************************************************************************/
157
 
157
 
158
ACPI_STATUS
158
ACPI_STATUS
159
AcpiHwValidateRegister (
159
AcpiHwValidateRegister (
160
    ACPI_GENERIC_ADDRESS    *Reg,
160
    ACPI_GENERIC_ADDRESS    *Reg,
161
    UINT8                   MaxBitWidth,
161
    UINT8                   MaxBitWidth,
162
    UINT64                  *Address)
162
    UINT64                  *Address)
163
{
163
{
164
 
164
 
165
    /* Must have a valid pointer to a GAS structure */
165
    /* Must have a valid pointer to a GAS structure */
166
 
166
 
167
    if (!Reg)
167
    if (!Reg)
168
    {
168
    {
169
        return (AE_BAD_PARAMETER);
169
        return (AE_BAD_PARAMETER);
170
    }
170
    }
171
 
171
 
172
    /*
172
    /*
173
     * Copy the target address. This handles possible alignment issues.
173
     * Copy the target address. This handles possible alignment issues.
174
     * Address must not be null. A null address also indicates an optional
174
     * Address must not be null. A null address also indicates an optional
175
     * ACPI register that is not supported, so no error message.
175
     * ACPI register that is not supported, so no error message.
176
     */
176
     */
177
    ACPI_MOVE_64_TO_64 (Address, &Reg->Address);
177
    ACPI_MOVE_64_TO_64 (Address, &Reg->Address);
178
    if (!(*Address))
178
    if (!(*Address))
179
    {
179
    {
180
        return (AE_BAD_ADDRESS);
180
        return (AE_BAD_ADDRESS);
181
    }
181
    }
182
 
182
 
183
    /* Validate the SpaceID */
183
    /* Validate the SpaceID */
184
 
184
 
185
    if ((Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
185
    if ((Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
186
        (Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_IO))
186
        (Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_IO))
187
    {
187
    {
188
        ACPI_ERROR ((AE_INFO,
188
        ACPI_ERROR ((AE_INFO,
189
            "Unsupported address space: 0x%X", Reg->SpaceId));
189
            "Unsupported address space: 0x%X", Reg->SpaceId));
190
        return (AE_SUPPORT);
190
        return (AE_SUPPORT);
191
    }
191
    }
192
 
192
 
193
    /* Validate the BitWidth */
193
    /* Validate the BitWidth */
194
 
194
 
195
    if ((Reg->BitWidth != 8) &&
195
    if ((Reg->BitWidth != 8) &&
196
        (Reg->BitWidth != 16) &&
196
        (Reg->BitWidth != 16) &&
197
        (Reg->BitWidth != 32) &&
197
        (Reg->BitWidth != 32) &&
198
        (Reg->BitWidth != MaxBitWidth))
198
        (Reg->BitWidth != MaxBitWidth))
199
    {
199
    {
200
        ACPI_ERROR ((AE_INFO,
200
        ACPI_ERROR ((AE_INFO,
201
            "Unsupported register bit width: 0x%X", Reg->BitWidth));
201
            "Unsupported register bit width: 0x%X", Reg->BitWidth));
202
        return (AE_SUPPORT);
202
        return (AE_SUPPORT);
203
    }
203
    }
204
 
204
 
205
    /* Validate the BitOffset. Just a warning for now. */
205
    /* Validate the BitOffset. Just a warning for now. */
206
 
206
 
207
    if (Reg->BitOffset != 0)
207
    if (Reg->BitOffset != 0)
208
    {
208
    {
209
        ACPI_WARNING ((AE_INFO,
209
        ACPI_WARNING ((AE_INFO,
210
            "Unsupported register bit offset: 0x%X", Reg->BitOffset));
210
            "Unsupported register bit offset: 0x%X", Reg->BitOffset));
211
    }
211
    }
212
 
212
 
213
    return (AE_OK);
213
    return (AE_OK);
214
}
214
}
215
 
215
 
216
 
216
 
217
/******************************************************************************
217
/******************************************************************************
218
 *
218
 *
219
 * FUNCTION:    AcpiHwRead
219
 * FUNCTION:    AcpiHwRead
220
 *
220
 *
221
 * PARAMETERS:  Value               - Where the value is returned
221
 * PARAMETERS:  Value               - Where the value is returned
222
 *              Reg                 - GAS register structure
222
 *              Reg                 - GAS register structure
223
 *
223
 *
224
 * RETURN:      Status
224
 * RETURN:      Status
225
 *
225
 *
226
 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
226
 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
227
 *              version of AcpiRead, used internally since the overhead of
227
 *              version of AcpiRead, used internally since the overhead of
228
 *              64-bit values is not needed.
228
 *              64-bit values is not needed.
229
 *
229
 *
230
 * LIMITATIONS: 
230
 * LIMITATIONS: 
231
 *      BitWidth must be exactly 8, 16, or 32.
231
 *      BitWidth must be exactly 8, 16, or 32.
232
 *      SpaceID must be SystemMemory or SystemIO.
232
 *      SpaceID must be SystemMemory or SystemIO.
233
 *      BitOffset and AccessWidth are currently ignored, as there has
233
 *      BitOffset and AccessWidth are currently ignored, as there has
234
 *          not been a need to implement these.
234
 *          not been a need to implement these.
235
 *
235
 *
236
 ******************************************************************************/
236
 ******************************************************************************/
237
 
237
 
238
ACPI_STATUS
238
ACPI_STATUS
239
AcpiHwRead (
239
AcpiHwRead (
240
    UINT32                  *Value,
240
    UINT32                  *Value,
241
    ACPI_GENERIC_ADDRESS    *Reg)
241
    ACPI_GENERIC_ADDRESS    *Reg)
242
{
242
{
243
    UINT64                  Address;
243
    UINT64                  Address;
244
    ACPI_STATUS             Status;
244
    ACPI_STATUS             Status;
245
 
245
 
246
 
246
 
247
    ACPI_FUNCTION_NAME (HwRead);
247
    ACPI_FUNCTION_NAME (HwRead);
248
 
248
 
249
 
249
 
250
    /* Validate contents of the GAS register */
250
    /* Validate contents of the GAS register */
251
 
251
 
252
    Status = AcpiHwValidateRegister (Reg, 32, &Address);
252
    Status = AcpiHwValidateRegister (Reg, 32, &Address);
253
    if (ACPI_FAILURE (Status))
253
    if (ACPI_FAILURE (Status))
254
    {
254
    {
255
        return (Status);
255
        return (Status);
256
    }
256
    }
257
 
257
 
258
    /* Initialize entire 32-bit return value to zero */
258
    /* Initialize entire 32-bit return value to zero */
259
 
259
 
260
    *Value = 0;
260
    *Value = 0;
261
 
261
 
262
    /*
262
    /*
263
     * Two address spaces supported: Memory or IO. PCI_Config is
263
     * Two address spaces supported: Memory or IO. PCI_Config is
264
     * not supported here because the GAS structure is insufficient
264
     * not supported here because the GAS structure is insufficient
265
     */
265
     */
266
    if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
266
    if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
267
    {
267
    {
268
        Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
268
        Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
269
                    Address, Value, Reg->BitWidth);
269
                    Address, Value, Reg->BitWidth);
270
    }
270
    }
271
    else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
271
    else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
272
    {
272
    {
273
        Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
273
        Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
274
                    Address, Value, Reg->BitWidth);
274
                    Address, Value, Reg->BitWidth);
275
    }
275
    }
276
 
276
 
277
    ACPI_DEBUG_PRINT ((ACPI_DB_IO,
277
    ACPI_DEBUG_PRINT ((ACPI_DB_IO,
278
        "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
278
        "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
279
        *Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
279
        *Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
280
        AcpiUtGetRegionName (Reg->SpaceId)));
280
        AcpiUtGetRegionName (Reg->SpaceId)));
281
 
281
 
282
    return (Status);
282
    return (Status);
283
}
283
}
284
 
284
 
285
 
285
 
286
/******************************************************************************
286
/******************************************************************************
287
 *
287
 *
288
 * FUNCTION:    AcpiHwWrite
288
 * FUNCTION:    AcpiHwWrite
289
 *
289
 *
290
 * PARAMETERS:  Value               - Value to be written
290
 * PARAMETERS:  Value               - Value to be written
291
 *              Reg                 - GAS register structure
291
 *              Reg                 - GAS register structure
292
 *
292
 *
293
 * RETURN:      Status
293
 * RETURN:      Status
294
 *
294
 *
295
 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
295
 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
296
 *              version of AcpiWrite, used internally since the overhead of
296
 *              version of AcpiWrite, used internally since the overhead of
297
 *              64-bit values is not needed.
297
 *              64-bit values is not needed.
298
 *
298
 *
299
 ******************************************************************************/
299
 ******************************************************************************/
300
 
300
 
301
ACPI_STATUS
301
ACPI_STATUS
302
AcpiHwWrite (
302
AcpiHwWrite (
303
    UINT32                  Value,
303
    UINT32                  Value,
304
    ACPI_GENERIC_ADDRESS    *Reg)
304
    ACPI_GENERIC_ADDRESS    *Reg)
305
{
305
{
306
    UINT64                  Address;
306
    UINT64                  Address;
307
    ACPI_STATUS             Status;
307
    ACPI_STATUS             Status;
308
 
308
 
309
 
309
 
310
    ACPI_FUNCTION_NAME (HwWrite);
310
    ACPI_FUNCTION_NAME (HwWrite);
311
 
311
 
312
 
312
 
313
    /* Validate contents of the GAS register */
313
    /* Validate contents of the GAS register */
314
 
314
 
315
    Status = AcpiHwValidateRegister (Reg, 32, &Address);
315
    Status = AcpiHwValidateRegister (Reg, 32, &Address);
316
    if (ACPI_FAILURE (Status))
316
    if (ACPI_FAILURE (Status))
317
    {
317
    {
318
        return (Status);
318
        return (Status);
319
    }
319
    }
320
 
320
 
321
    /*
321
    /*
322
     * Two address spaces supported: Memory or IO. PCI_Config is
322
     * Two address spaces supported: Memory or IO. PCI_Config is
323
     * not supported here because the GAS structure is insufficient
323
     * not supported here because the GAS structure is insufficient
324
     */
324
     */
325
    if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
325
    if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
326
    {
326
    {
327
        Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
327
        Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
328
                    Address, Value, Reg->BitWidth);
328
                    Address, Value, Reg->BitWidth);
329
    }
329
    }
330
    else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
330
    else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
331
    {
331
    {
332
        Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
332
        Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
333
                    Address, Value, Reg->BitWidth);
333
                    Address, Value, Reg->BitWidth);
334
    }
334
    }
335
 
335
 
336
    ACPI_DEBUG_PRINT ((ACPI_DB_IO,
336
    ACPI_DEBUG_PRINT ((ACPI_DB_IO,
337
        "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
337
        "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
338
        Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
338
        Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
339
        AcpiUtGetRegionName (Reg->SpaceId)));
339
        AcpiUtGetRegionName (Reg->SpaceId)));
340
 
340
 
341
    return (Status);
341
    return (Status);
342
}
342
}
343
 
343
 
344
 
344
 
345
/*******************************************************************************
345
/*******************************************************************************
346
 *
346
 *
347
 * FUNCTION:    AcpiHwClearAcpiStatus
347
 * FUNCTION:    AcpiHwClearAcpiStatus
348
 *
348
 *
349
 * PARAMETERS:  None
349
 * PARAMETERS:  None
350
 *
350
 *
351
 * RETURN:      Status
351
 * RETURN:      Status
352
 *
352
 *
353
 * DESCRIPTION: Clears all fixed and general purpose status bits
353
 * DESCRIPTION: Clears all fixed and general purpose status bits
354
 *
354
 *
355
 ******************************************************************************/
355
 ******************************************************************************/
356
 
356
 
357
ACPI_STATUS
357
ACPI_STATUS
358
AcpiHwClearAcpiStatus (
358
AcpiHwClearAcpiStatus (
359
    void)
359
    void)
360
{
360
{
361
    ACPI_STATUS             Status;
361
    ACPI_STATUS             Status;
362
    ACPI_CPU_FLAGS          LockFlags = 0;
362
    ACPI_CPU_FLAGS          LockFlags = 0;
363
 
363
 
364
 
364
 
365
    ACPI_FUNCTION_TRACE (HwClearAcpiStatus);
365
    ACPI_FUNCTION_TRACE (HwClearAcpiStatus);
366
 
366
 
367
 
367
 
368
    ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
368
    ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
369
        ACPI_BITMASK_ALL_FIXED_STATUS,
369
        ACPI_BITMASK_ALL_FIXED_STATUS,
370
        ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus.Address)));
370
        ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus.Address)));
371
 
371
 
372
    LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
372
    LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
373
 
373
 
374
    /* Clear the fixed events in PM1 A/B */
374
    /* Clear the fixed events in PM1 A/B */
375
 
375
 
376
    Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
376
    Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
377
                ACPI_BITMASK_ALL_FIXED_STATUS);
377
                ACPI_BITMASK_ALL_FIXED_STATUS);
378
    if (ACPI_FAILURE (Status))
378
    if (ACPI_FAILURE (Status))
379
    {
379
    {
380
        goto UnlockAndExit;
380
        goto UnlockAndExit;
381
    }
381
    }
382
 
382
 
383
    /* Clear the GPE Bits in all GPE registers in all GPE blocks */
383
    /* Clear the GPE Bits in all GPE registers in all GPE blocks */
384
 
384
 
385
    Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL);
385
    Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL);
386
 
386
 
387
UnlockAndExit:
387
UnlockAndExit:
388
    AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
388
    AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
389
    return_ACPI_STATUS (Status);
389
    return_ACPI_STATUS (Status);
390
}
390
}
391
 
391
 
392
 
392
 
393
/*******************************************************************************
393
/*******************************************************************************
394
 *
394
 *
395
 * FUNCTION:    AcpiHwGetRegisterBitMask
395
 * FUNCTION:    AcpiHwGetRegisterBitMask
396
 *
396
 *
397
 * PARAMETERS:  RegisterId          - Index of ACPI Register to access
397
 * PARAMETERS:  RegisterId          - Index of ACPI Register to access
398
 *
398
 *
399
 * RETURN:      The bitmask to be used when accessing the register
399
 * RETURN:      The bitmask to be used when accessing the register
400
 *
400
 *
401
 * DESCRIPTION: Map RegisterId into a register bitmask.
401
 * DESCRIPTION: Map RegisterId into a register bitmask.
402
 *
402
 *
403
 ******************************************************************************/
403
 ******************************************************************************/
404
 
404
 
405
ACPI_BIT_REGISTER_INFO *
405
ACPI_BIT_REGISTER_INFO *
406
AcpiHwGetBitRegisterInfo (
406
AcpiHwGetBitRegisterInfo (
407
    UINT32                  RegisterId)
407
    UINT32                  RegisterId)
408
{
408
{
409
    ACPI_FUNCTION_ENTRY ();
409
    ACPI_FUNCTION_ENTRY ();
410
 
410
 
411
 
411
 
412
    if (RegisterId > ACPI_BITREG_MAX)
412
    if (RegisterId > ACPI_BITREG_MAX)
413
    {
413
    {
414
        ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: 0x%X", RegisterId));
414
        ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: 0x%X", RegisterId));
415
        return (NULL);
415
        return (NULL);
416
    }
416
    }
417
 
417
 
418
    return (&AcpiGbl_BitRegisterInfo[RegisterId]);
418
    return (&AcpiGbl_BitRegisterInfo[RegisterId]);
419
}
419
}
420
 
420
 
421
 
421
 
422
/******************************************************************************
422
/******************************************************************************
423
 *
423
 *
424
 * FUNCTION:    AcpiHwWritePm1Control
424
 * FUNCTION:    AcpiHwWritePm1Control
425
 *
425
 *
426
 * PARAMETERS:  Pm1aControl         - Value to be written to PM1A control
426
 * PARAMETERS:  Pm1aControl         - Value to be written to PM1A control
427
 *              Pm1bControl         - Value to be written to PM1B control
427
 *              Pm1bControl         - Value to be written to PM1B control
428
 *
428
 *
429
 * RETURN:      Status
429
 * RETURN:      Status
430
 *
430
 *
431
 * DESCRIPTION: Write the PM1 A/B control registers. These registers are
431
 * DESCRIPTION: Write the PM1 A/B control registers. These registers are
432
 *              different than than the PM1 A/B status and enable registers
432
 *              different than than the PM1 A/B status and enable registers
433
 *              in that different values can be written to the A/B registers.
433
 *              in that different values can be written to the A/B registers.
434
 *              Most notably, the SLP_TYP bits can be different, as per the
434
 *              Most notably, the SLP_TYP bits can be different, as per the
435
 *              values returned from the _Sx predefined methods.
435
 *              values returned from the _Sx predefined methods.
436
 *
436
 *
437
 ******************************************************************************/
437
 ******************************************************************************/
438
 
438
 
439
ACPI_STATUS
439
ACPI_STATUS
440
AcpiHwWritePm1Control (
440
AcpiHwWritePm1Control (
441
    UINT32                  Pm1aControl,
441
    UINT32                  Pm1aControl,
442
    UINT32                  Pm1bControl)
442
    UINT32                  Pm1bControl)
443
{
443
{
444
    ACPI_STATUS             Status;
444
    ACPI_STATUS             Status;
445
 
445
 
446
 
446
 
447
    ACPI_FUNCTION_TRACE (HwWritePm1Control);
447
    ACPI_FUNCTION_TRACE (HwWritePm1Control);
448
 
448
 
449
 
449
 
450
    Status = AcpiHwWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock);
450
    Status = AcpiHwWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock);
451
    if (ACPI_FAILURE (Status))
451
    if (ACPI_FAILURE (Status))
452
    {
452
    {
453
        return_ACPI_STATUS (Status);
453
        return_ACPI_STATUS (Status);
454
    }
454
    }
455
 
455
 
456
    if (AcpiGbl_FADT.XPm1bControlBlock.Address)
456
    if (AcpiGbl_FADT.XPm1bControlBlock.Address)
457
    {
457
    {
458
        Status = AcpiHwWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock);
458
        Status = AcpiHwWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock);
459
    }
459
    }
460
    return_ACPI_STATUS (Status);
460
    return_ACPI_STATUS (Status);
461
}
461
}
462
 
462
 
463
 
463
 
464
/******************************************************************************
464
/******************************************************************************
465
 *
465
 *
466
 * FUNCTION:    AcpiHwRegisterRead
466
 * FUNCTION:    AcpiHwRegisterRead
467
 *
467
 *
468
 * PARAMETERS:  RegisterId          - ACPI Register ID
468
 * PARAMETERS:  RegisterId          - ACPI Register ID
469
 *              ReturnValue         - Where the register value is returned
469
 *              ReturnValue         - Where the register value is returned
470
 *
470
 *
471
 * RETURN:      Status and the value read.
471
 * RETURN:      Status and the value read.
472
 *
472
 *
473
 * DESCRIPTION: Read from the specified ACPI register
473
 * DESCRIPTION: Read from the specified ACPI register
474
 *
474
 *
475
 ******************************************************************************/
475
 ******************************************************************************/
476
 
476
 
477
ACPI_STATUS
477
ACPI_STATUS
478
AcpiHwRegisterRead (
478
AcpiHwRegisterRead (
479
    UINT32                  RegisterId,
479
    UINT32                  RegisterId,
480
    UINT32                  *ReturnValue)
480
    UINT32                  *ReturnValue)
481
{
481
{
482
    UINT32                  Value = 0;
482
    UINT32                  Value = 0;
483
    ACPI_STATUS             Status;
483
    ACPI_STATUS             Status;
484
 
484
 
485
 
485
 
486
    ACPI_FUNCTION_TRACE (HwRegisterRead);
486
    ACPI_FUNCTION_TRACE (HwRegisterRead);
487
 
487
 
488
 
488
 
489
    switch (RegisterId)
489
    switch (RegisterId)
490
    {
490
    {
491
    case ACPI_REGISTER_PM1_STATUS:           /* PM1 A/B: 16-bit access each */
491
    case ACPI_REGISTER_PM1_STATUS:           /* PM1 A/B: 16-bit access each */
492
 
492
 
493
        Status = AcpiHwReadMultiple (&Value,
493
        Status = AcpiHwReadMultiple (&Value,
494
                    &AcpiGbl_XPm1aStatus,
494
                    &AcpiGbl_XPm1aStatus,
495
                    &AcpiGbl_XPm1bStatus);
495
                    &AcpiGbl_XPm1bStatus);
496
        break;
496
        break;
497
 
497
 
498
 
498
 
499
    case ACPI_REGISTER_PM1_ENABLE:           /* PM1 A/B: 16-bit access each */
499
    case ACPI_REGISTER_PM1_ENABLE:           /* PM1 A/B: 16-bit access each */
500
 
500
 
501
        Status = AcpiHwReadMultiple (&Value,
501
        Status = AcpiHwReadMultiple (&Value,
502
                    &AcpiGbl_XPm1aEnable,
502
                    &AcpiGbl_XPm1aEnable,
503
                    &AcpiGbl_XPm1bEnable);
503
                    &AcpiGbl_XPm1bEnable);
504
        break;
504
        break;
505
 
505
 
506
 
506
 
507
    case ACPI_REGISTER_PM1_CONTROL:          /* PM1 A/B: 16-bit access each */
507
    case ACPI_REGISTER_PM1_CONTROL:          /* PM1 A/B: 16-bit access each */
508
 
508
 
509
        Status = AcpiHwReadMultiple (&Value,
509
        Status = AcpiHwReadMultiple (&Value,
510
                    &AcpiGbl_FADT.XPm1aControlBlock,
510
                    &AcpiGbl_FADT.XPm1aControlBlock,
511
                    &AcpiGbl_FADT.XPm1bControlBlock);
511
                    &AcpiGbl_FADT.XPm1bControlBlock);
512
 
512
 
513
        /*
513
        /*
514
         * Zero the write-only bits. From the ACPI specification, "Hardware
514
         * Zero the write-only bits. From the ACPI specification, "Hardware
515
         * Write-Only Bits": "Upon reads to registers with write-only bits,
515
         * Write-Only Bits": "Upon reads to registers with write-only bits,
516
         * software masks out all write-only bits."
516
         * software masks out all write-only bits."
517
         */
517
         */
518
        Value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
518
        Value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
519
        break;
519
        break;
520
 
520
 
521
 
521
 
522
    case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
522
    case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
523
 
523
 
524
        Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock);
524
        Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock);
525
        break;
525
        break;
526
 
526
 
527
 
527
 
528
    case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
528
    case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
529
 
529
 
530
        Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPmTimerBlock);
530
        Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPmTimerBlock);
531
        break;
531
        break;
532
 
532
 
533
 
533
 
534
    case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
534
    case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
535
 
535
 
536
        Status = AcpiHwReadPort (AcpiGbl_FADT.SmiCommand, &Value, 8);
536
        Status = AcpiHwReadPort (AcpiGbl_FADT.SmiCommand, &Value, 8);
537
        break;
537
        break;
538
 
538
 
539
 
539
 
540
    default:
540
    default:
541
        ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
541
        ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
542
            RegisterId));
542
            RegisterId));
543
        Status = AE_BAD_PARAMETER;
543
        Status = AE_BAD_PARAMETER;
544
        break;
544
        break;
545
    }
545
    }
546
 
546
 
547
    if (ACPI_SUCCESS (Status))
547
    if (ACPI_SUCCESS (Status))
548
    {
548
    {
549
        *ReturnValue = Value;
549
        *ReturnValue = Value;
550
    }
550
    }
551
 
551
 
552
    return_ACPI_STATUS (Status);
552
    return_ACPI_STATUS (Status);
553
}
553
}
554
 
554
 
555
 
555
 
556
/******************************************************************************
556
/******************************************************************************
557
 *
557
 *
558
 * FUNCTION:    AcpiHwRegisterWrite
558
 * FUNCTION:    AcpiHwRegisterWrite
559
 *
559
 *
560
 * PARAMETERS:  RegisterId          - ACPI Register ID
560
 * PARAMETERS:  RegisterId          - ACPI Register ID
561
 *              Value               - The value to write
561
 *              Value               - The value to write
562
 *
562
 *
563
 * RETURN:      Status
563
 * RETURN:      Status
564
 *
564
 *
565
 * DESCRIPTION: Write to the specified ACPI register
565
 * DESCRIPTION: Write to the specified ACPI register
566
 *
566
 *
567
 * NOTE: In accordance with the ACPI specification, this function automatically
567
 * NOTE: In accordance with the ACPI specification, this function automatically
568
 * preserves the value of the following bits, meaning that these bits cannot be
568
 * preserves the value of the following bits, meaning that these bits cannot be
569
 * changed via this interface:
569
 * changed via this interface:
570
 *
570
 *
571
 * PM1_CONTROL[0] = SCI_EN
571
 * PM1_CONTROL[0] = SCI_EN
572
 * PM1_CONTROL[9]
572
 * PM1_CONTROL[9]
573
 * PM1_STATUS[11]
573
 * PM1_STATUS[11]
574
 *
574
 *
575
 * ACPI References:
575
 * ACPI References:
576
 * 1) Hardware Ignored Bits: When software writes to a register with ignored
576
 * 1) Hardware Ignored Bits: When software writes to a register with ignored
577
 *      bit fields, it preserves the ignored bit fields
577
 *      bit fields, it preserves the ignored bit fields
578
 * 2) SCI_EN: OSPM always preserves this bit position
578
 * 2) SCI_EN: OSPM always preserves this bit position
579
 *
579
 *
580
 ******************************************************************************/
580
 ******************************************************************************/
581
 
581
 
582
ACPI_STATUS
582
ACPI_STATUS
583
AcpiHwRegisterWrite (
583
AcpiHwRegisterWrite (
584
    UINT32                  RegisterId,
584
    UINT32                  RegisterId,
585
    UINT32                  Value)
585
    UINT32                  Value)
586
{
586
{
587
    ACPI_STATUS             Status;
587
    ACPI_STATUS             Status;
588
    UINT32                  ReadValue;
588
    UINT32                  ReadValue;
589
 
589
 
590
 
590
 
591
    ACPI_FUNCTION_TRACE (HwRegisterWrite);
591
    ACPI_FUNCTION_TRACE (HwRegisterWrite);
592
 
592
 
593
 
593
 
594
    switch (RegisterId)
594
    switch (RegisterId)
595
    {
595
    {
596
    case ACPI_REGISTER_PM1_STATUS:           /* PM1 A/B: 16-bit access each */
596
    case ACPI_REGISTER_PM1_STATUS:           /* PM1 A/B: 16-bit access each */
597
        /*
597
        /*
598
         * Handle the "ignored" bit in PM1 Status. According to the ACPI
598
         * Handle the "ignored" bit in PM1 Status. According to the ACPI
599
         * specification, ignored bits are to be preserved when writing.
599
         * specification, ignored bits are to be preserved when writing.
600
         * Normally, this would mean a read/modify/write sequence. However,
600
         * Normally, this would mean a read/modify/write sequence. However,
601
         * preserving a bit in the status register is different. Writing a
601
         * preserving a bit in the status register is different. Writing a
602
         * one clears the status, and writing a zero preserves the status.
602
         * one clears the status, and writing a zero preserves the status.
603
         * Therefore, we must always write zero to the ignored bit.
603
         * Therefore, we must always write zero to the ignored bit.
604
         *
604
         *
605
         * This behavior is clarified in the ACPI 4.0 specification.
605
         * This behavior is clarified in the ACPI 4.0 specification.
606
         */
606
         */
607
        Value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
607
        Value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
608
 
608
 
609
        Status = AcpiHwWriteMultiple (Value,
609
        Status = AcpiHwWriteMultiple (Value,
610
                    &AcpiGbl_XPm1aStatus,
610
                    &AcpiGbl_XPm1aStatus,
611
                    &AcpiGbl_XPm1bStatus);
611
                    &AcpiGbl_XPm1bStatus);
612
        break;
612
        break;
613
 
613
 
614
 
614
 
615
    case ACPI_REGISTER_PM1_ENABLE:           /* PM1 A/B: 16-bit access each */
615
    case ACPI_REGISTER_PM1_ENABLE:           /* PM1 A/B: 16-bit access each */
616
 
616
 
617
        Status = AcpiHwWriteMultiple (Value,
617
        Status = AcpiHwWriteMultiple (Value,
618
                    &AcpiGbl_XPm1aEnable,
618
                    &AcpiGbl_XPm1aEnable,
619
                    &AcpiGbl_XPm1bEnable);
619
                    &AcpiGbl_XPm1bEnable);
620
        break;
620
        break;
621
 
621
 
622
 
622
 
623
    case ACPI_REGISTER_PM1_CONTROL:          /* PM1 A/B: 16-bit access each */
623
    case ACPI_REGISTER_PM1_CONTROL:          /* PM1 A/B: 16-bit access each */
624
 
624
 
625
        /*
625
        /*
626
         * Perform a read first to preserve certain bits (per ACPI spec)
626
         * Perform a read first to preserve certain bits (per ACPI spec)
627
         * Note: This includes SCI_EN, we never want to change this bit
627
         * Note: This includes SCI_EN, we never want to change this bit
628
         */
628
         */
629
        Status = AcpiHwReadMultiple (&ReadValue,
629
        Status = AcpiHwReadMultiple (&ReadValue,
630
                    &AcpiGbl_FADT.XPm1aControlBlock,
630
                    &AcpiGbl_FADT.XPm1aControlBlock,
631
                    &AcpiGbl_FADT.XPm1bControlBlock);
631
                    &AcpiGbl_FADT.XPm1bControlBlock);
632
        if (ACPI_FAILURE (Status))
632
        if (ACPI_FAILURE (Status))
633
        {
633
        {
634
            goto Exit;
634
            goto Exit;
635
        }
635
        }
636
 
636
 
637
        /* Insert the bits to be preserved */
637
        /* Insert the bits to be preserved */
638
 
638
 
639
        ACPI_INSERT_BITS (Value, ACPI_PM1_CONTROL_PRESERVED_BITS, ReadValue);
639
        ACPI_INSERT_BITS (Value, ACPI_PM1_CONTROL_PRESERVED_BITS, ReadValue);
640
 
640
 
641
        /* Now we can write the data */
641
        /* Now we can write the data */
642
 
642
 
643
        Status = AcpiHwWriteMultiple (Value,
643
        Status = AcpiHwWriteMultiple (Value,
644
                    &AcpiGbl_FADT.XPm1aControlBlock,
644
                    &AcpiGbl_FADT.XPm1aControlBlock,
645
                    &AcpiGbl_FADT.XPm1bControlBlock);
645
                    &AcpiGbl_FADT.XPm1bControlBlock);
646
        break;
646
        break;
647
 
647
 
648
 
648
 
649
    case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
649
    case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
650
 
650
 
651
        /*
651
        /*
652
         * For control registers, all reserved bits must be preserved,
652
         * For control registers, all reserved bits must be preserved,
653
         * as per the ACPI spec.
653
         * as per the ACPI spec.
654
         */
654
         */
655
        Status = AcpiHwRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock);
655
        Status = AcpiHwRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock);
656
        if (ACPI_FAILURE (Status))
656
        if (ACPI_FAILURE (Status))
657
        {
657
        {
658
            goto Exit;
658
            goto Exit;
659
        }
659
        }
660
 
660
 
661
        /* Insert the bits to be preserved */
661
        /* Insert the bits to be preserved */
662
 
662
 
663
        ACPI_INSERT_BITS (Value, ACPI_PM2_CONTROL_PRESERVED_BITS, ReadValue);
663
        ACPI_INSERT_BITS (Value, ACPI_PM2_CONTROL_PRESERVED_BITS, ReadValue);
664
 
664
 
665
        Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock);
665
        Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock);
666
        break;
666
        break;
667
 
667
 
668
 
668
 
669
    case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
669
    case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
670
 
670
 
671
        Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPmTimerBlock);
671
        Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPmTimerBlock);
672
        break;
672
        break;
673
 
673
 
674
 
674
 
675
    case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
675
    case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
676
 
676
 
677
        /* SMI_CMD is currently always in IO space */
677
        /* SMI_CMD is currently always in IO space */
678
 
678
 
679
        Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, Value, 8);
679
        Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, Value, 8);
680
        break;
680
        break;
681
 
681
 
682
 
682
 
683
    default:
683
    default:
684
        ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
684
        ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
685
            RegisterId));
685
            RegisterId));
686
        Status = AE_BAD_PARAMETER;
686
        Status = AE_BAD_PARAMETER;
687
        break;
687
        break;
688
    }
688
    }
689
 
689
 
690
Exit:
690
Exit:
691
    return_ACPI_STATUS (Status);
691
    return_ACPI_STATUS (Status);
692
}
692
}
693
 
693
 
694
 
694
 
695
/******************************************************************************
695
/******************************************************************************
696
 *
696
 *
697
 * FUNCTION:    AcpiHwReadMultiple
697
 * FUNCTION:    AcpiHwReadMultiple
698
 *
698
 *
699
 * PARAMETERS:  Value               - Where the register value is returned
699
 * PARAMETERS:  Value               - Where the register value is returned
700
 *              RegisterA           - First ACPI register (required)
700
 *              RegisterA           - First ACPI register (required)
701
 *              RegisterB           - Second ACPI register (optional)
701
 *              RegisterB           - Second ACPI register (optional)
702
 *
702
 *
703
 * RETURN:      Status
703
 * RETURN:      Status
704
 *
704
 *
705
 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
705
 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
706
 *
706
 *
707
 ******************************************************************************/
707
 ******************************************************************************/
708
 
708
 
709
static ACPI_STATUS
709
static ACPI_STATUS
710
AcpiHwReadMultiple (
710
AcpiHwReadMultiple (
711
    UINT32                  *Value,
711
    UINT32                  *Value,
712
    ACPI_GENERIC_ADDRESS    *RegisterA,
712
    ACPI_GENERIC_ADDRESS    *RegisterA,
713
    ACPI_GENERIC_ADDRESS    *RegisterB)
713
    ACPI_GENERIC_ADDRESS    *RegisterB)
714
{
714
{
715
    UINT32                  ValueA = 0;
715
    UINT32                  ValueA = 0;
716
    UINT32                  ValueB = 0;
716
    UINT32                  ValueB = 0;
717
    ACPI_STATUS             Status;
717
    ACPI_STATUS             Status;
718
 
718
 
719
 
719
 
720
    /* The first register is always required */
720
    /* The first register is always required */
721
 
721
 
722
    Status = AcpiHwRead (&ValueA, RegisterA);
722
    Status = AcpiHwRead (&ValueA, RegisterA);
723
    if (ACPI_FAILURE (Status))
723
    if (ACPI_FAILURE (Status))
724
    {
724
    {
725
        return (Status);
725
        return (Status);
726
    }
726
    }
727
 
727
 
728
    /* Second register is optional */
728
    /* Second register is optional */
729
 
729
 
730
    if (RegisterB->Address)
730
    if (RegisterB->Address)
731
    {
731
    {
732
        Status = AcpiHwRead (&ValueB, RegisterB);
732
        Status = AcpiHwRead (&ValueB, RegisterB);
733
        if (ACPI_FAILURE (Status))
733
        if (ACPI_FAILURE (Status))
734
        {
734
        {
735
            return (Status);
735
            return (Status);
736
        }
736
        }
737
    }
737
    }
738
 
738
 
739
    /*
739
    /*
740
     * OR the two return values together. No shifting or masking is necessary,
740
     * OR the two return values together. No shifting or masking is necessary,
741
     * because of how the PM1 registers are defined in the ACPI specification:
741
     * because of how the PM1 registers are defined in the ACPI specification:
742
     *
742
     *
743
     * "Although the bits can be split between the two register blocks (each
743
     * "Although the bits can be split between the two register blocks (each
744
     * register block has a unique pointer within the FADT), the bit positions
744
     * register block has a unique pointer within the FADT), the bit positions
745
     * are maintained. The register block with unimplemented bits (that is,
745
     * are maintained. The register block with unimplemented bits (that is,
746
     * those implemented in the other register block) always returns zeros,
746
     * those implemented in the other register block) always returns zeros,
747
     * and writes have no side effects"
747
     * and writes have no side effects"
748
     */
748
     */
749
    *Value = (ValueA | ValueB);
749
    *Value = (ValueA | ValueB);
750
    return (AE_OK);
750
    return (AE_OK);
751
}
751
}
752
 
752
 
753
 
753
 
754
/******************************************************************************
754
/******************************************************************************
755
 *
755
 *
756
 * FUNCTION:    AcpiHwWriteMultiple
756
 * FUNCTION:    AcpiHwWriteMultiple
757
 *
757
 *
758
 * PARAMETERS:  Value               - The value to write
758
 * PARAMETERS:  Value               - The value to write
759
 *              RegisterA           - First ACPI register (required)
759
 *              RegisterA           - First ACPI register (required)
760
 *              RegisterB           - Second ACPI register (optional)
760
 *              RegisterB           - Second ACPI register (optional)
761
 *
761
 *
762
 * RETURN:      Status
762
 * RETURN:      Status
763
 *
763
 *
764
 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
764
 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
765
 *
765
 *
766
 ******************************************************************************/
766
 ******************************************************************************/
767
 
767
 
768
static ACPI_STATUS
768
static ACPI_STATUS
769
AcpiHwWriteMultiple (
769
AcpiHwWriteMultiple (
770
    UINT32                  Value,
770
    UINT32                  Value,
771
    ACPI_GENERIC_ADDRESS    *RegisterA,
771
    ACPI_GENERIC_ADDRESS    *RegisterA,
772
    ACPI_GENERIC_ADDRESS    *RegisterB)
772
    ACPI_GENERIC_ADDRESS    *RegisterB)
773
{
773
{
774
    ACPI_STATUS             Status;
774
    ACPI_STATUS             Status;
775
 
775
 
776
 
776
 
777
    /* The first register is always required */
777
    /* The first register is always required */
778
 
778
 
779
    Status = AcpiHwWrite (Value, RegisterA);
779
    Status = AcpiHwWrite (Value, RegisterA);
780
    if (ACPI_FAILURE (Status))
780
    if (ACPI_FAILURE (Status))
781
    {
781
    {
782
        return (Status);
782
        return (Status);
783
    }
783
    }
784
 
784
 
785
    /*
785
    /*
786
     * Second register is optional
786
     * Second register is optional
787
     *
787
     *
788
     * No bit shifting or clearing is necessary, because of how the PM1
788
     * No bit shifting or clearing is necessary, because of how the PM1
789
     * registers are defined in the ACPI specification:
789
     * registers are defined in the ACPI specification:
790
     *
790
     *
791
     * "Although the bits can be split between the two register blocks (each
791
     * "Although the bits can be split between the two register blocks (each
792
     * register block has a unique pointer within the FADT), the bit positions
792
     * register block has a unique pointer within the FADT), the bit positions
793
     * are maintained. The register block with unimplemented bits (that is,
793
     * are maintained. The register block with unimplemented bits (that is,
794
     * those implemented in the other register block) always returns zeros,
794
     * those implemented in the other register block) always returns zeros,
795
     * and writes have no side effects"
795
     * and writes have no side effects"
796
     */
796
     */
797
    if (RegisterB->Address)
797
    if (RegisterB->Address)
798
    {
798
    {
799
        Status = AcpiHwWrite (Value, RegisterB);
799
        Status = AcpiHwWrite (Value, RegisterB);
800
    }
800
    }
801
 
801
 
802
    return (Status);
802
    return (Status);
803
}
803
}