Deleted Added
full compact
hwregs.c (80062) hwregs.c (82367)
1
2/*******************************************************************************
3 *
4 * Module Name: hwregs - Read/write access functions for the various ACPI
5 * control and status registers.
1
2/*******************************************************************************
3 *
4 * Module Name: hwregs - Read/write access functions for the various ACPI
5 * control and status registers.
6 * $Revision: 102 $
6 * $Revision: 104 $
7 *
8 ******************************************************************************/
9
10/******************************************************************************
11 *
12 * 1. Copyright Notice
13 *
14 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
15 * All rights reserved.
16 *
17 * 2. License
18 *
19 * 2.1. This is your license from Intel Corp. under its intellectual property
20 * rights. You may have additional license terms from the party that provided
21 * you this software, covering your right to use that party's intellectual
22 * property rights.
23 *
24 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
25 * copy of the source code appearing in this file ("Covered Code") an
26 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
27 * base code distributed originally by Intel ("Original Intel Code") to copy,
28 * make derivatives, distribute, use and display any portion of the Covered
29 * Code in any form, with the right to sublicense such rights; and
30 *
31 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
32 * license (with the right to sublicense), under only those claims of Intel
33 * patents that are infringed by the Original Intel Code, to make, use, sell,
34 * offer to sell, and import the Covered Code and derivative works thereof
35 * solely to the minimum extent necessary to exercise the above copyright
36 * license, and in no event shall the patent license extend to any additions
37 * to or modifications of the Original Intel Code. No other license or right
38 * is granted directly or by implication, estoppel or otherwise;
39 *
40 * The above copyright and patent license is granted only if the following
41 * conditions are met:
42 *
43 * 3. Conditions
44 *
45 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
46 * Redistribution of source code of any substantial portion of the Covered
47 * Code or modification with rights to further distribute source must include
48 * the above Copyright Notice, the above License, this list of Conditions,
49 * and the following Disclaimer and Export Compliance provision. In addition,
50 * Licensee must cause all Covered Code to which Licensee contributes to
51 * contain a file documenting the changes Licensee made to create that Covered
52 * Code and the date of any change. Licensee must include in that file the
53 * documentation of any changes made by any predecessor Licensee. Licensee
54 * must include a prominent statement that the modification is derived,
55 * directly or indirectly, from Original Intel Code.
56 *
57 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
58 * Redistribution of source code of any substantial portion of the Covered
59 * Code or modification without rights to further distribute source must
60 * include the following Disclaimer and Export Compliance provision in the
61 * documentation and/or other materials provided with distribution. In
62 * addition, Licensee may not authorize further sublicense of source of any
63 * portion of the Covered Code, and must include terms to the effect that the
64 * license from Licensee to its licensee is limited to the intellectual
65 * property embodied in the software Licensee provides to its licensee, and
66 * not to intellectual property embodied in modifications its licensee may
67 * make.
68 *
69 * 3.3. Redistribution of Executable. Redistribution in executable form of any
70 * substantial portion of the Covered Code or modification must reproduce the
71 * above Copyright Notice, and the following Disclaimer and Export Compliance
72 * provision in the documentation and/or other materials provided with the
73 * distribution.
74 *
75 * 3.4. Intel retains all right, title, and interest in and to the Original
76 * Intel Code.
77 *
78 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
79 * Intel shall be used in advertising or otherwise to promote the sale, use or
80 * other dealings in products derived from or relating to the Covered Code
81 * without prior written authorization from Intel.
82 *
83 * 4. Disclaimer and Export Compliance
84 *
85 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
86 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
87 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
88 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
89 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
90 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91 * PARTICULAR PURPOSE.
92 *
93 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
94 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
95 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
96 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
97 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
98 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
99 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100 * LIMITED REMEDY.
101 *
102 * 4.3. Licensee shall not export, either directly or indirectly, any of this
103 * software or system incorporating such software without first obtaining any
104 * required license or other approval from the U. S. Department of Commerce or
105 * any other agency or department of the United States Government. In the
106 * event Licensee exports any such software from the United States or
107 * re-exports any such software from a foreign destination, Licensee shall
108 * ensure that the distribution and export/re-export of the software is in
109 * compliance with all laws, regulations, orders, or other restrictions of the
110 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
111 * any of its subsidiaries will export/re-export any technical data, process,
112 * software, or service, directly or indirectly, to any country for which the
113 * United States government or any agency thereof requires an export license,
114 * other governmental approval, or letter of assurance, without first obtaining
115 * such license, approval or letter.
116 *
117 *****************************************************************************/
118
119#define __HWREGS_C__
120
121#include "acpi.h"
122#include "achware.h"
123#include "acnamesp.h"
124
125#define _COMPONENT ACPI_HARDWARE
126 MODULE_NAME ("hwregs")
127
128
129/* This matches the #defines in actypes.h. */
130
131NATIVE_CHAR *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
132 "\\_S4_","\\_S5_","\\_S4B"};
133
134
135/*******************************************************************************
136 *
137 * FUNCTION: AcpiHwGetBitShift
138 *
139 * PARAMETERS: Mask - Input mask to determine bit shift from.
140 * Must have at least 1 bit set.
141 *
142 * RETURN: Bit location of the lsb of the mask
143 *
144 * DESCRIPTION: Returns the bit number for the low order bit that's set.
145 *
146 ******************************************************************************/
147
148UINT32
149AcpiHwGetBitShift (
150 UINT32 Mask)
151{
152 UINT32 Shift;
153
154
155 FUNCTION_TRACE ("HwGetBitShift");
156
157
158 for (Shift = 0; ((Mask >> Shift) & 1) == 0; Shift++)
159 { ; }
160
161 return_VALUE (Shift);
162}
163
164
165/*******************************************************************************
166 *
167 * FUNCTION: AcpiHwClearAcpiStatus
168 *
169 * PARAMETERS: none
170 *
171 * RETURN: none
172 *
173 * DESCRIPTION: Clears all fixed and general purpose status bits
174 *
175 ******************************************************************************/
176
177void
178AcpiHwClearAcpiStatus (void)
179{
180 UINT16 GpeLength;
181 UINT16 Index;
182
183
184 FUNCTION_TRACE ("HwClearAcpiStatus");
185
186
7 *
8 ******************************************************************************/
9
10/******************************************************************************
11 *
12 * 1. Copyright Notice
13 *
14 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
15 * All rights reserved.
16 *
17 * 2. License
18 *
19 * 2.1. This is your license from Intel Corp. under its intellectual property
20 * rights. You may have additional license terms from the party that provided
21 * you this software, covering your right to use that party's intellectual
22 * property rights.
23 *
24 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
25 * copy of the source code appearing in this file ("Covered Code") an
26 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
27 * base code distributed originally by Intel ("Original Intel Code") to copy,
28 * make derivatives, distribute, use and display any portion of the Covered
29 * Code in any form, with the right to sublicense such rights; and
30 *
31 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
32 * license (with the right to sublicense), under only those claims of Intel
33 * patents that are infringed by the Original Intel Code, to make, use, sell,
34 * offer to sell, and import the Covered Code and derivative works thereof
35 * solely to the minimum extent necessary to exercise the above copyright
36 * license, and in no event shall the patent license extend to any additions
37 * to or modifications of the Original Intel Code. No other license or right
38 * is granted directly or by implication, estoppel or otherwise;
39 *
40 * The above copyright and patent license is granted only if the following
41 * conditions are met:
42 *
43 * 3. Conditions
44 *
45 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
46 * Redistribution of source code of any substantial portion of the Covered
47 * Code or modification with rights to further distribute source must include
48 * the above Copyright Notice, the above License, this list of Conditions,
49 * and the following Disclaimer and Export Compliance provision. In addition,
50 * Licensee must cause all Covered Code to which Licensee contributes to
51 * contain a file documenting the changes Licensee made to create that Covered
52 * Code and the date of any change. Licensee must include in that file the
53 * documentation of any changes made by any predecessor Licensee. Licensee
54 * must include a prominent statement that the modification is derived,
55 * directly or indirectly, from Original Intel Code.
56 *
57 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
58 * Redistribution of source code of any substantial portion of the Covered
59 * Code or modification without rights to further distribute source must
60 * include the following Disclaimer and Export Compliance provision in the
61 * documentation and/or other materials provided with distribution. In
62 * addition, Licensee may not authorize further sublicense of source of any
63 * portion of the Covered Code, and must include terms to the effect that the
64 * license from Licensee to its licensee is limited to the intellectual
65 * property embodied in the software Licensee provides to its licensee, and
66 * not to intellectual property embodied in modifications its licensee may
67 * make.
68 *
69 * 3.3. Redistribution of Executable. Redistribution in executable form of any
70 * substantial portion of the Covered Code or modification must reproduce the
71 * above Copyright Notice, and the following Disclaimer and Export Compliance
72 * provision in the documentation and/or other materials provided with the
73 * distribution.
74 *
75 * 3.4. Intel retains all right, title, and interest in and to the Original
76 * Intel Code.
77 *
78 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
79 * Intel shall be used in advertising or otherwise to promote the sale, use or
80 * other dealings in products derived from or relating to the Covered Code
81 * without prior written authorization from Intel.
82 *
83 * 4. Disclaimer and Export Compliance
84 *
85 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
86 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
87 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
88 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
89 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
90 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91 * PARTICULAR PURPOSE.
92 *
93 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
94 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
95 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
96 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
97 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
98 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
99 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100 * LIMITED REMEDY.
101 *
102 * 4.3. Licensee shall not export, either directly or indirectly, any of this
103 * software or system incorporating such software without first obtaining any
104 * required license or other approval from the U. S. Department of Commerce or
105 * any other agency or department of the United States Government. In the
106 * event Licensee exports any such software from the United States or
107 * re-exports any such software from a foreign destination, Licensee shall
108 * ensure that the distribution and export/re-export of the software is in
109 * compliance with all laws, regulations, orders, or other restrictions of the
110 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
111 * any of its subsidiaries will export/re-export any technical data, process,
112 * software, or service, directly or indirectly, to any country for which the
113 * United States government or any agency thereof requires an export license,
114 * other governmental approval, or letter of assurance, without first obtaining
115 * such license, approval or letter.
116 *
117 *****************************************************************************/
118
119#define __HWREGS_C__
120
121#include "acpi.h"
122#include "achware.h"
123#include "acnamesp.h"
124
125#define _COMPONENT ACPI_HARDWARE
126 MODULE_NAME ("hwregs")
127
128
129/* This matches the #defines in actypes.h. */
130
131NATIVE_CHAR *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
132 "\\_S4_","\\_S5_","\\_S4B"};
133
134
135/*******************************************************************************
136 *
137 * FUNCTION: AcpiHwGetBitShift
138 *
139 * PARAMETERS: Mask - Input mask to determine bit shift from.
140 * Must have at least 1 bit set.
141 *
142 * RETURN: Bit location of the lsb of the mask
143 *
144 * DESCRIPTION: Returns the bit number for the low order bit that's set.
145 *
146 ******************************************************************************/
147
148UINT32
149AcpiHwGetBitShift (
150 UINT32 Mask)
151{
152 UINT32 Shift;
153
154
155 FUNCTION_TRACE ("HwGetBitShift");
156
157
158 for (Shift = 0; ((Mask >> Shift) & 1) == 0; Shift++)
159 { ; }
160
161 return_VALUE (Shift);
162}
163
164
165/*******************************************************************************
166 *
167 * FUNCTION: AcpiHwClearAcpiStatus
168 *
169 * PARAMETERS: none
170 *
171 * RETURN: none
172 *
173 * DESCRIPTION: Clears all fixed and general purpose status bits
174 *
175 ******************************************************************************/
176
177void
178AcpiHwClearAcpiStatus (void)
179{
180 UINT16 GpeLength;
181 UINT16 Index;
182
183
184 FUNCTION_TRACE ("HwClearAcpiStatus");
185
186
187 DEBUG_PRINTP (TRACE_IO, ("About to write %04X to %04X\n",
187 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
188 ALL_FIXED_STS_BITS,
189 (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address)));
190
191
192 AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
193
194 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS);
195
196
197 if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address))
198 {
199 AcpiOsWritePort ((ACPI_IO_ADDRESS)
200 ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address),
201 ALL_FIXED_STS_BITS, 16);
202 }
203
204 /* now clear the GPE Bits */
205
206 if (AcpiGbl_FADT->Gpe0BlkLen)
207 {
208 GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
209
210 for (Index = 0; Index < GpeLength; Index++)
211 {
212 AcpiOsWritePort ((ACPI_IO_ADDRESS) (
213 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address) + Index),
214 0xFF, 8);
215 }
216 }
217
218 if (AcpiGbl_FADT->Gpe1BlkLen)
219 {
220 GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
221
222 for (Index = 0; Index < GpeLength; Index++)
223 {
224 AcpiOsWritePort ((ACPI_IO_ADDRESS) (
225 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address) + Index),
226 0xFF, 8);
227 }
228 }
229
230 AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
231 return_VOID;
232}
233
234
235/*******************************************************************************
236 *
237 * FUNCTION: AcpiHwObtainSleepTypeRegisterData
238 *
239 * PARAMETERS: SleepState - Numeric state requested
240 * *Slp_TypA - Pointer to byte to receive SLP_TYPa value
241 * *Slp_TypB - Pointer to byte to receive SLP_TYPb value
242 *
243 * RETURN: Status - ACPI status
244 *
245 * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and
246 * SLP_TYPb values for the sleep state requested.
247 *
248 ******************************************************************************/
249
250ACPI_STATUS
251AcpiHwObtainSleepTypeRegisterData (
252 UINT8 SleepState,
253 UINT8 *Slp_TypA,
254 UINT8 *Slp_TypB)
255{
256 ACPI_STATUS Status = AE_OK;
257 ACPI_OPERAND_OBJECT *ObjDesc;
258
259
260 FUNCTION_TRACE ("HwObtainSleepTypeRegisterData");
261
262
263 /*
264 * Validate parameters
265 */
266
267 if ((SleepState > ACPI_S_STATES_MAX) ||
268 !Slp_TypA || !Slp_TypB)
269 {
270 return_ACPI_STATUS (AE_BAD_PARAMETER);
271 }
272
273 /*
274 * AcpiEvaluate the namespace object containing the values for this state
275 */
276
277 Status = AcpiNsEvaluateByName (SleepStateTable[SleepState], NULL, &ObjDesc);
278 if (ACPI_FAILURE (Status))
279 {
280 return_ACPI_STATUS (Status);
281 }
282
283 if (!ObjDesc)
284 {
285 REPORT_ERROR (("Missing Sleep State object\n"));
286 return_ACPI_STATUS (AE_NOT_EXIST);
287 }
288
289 /*
290 * We got something, now ensure it is correct. The object must
291 * be a package and must have at least 2 numeric values as the
292 * two elements
293 */
294
295 /* Even though AcpiEvaluateObject resolves package references,
296 * NsEvaluate dpesn't. So, we do it here.
297 */
298 Status = AcpiUtResolvePackageReferences(ObjDesc);
299
300 if (ObjDesc->Package.Count < 2)
301 {
302 /* Must have at least two elements */
303
304 REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
305 Status = AE_ERROR;
306 }
307
308 else if (((ObjDesc->Package.Elements[0])->Common.Type !=
309 ACPI_TYPE_INTEGER) ||
310 ((ObjDesc->Package.Elements[1])->Common.Type !=
311 ACPI_TYPE_INTEGER))
312 {
313 /* Must have two */
314
315 REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
316 Status = AE_ERROR;
317 }
318
319 else
320 {
321 /*
322 * Valid _Sx_ package size, type, and value
323 */
324 *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value;
325
326 *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value;
327 }
328
329
330 if (ACPI_FAILURE (Status))
331 {
188 ALL_FIXED_STS_BITS,
189 (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address)));
190
191
192 AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
193
194 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS);
195
196
197 if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address))
198 {
199 AcpiOsWritePort ((ACPI_IO_ADDRESS)
200 ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address),
201 ALL_FIXED_STS_BITS, 16);
202 }
203
204 /* now clear the GPE Bits */
205
206 if (AcpiGbl_FADT->Gpe0BlkLen)
207 {
208 GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
209
210 for (Index = 0; Index < GpeLength; Index++)
211 {
212 AcpiOsWritePort ((ACPI_IO_ADDRESS) (
213 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address) + Index),
214 0xFF, 8);
215 }
216 }
217
218 if (AcpiGbl_FADT->Gpe1BlkLen)
219 {
220 GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
221
222 for (Index = 0; Index < GpeLength; Index++)
223 {
224 AcpiOsWritePort ((ACPI_IO_ADDRESS) (
225 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address) + Index),
226 0xFF, 8);
227 }
228 }
229
230 AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
231 return_VOID;
232}
233
234
235/*******************************************************************************
236 *
237 * FUNCTION: AcpiHwObtainSleepTypeRegisterData
238 *
239 * PARAMETERS: SleepState - Numeric state requested
240 * *Slp_TypA - Pointer to byte to receive SLP_TYPa value
241 * *Slp_TypB - Pointer to byte to receive SLP_TYPb value
242 *
243 * RETURN: Status - ACPI status
244 *
245 * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and
246 * SLP_TYPb values for the sleep state requested.
247 *
248 ******************************************************************************/
249
250ACPI_STATUS
251AcpiHwObtainSleepTypeRegisterData (
252 UINT8 SleepState,
253 UINT8 *Slp_TypA,
254 UINT8 *Slp_TypB)
255{
256 ACPI_STATUS Status = AE_OK;
257 ACPI_OPERAND_OBJECT *ObjDesc;
258
259
260 FUNCTION_TRACE ("HwObtainSleepTypeRegisterData");
261
262
263 /*
264 * Validate parameters
265 */
266
267 if ((SleepState > ACPI_S_STATES_MAX) ||
268 !Slp_TypA || !Slp_TypB)
269 {
270 return_ACPI_STATUS (AE_BAD_PARAMETER);
271 }
272
273 /*
274 * AcpiEvaluate the namespace object containing the values for this state
275 */
276
277 Status = AcpiNsEvaluateByName (SleepStateTable[SleepState], NULL, &ObjDesc);
278 if (ACPI_FAILURE (Status))
279 {
280 return_ACPI_STATUS (Status);
281 }
282
283 if (!ObjDesc)
284 {
285 REPORT_ERROR (("Missing Sleep State object\n"));
286 return_ACPI_STATUS (AE_NOT_EXIST);
287 }
288
289 /*
290 * We got something, now ensure it is correct. The object must
291 * be a package and must have at least 2 numeric values as the
292 * two elements
293 */
294
295 /* Even though AcpiEvaluateObject resolves package references,
296 * NsEvaluate dpesn't. So, we do it here.
297 */
298 Status = AcpiUtResolvePackageReferences(ObjDesc);
299
300 if (ObjDesc->Package.Count < 2)
301 {
302 /* Must have at least two elements */
303
304 REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
305 Status = AE_ERROR;
306 }
307
308 else if (((ObjDesc->Package.Elements[0])->Common.Type !=
309 ACPI_TYPE_INTEGER) ||
310 ((ObjDesc->Package.Elements[1])->Common.Type !=
311 ACPI_TYPE_INTEGER))
312 {
313 /* Must have two */
314
315 REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
316 Status = AE_ERROR;
317 }
318
319 else
320 {
321 /*
322 * Valid _Sx_ package size, type, and value
323 */
324 *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value;
325
326 *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value;
327 }
328
329
330 if (ACPI_FAILURE (Status))
331 {
332 DEBUG_PRINTP (ACPI_ERROR, ("Bad Sleep object %p type %X\n",
332 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %X\n",
333 ObjDesc, ObjDesc->Common.Type));
334 }
335
336 AcpiUtRemoveReference (ObjDesc);
337
338 return_ACPI_STATUS (Status);
339}
340
341
342/*******************************************************************************
343 *
344 * FUNCTION: AcpiHwRegisterBitAccess
345 *
346 * PARAMETERS: ReadWrite - Either ACPI_READ or ACPI_WRITE.
347 * UseLock - Lock the hardware
348 * RegisterId - index of ACPI Register to access
349 * Value - (only used on write) value to write to the
350 * Register. Shifted all the way right.
351 *
352 * RETURN: Value written to or read from specified Register. This value
353 * is shifted all the way right.
354 *
355 * DESCRIPTION: Generic ACPI Register read/write function.
356 *
357 ******************************************************************************/
358
359UINT32
360AcpiHwRegisterBitAccess (
361 NATIVE_UINT ReadWrite,
362 BOOLEAN UseLock,
363 UINT32 RegisterId,
364 ...) /* Value (only used on write) */
365{
366 UINT32 RegisterValue = 0;
367 UINT32 Mask = 0;
368 UINT32 Value = 0;
369 va_list marker;
370
371
372 FUNCTION_TRACE ("HwRegisterBitAccess");
373
374
375 if (ReadWrite == ACPI_WRITE)
376 {
377 va_start (marker, RegisterId);
378 Value = va_arg (marker, UINT32);
379 va_end (marker);
380 }
381
382 if (ACPI_MTX_LOCK == UseLock)
383 {
384 AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
385 }
386
387 /*
388 * Decode the Register ID
389 * Register id = Register block id | bit id
390 *
391 * Check bit id to fine locate Register offset.
392 * Check Mask to determine Register offset, and then read-write.
393 */
394
395 switch (REGISTER_BLOCK_ID (RegisterId))
396 {
397 case PM1_STS:
398
399 switch (RegisterId)
400 {
401 case TMR_STS:
402 Mask = TMR_STS_MASK;
403 break;
404
405 case BM_STS:
406 Mask = BM_STS_MASK;
407 break;
408
409 case GBL_STS:
410 Mask = GBL_STS_MASK;
411 break;
412
413 case PWRBTN_STS:
414 Mask = PWRBTN_STS_MASK;
415 break;
416
417 case SLPBTN_STS:
418 Mask = SLPBTN_STS_MASK;
419 break;
420
421 case RTC_STS:
422 Mask = RTC_STS_MASK;
423 break;
424
425 case WAK_STS:
426 Mask = WAK_STS_MASK;
427 break;
428
429 default:
430 Mask = 0;
431 break;
432 }
433
434 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS);
435
436 if (ReadWrite == ACPI_WRITE)
437 {
438 /*
439 * Status Registers are different from the rest. Clear by
440 * writing 1, writing 0 has no effect. So, the only relevent
441 * information is the single bit we're interested in, all
442 * others should be written as 0 so they will be left
443 * unchanged
444 */
445
446 Value <<= AcpiHwGetBitShift (Mask);
447 Value &= Mask;
448
449 if (Value)
450 {
451 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS,
452 (UINT16) Value);
453 RegisterValue = 0;
454 }
455 }
456
457 break;
458
459
460 case PM1_EN:
461
462 switch (RegisterId)
463 {
464 case TMR_EN:
465 Mask = TMR_EN_MASK;
466 break;
467
468 case GBL_EN:
469 Mask = GBL_EN_MASK;
470 break;
471
472 case PWRBTN_EN:
473 Mask = PWRBTN_EN_MASK;
474 break;
475
476 case SLPBTN_EN:
477 Mask = SLPBTN_EN_MASK;
478 break;
479
480 case RTC_EN:
481 Mask = RTC_EN_MASK;
482 break;
483
484 default:
485 Mask = 0;
486 break;
487 }
488
489 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN);
490
491 if (ReadWrite == ACPI_WRITE)
492 {
493 RegisterValue &= ~Mask;
494 Value <<= AcpiHwGetBitShift (Mask);
495 Value &= Mask;
496 RegisterValue |= Value;
497
498 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue);
499 }
500
501 break;
502
503
504 case PM1_CONTROL:
505
506 switch (RegisterId)
507 {
508 case SCI_EN:
509 Mask = SCI_EN_MASK;
510 break;
511
512 case BM_RLD:
513 Mask = BM_RLD_MASK;
514 break;
515
516 case GBL_RLS:
517 Mask = GBL_RLS_MASK;
518 break;
519
520 case SLP_TYPE_A:
521 case SLP_TYPE_B:
522 Mask = SLP_TYPE_X_MASK;
523 break;
524
525 case SLP_EN:
526 Mask = SLP_EN_MASK;
527 break;
528
529 default:
530 Mask = 0;
531 break;
532 }
533
534
535 /*
536 * Read the PM1 Control register.
537 * Note that at this level, the fact that there are actually TWO
538 * registers (A and B) and that B may not exist, are abstracted.
539 */
540 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL);
541
333 ObjDesc, ObjDesc->Common.Type));
334 }
335
336 AcpiUtRemoveReference (ObjDesc);
337
338 return_ACPI_STATUS (Status);
339}
340
341
342/*******************************************************************************
343 *
344 * FUNCTION: AcpiHwRegisterBitAccess
345 *
346 * PARAMETERS: ReadWrite - Either ACPI_READ or ACPI_WRITE.
347 * UseLock - Lock the hardware
348 * RegisterId - index of ACPI Register to access
349 * Value - (only used on write) value to write to the
350 * Register. Shifted all the way right.
351 *
352 * RETURN: Value written to or read from specified Register. This value
353 * is shifted all the way right.
354 *
355 * DESCRIPTION: Generic ACPI Register read/write function.
356 *
357 ******************************************************************************/
358
359UINT32
360AcpiHwRegisterBitAccess (
361 NATIVE_UINT ReadWrite,
362 BOOLEAN UseLock,
363 UINT32 RegisterId,
364 ...) /* Value (only used on write) */
365{
366 UINT32 RegisterValue = 0;
367 UINT32 Mask = 0;
368 UINT32 Value = 0;
369 va_list marker;
370
371
372 FUNCTION_TRACE ("HwRegisterBitAccess");
373
374
375 if (ReadWrite == ACPI_WRITE)
376 {
377 va_start (marker, RegisterId);
378 Value = va_arg (marker, UINT32);
379 va_end (marker);
380 }
381
382 if (ACPI_MTX_LOCK == UseLock)
383 {
384 AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
385 }
386
387 /*
388 * Decode the Register ID
389 * Register id = Register block id | bit id
390 *
391 * Check bit id to fine locate Register offset.
392 * Check Mask to determine Register offset, and then read-write.
393 */
394
395 switch (REGISTER_BLOCK_ID (RegisterId))
396 {
397 case PM1_STS:
398
399 switch (RegisterId)
400 {
401 case TMR_STS:
402 Mask = TMR_STS_MASK;
403 break;
404
405 case BM_STS:
406 Mask = BM_STS_MASK;
407 break;
408
409 case GBL_STS:
410 Mask = GBL_STS_MASK;
411 break;
412
413 case PWRBTN_STS:
414 Mask = PWRBTN_STS_MASK;
415 break;
416
417 case SLPBTN_STS:
418 Mask = SLPBTN_STS_MASK;
419 break;
420
421 case RTC_STS:
422 Mask = RTC_STS_MASK;
423 break;
424
425 case WAK_STS:
426 Mask = WAK_STS_MASK;
427 break;
428
429 default:
430 Mask = 0;
431 break;
432 }
433
434 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS);
435
436 if (ReadWrite == ACPI_WRITE)
437 {
438 /*
439 * Status Registers are different from the rest. Clear by
440 * writing 1, writing 0 has no effect. So, the only relevent
441 * information is the single bit we're interested in, all
442 * others should be written as 0 so they will be left
443 * unchanged
444 */
445
446 Value <<= AcpiHwGetBitShift (Mask);
447 Value &= Mask;
448
449 if (Value)
450 {
451 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS,
452 (UINT16) Value);
453 RegisterValue = 0;
454 }
455 }
456
457 break;
458
459
460 case PM1_EN:
461
462 switch (RegisterId)
463 {
464 case TMR_EN:
465 Mask = TMR_EN_MASK;
466 break;
467
468 case GBL_EN:
469 Mask = GBL_EN_MASK;
470 break;
471
472 case PWRBTN_EN:
473 Mask = PWRBTN_EN_MASK;
474 break;
475
476 case SLPBTN_EN:
477 Mask = SLPBTN_EN_MASK;
478 break;
479
480 case RTC_EN:
481 Mask = RTC_EN_MASK;
482 break;
483
484 default:
485 Mask = 0;
486 break;
487 }
488
489 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN);
490
491 if (ReadWrite == ACPI_WRITE)
492 {
493 RegisterValue &= ~Mask;
494 Value <<= AcpiHwGetBitShift (Mask);
495 Value &= Mask;
496 RegisterValue |= Value;
497
498 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue);
499 }
500
501 break;
502
503
504 case PM1_CONTROL:
505
506 switch (RegisterId)
507 {
508 case SCI_EN:
509 Mask = SCI_EN_MASK;
510 break;
511
512 case BM_RLD:
513 Mask = BM_RLD_MASK;
514 break;
515
516 case GBL_RLS:
517 Mask = GBL_RLS_MASK;
518 break;
519
520 case SLP_TYPE_A:
521 case SLP_TYPE_B:
522 Mask = SLP_TYPE_X_MASK;
523 break;
524
525 case SLP_EN:
526 Mask = SLP_EN_MASK;
527 break;
528
529 default:
530 Mask = 0;
531 break;
532 }
533
534
535 /*
536 * Read the PM1 Control register.
537 * Note that at this level, the fact that there are actually TWO
538 * registers (A and B) and that B may not exist, are abstracted.
539 */
540 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL);
541
542 DEBUG_PRINT (TRACE_IO, ("PM1 control: Read %X\n", RegisterValue));
542 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", RegisterValue));
543
544 if (ReadWrite == ACPI_WRITE)
545 {
546 RegisterValue &= ~Mask;
547 Value <<= AcpiHwGetBitShift (Mask);
548 Value &= Mask;
549 RegisterValue |= Value;
550
551 /*
552 * SLP_TYPE_x Registers are written differently
553 * than any other control Registers with
554 * respect to A and B Registers. The value
555 * for A may be different than the value for B
556 *
557 * Therefore, pass the RegisterId, not just generic PM1_CONTROL,
558 * because we need to do different things. Yuck.
559 */
560
561 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId,
562 (UINT16) RegisterValue);
563 }
564 break;
565
566
567 case PM2_CONTROL:
568
569 switch (RegisterId)
570 {
571 case ARB_DIS:
572 Mask = ARB_DIS_MASK;
573 break;
574
575 default:
576 Mask = 0;
577 break;
578 }
579
580 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL);
581
543
544 if (ReadWrite == ACPI_WRITE)
545 {
546 RegisterValue &= ~Mask;
547 Value <<= AcpiHwGetBitShift (Mask);
548 Value &= Mask;
549 RegisterValue |= Value;
550
551 /*
552 * SLP_TYPE_x Registers are written differently
553 * than any other control Registers with
554 * respect to A and B Registers. The value
555 * for A may be different than the value for B
556 *
557 * Therefore, pass the RegisterId, not just generic PM1_CONTROL,
558 * because we need to do different things. Yuck.
559 */
560
561 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId,
562 (UINT16) RegisterValue);
563 }
564 break;
565
566
567 case PM2_CONTROL:
568
569 switch (RegisterId)
570 {
571 case ARB_DIS:
572 Mask = ARB_DIS_MASK;
573 break;
574
575 default:
576 Mask = 0;
577 break;
578 }
579
580 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL);
581
582 DEBUG_PRINT (TRACE_IO, ("PM2 control: Read %X from %p\n",
582 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %p\n",
583 RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)));
584
585 if (ReadWrite == ACPI_WRITE)
586 {
587 RegisterValue &= ~Mask;
588 Value <<= AcpiHwGetBitShift (Mask);
589 Value &= Mask;
590 RegisterValue |= Value;
591
583 RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)));
584
585 if (ReadWrite == ACPI_WRITE)
586 {
587 RegisterValue &= ~Mask;
588 Value <<= AcpiHwGetBitShift (Mask);
589 Value &= Mask;
590 RegisterValue |= Value;
591
592 DEBUG_PRINT (TRACE_IO, ("About to write %04X to %p\n", RegisterValue,
592 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %p\n", RegisterValue,
593 AcpiGbl_FADT->XPm2CntBlk.Address));
594
595 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
596 PM2_CONTROL, (UINT8) (RegisterValue));
597 }
598 break;
599
600
601 case PM_TIMER:
602
603 Mask = TMR_VAL_MASK;
604 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
605 PM_TIMER);
593 AcpiGbl_FADT->XPm2CntBlk.Address));
594
595 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
596 PM2_CONTROL, (UINT8) (RegisterValue));
597 }
598 break;
599
600
601 case PM_TIMER:
602
603 Mask = TMR_VAL_MASK;
604 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
605 PM_TIMER);
606 DEBUG_PRINT (TRACE_IO, ("PM_TIMER: Read %X from %p\n",
606 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM_TIMER: Read %X from %p\n",
607 RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPmTmrBlk.Address)));
608
609 break;
610
611
612 case GPE1_EN_BLOCK:
613 case GPE1_STS_BLOCK:
614 case GPE0_EN_BLOCK:
615 case GPE0_STS_BLOCK:
616
617 /* Determine the bit to be accessed
618 *
619 * (UINT32) RegisterId:
620 * 31 24 16 8 0
621 * +--------+--------+--------+--------+
622 * | gpe_block_id | gpe_bit_number |
623 * +--------+--------+--------+--------+
624 *
625 * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
626 * gpe_bit_number is relative from the gpe_block (0x00~0xFF)
627 */
628
629 Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */
630 RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3);
631 Mask = AcpiGbl_DecodeTo8bit [Mask % 8];
632
633 /*
634 * The base address of the GPE 0 Register Block
635 * Plus 1/2 the length of the GPE 0 Register Block
636 * The enable Register is the Register following the Status Register
637 * and each Register is defined as 1/2 of the total Register Block
638 */
639
640 /*
641 * This sets the bit within EnableBit that needs to be written to
642 * the Register indicated in Mask to a 1, all others are 0
643 */
644
645 /* Now get the current Enable Bits in the selected Reg */
646
647 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId);
607 RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPmTmrBlk.Address)));
608
609 break;
610
611
612 case GPE1_EN_BLOCK:
613 case GPE1_STS_BLOCK:
614 case GPE0_EN_BLOCK:
615 case GPE0_STS_BLOCK:
616
617 /* Determine the bit to be accessed
618 *
619 * (UINT32) RegisterId:
620 * 31 24 16 8 0
621 * +--------+--------+--------+--------+
622 * | gpe_block_id | gpe_bit_number |
623 * +--------+--------+--------+--------+
624 *
625 * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
626 * gpe_bit_number is relative from the gpe_block (0x00~0xFF)
627 */
628
629 Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */
630 RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3);
631 Mask = AcpiGbl_DecodeTo8bit [Mask % 8];
632
633 /*
634 * The base address of the GPE 0 Register Block
635 * Plus 1/2 the length of the GPE 0 Register Block
636 * The enable Register is the Register following the Status Register
637 * and each Register is defined as 1/2 of the total Register Block
638 */
639
640 /*
641 * This sets the bit within EnableBit that needs to be written to
642 * the Register indicated in Mask to a 1, all others are 0
643 */
644
645 /* Now get the current Enable Bits in the selected Reg */
646
647 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId);
648 DEBUG_PRINT (TRACE_IO, ("GPE Enable bits: Read %X from %X\n",
648 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "GPE Enable bits: Read %X from %X\n",
649 RegisterValue, RegisterId));
650
651 if (ReadWrite == ACPI_WRITE)
652 {
653 RegisterValue &= ~Mask;
654 Value <<= AcpiHwGetBitShift (Mask);
655 Value &= Mask;
656 RegisterValue |= Value;
657
658 /* This write will put the Action state into the General Purpose */
659 /* Enable Register indexed by the value in Mask */
660
649 RegisterValue, RegisterId));
650
651 if (ReadWrite == ACPI_WRITE)
652 {
653 RegisterValue &= ~Mask;
654 Value <<= AcpiHwGetBitShift (Mask);
655 Value &= Mask;
656 RegisterValue |= Value;
657
658 /* This write will put the Action state into the General Purpose */
659 /* Enable Register indexed by the value in Mask */
660
661 DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n",
661 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
662 RegisterValue, RegisterId));
663 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId,
664 (UINT8) RegisterValue);
665 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
666 RegisterId);
667 }
668 break;
669
670
671 case SMI_CMD_BLOCK:
672 case PROCESSOR_BLOCK:
673 /* Not used by any callers at this time - therefore, not implemented */
674
675 default:
676
677 Mask = 0;
678 break;
679 }
680
681 if (ACPI_MTX_LOCK == UseLock) {
682 AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
683 }
684
685
686 RegisterValue &= Mask;
687 RegisterValue >>= AcpiHwGetBitShift (Mask);
688
662 RegisterValue, RegisterId));
663 AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId,
664 (UINT8) RegisterValue);
665 RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
666 RegisterId);
667 }
668 break;
669
670
671 case SMI_CMD_BLOCK:
672 case PROCESSOR_BLOCK:
673 /* Not used by any callers at this time - therefore, not implemented */
674
675 default:
676
677 Mask = 0;
678 break;
679 }
680
681 if (ACPI_MTX_LOCK == UseLock) {
682 AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
683 }
684
685
686 RegisterValue &= Mask;
687 RegisterValue >>= AcpiHwGetBitShift (Mask);
688
689 DEBUG_PRINT (TRACE_IO, ("Register I/O: returning %X\n", RegisterValue));
689 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Register I/O: returning %X\n", RegisterValue));
690 return_VALUE (RegisterValue);
691}
692
693
694/******************************************************************************
695 *
696 * FUNCTION: AcpiHwRegisterRead
697 *
698 * PARAMETERS: UseLock - Mutex hw access.
699 * RegisterId - RegisterID + Offset.
700 *
701 * RETURN: Value read or written.
702 *
703 * DESCRIPTION: Acpi register read function. Registers are read at the
704 * given offset.
705 *
706 ******************************************************************************/
707
708UINT32
709AcpiHwRegisterRead (
710 BOOLEAN UseLock,
711 UINT32 RegisterId)
712{
713 UINT32 Value = 0;
714 UINT32 BankOffset;
715
716
717 FUNCTION_TRACE ("AcpiHwRegisterRead");
718
719
720 if (ACPI_MTX_LOCK == UseLock)
721 {
722 AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
723 }
724
725
726 switch (REGISTER_BLOCK_ID(RegisterId))
727 {
728 case PM1_STS: /* 16-bit access */
729
730 Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
731 Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
732 break;
733
734
735 case PM1_EN: /* 16-bit access*/
736
737 BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
738 Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
739 Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
740 break;
741
742
743 case PM1_CONTROL: /* 16-bit access */
744
745 Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0);
746 Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0);
747 break;
748
749
750 case PM2_CONTROL: /* 8-bit access */
751
752 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0);
753 break;
754
755
756 case PM_TIMER: /* 32-bit access */
757
758 Value = AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0);
759 break;
760
761
690 return_VALUE (RegisterValue);
691}
692
693
694/******************************************************************************
695 *
696 * FUNCTION: AcpiHwRegisterRead
697 *
698 * PARAMETERS: UseLock - Mutex hw access.
699 * RegisterId - RegisterID + Offset.
700 *
701 * RETURN: Value read or written.
702 *
703 * DESCRIPTION: Acpi register read function. Registers are read at the
704 * given offset.
705 *
706 ******************************************************************************/
707
708UINT32
709AcpiHwRegisterRead (
710 BOOLEAN UseLock,
711 UINT32 RegisterId)
712{
713 UINT32 Value = 0;
714 UINT32 BankOffset;
715
716
717 FUNCTION_TRACE ("AcpiHwRegisterRead");
718
719
720 if (ACPI_MTX_LOCK == UseLock)
721 {
722 AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
723 }
724
725
726 switch (REGISTER_BLOCK_ID(RegisterId))
727 {
728 case PM1_STS: /* 16-bit access */
729
730 Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
731 Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
732 break;
733
734
735 case PM1_EN: /* 16-bit access*/
736
737 BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
738 Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
739 Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
740 break;
741
742
743 case PM1_CONTROL: /* 16-bit access */
744
745 Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0);
746 Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0);
747 break;
748
749
750 case PM2_CONTROL: /* 8-bit access */
751
752 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0);
753 break;
754
755
756 case PM_TIMER: /* 32-bit access */
757
758 Value = AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0);
759 break;
760
761
762 /*
763 * For the GPE? Blocks, the lower word of RegisterId contains the
764 * byte offset for which to read, as each part of each block may be
765 * several bytes long.
766 */
762 case GPE0_STS_BLOCK: /* 8-bit access */
763
767 case GPE0_STS_BLOCK: /* 8-bit access */
768
764 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, 0);
769 BankOffset = REGISTER_BIT_ID(RegisterId);
770 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
765 break;
766
771 break;
772
767
768 case GPE0_EN_BLOCK: /* 8-bit access */
769
773 case GPE0_EN_BLOCK: /* 8-bit access */
774
770 BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
771 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
775 BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen) + REGISTER_BIT_ID(RegisterId);
776 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
772 break;
773
777 break;
778
774
775 case GPE1_STS_BLOCK: /* 8-bit access */
776
779 case GPE1_STS_BLOCK: /* 8-bit access */
780
777 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, 0);
781 BankOffset = REGISTER_BIT_ID(RegisterId);
782 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
778 break;
779
783 break;
784
780
781 case GPE1_EN_BLOCK: /* 8-bit access */
782
785 case GPE1_EN_BLOCK: /* 8-bit access */
786
783 BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
784 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
787 BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen) + REGISTER_BIT_ID(RegisterId);
788 Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
785 break;
786
789 break;
790
787
788 case SMI_CMD_BLOCK: /* 8bit */
789
790 AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value, 8);
791 break;
792
791 case SMI_CMD_BLOCK: /* 8bit */
792
793 AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value, 8);
794 break;
795
793
794 default:
795 /* Value will be returned as 0 */
796 break;
797 }
798
799
800 if (ACPI_MTX_LOCK == UseLock)
801 {
802 AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
803 }
804
805 return_VALUE (Value);
806}
807
808
809/******************************************************************************
810 *
811 * FUNCTION: AcpiHwRegisterWrite
812 *
813 * PARAMETERS: UseLock - Mutex hw access.
814 * RegisterId - RegisterID + Offset.
815 *
816 * RETURN: Value read or written.
817 *
818 * DESCRIPTION: Acpi register Write function. Registers are written at the
819 * given offset.
820 *
821 ******************************************************************************/
822
823void
824AcpiHwRegisterWrite (
825 BOOLEAN UseLock,
826 UINT32 RegisterId,
827 UINT32 Value)
828{
829 UINT32 BankOffset;
830
831 FUNCTION_TRACE ("AcpiHwRegisterWrite");
832
833
834 if (ACPI_MTX_LOCK == UseLock)
835 {
836 AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
837 }
838
839
840 switch (REGISTER_BLOCK_ID (RegisterId))
841 {
842 case PM1_STS: /* 16-bit access */
843
844 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
845 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
846 break;
847
848
849 case PM1_EN: /* 16-bit access*/
850
851 BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
852 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
853 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
854 break;
855
856
857 case PM1_CONTROL: /* 16-bit access */
858
859 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
860 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
861 break;
862
863
864 case PM1A_CONTROL: /* 16-bit access */
865
866 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
867 break;
868
869
870 case PM1B_CONTROL: /* 16-bit access */
871
872 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
873 break;
874
875
876 case PM2_CONTROL: /* 8-bit access */
877
878 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0);
879 break;
880
881
882 case PM_TIMER: /* 32-bit access */
883
884 AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0);
885 break;
886
887
888 case GPE0_STS_BLOCK: /* 8-bit access */
889
796 default:
797 /* Value will be returned as 0 */
798 break;
799 }
800
801
802 if (ACPI_MTX_LOCK == UseLock)
803 {
804 AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
805 }
806
807 return_VALUE (Value);
808}
809
810
811/******************************************************************************
812 *
813 * FUNCTION: AcpiHwRegisterWrite
814 *
815 * PARAMETERS: UseLock - Mutex hw access.
816 * RegisterId - RegisterID + Offset.
817 *
818 * RETURN: Value read or written.
819 *
820 * DESCRIPTION: Acpi register Write function. Registers are written at the
821 * given offset.
822 *
823 ******************************************************************************/
824
825void
826AcpiHwRegisterWrite (
827 BOOLEAN UseLock,
828 UINT32 RegisterId,
829 UINT32 Value)
830{
831 UINT32 BankOffset;
832
833 FUNCTION_TRACE ("AcpiHwRegisterWrite");
834
835
836 if (ACPI_MTX_LOCK == UseLock)
837 {
838 AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
839 }
840
841
842 switch (REGISTER_BLOCK_ID (RegisterId))
843 {
844 case PM1_STS: /* 16-bit access */
845
846 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
847 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
848 break;
849
850
851 case PM1_EN: /* 16-bit access*/
852
853 BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
854 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
855 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
856 break;
857
858
859 case PM1_CONTROL: /* 16-bit access */
860
861 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
862 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
863 break;
864
865
866 case PM1A_CONTROL: /* 16-bit access */
867
868 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
869 break;
870
871
872 case PM1B_CONTROL: /* 16-bit access */
873
874 AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
875 break;
876
877
878 case PM2_CONTROL: /* 8-bit access */
879
880 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0);
881 break;
882
883
884 case PM_TIMER: /* 32-bit access */
885
886 AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0);
887 break;
888
889
890 case GPE0_STS_BLOCK: /* 8-bit access */
891
890 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, 0);
892 BankOffset = REGISTER_BIT_ID(RegisterId);
893 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
891 break;
892
893
894 case GPE0_EN_BLOCK: /* 8-bit access */
895
894 break;
895
896
897 case GPE0_EN_BLOCK: /* 8-bit access */
898
896 BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
899 BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen) + REGISTER_BIT_ID(RegisterId);
897 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
898 break;
899
900
901 case GPE1_STS_BLOCK: /* 8-bit access */
902
900 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
901 break;
902
903
904 case GPE1_STS_BLOCK: /* 8-bit access */
905
903 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, 0);
906 BankOffset = REGISTER_BIT_ID(RegisterId);
907 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
904 break;
905
906
907 case GPE1_EN_BLOCK: /* 8-bit access */
908
908 break;
909
910
911 case GPE1_EN_BLOCK: /* 8-bit access */
912
909 BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
913 BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen) + REGISTER_BIT_ID(RegisterId);
910 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
911 break;
912
913
914 case SMI_CMD_BLOCK: /* 8bit */
915
916 /* For 2.0, SMI_CMD is always in IO space */
917 /* TBD: what about 1.0? 0.71? */
918
919 AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, Value, 8);
920 break;
921
922
923 default:
924 Value = 0;
925 break;
926 }
927
928
929 if (ACPI_MTX_LOCK == UseLock)
930 {
931 AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
932 }
933
934 return_VOID;
935}
936
937
938/******************************************************************************
939 *
940 * FUNCTION: AcpiHwLowLevelRead
941 *
942 * PARAMETERS: Register - GAS register structure
943 * Offset - Offset from the base address in the GAS
944 * Width - 8, 16, or 32
945 *
946 * RETURN: Value read
947 *
948 * DESCRIPTION: Read from either memory, IO, or PCI config space.
949 *
950 ******************************************************************************/
951
952UINT32
953AcpiHwLowLevelRead (
954 UINT32 Width,
955 ACPI_GENERIC_ADDRESS *Reg,
956 UINT32 Offset)
957{
958 UINT32 Value = 0;
959 ACPI_PHYSICAL_ADDRESS MemAddress;
960 ACPI_IO_ADDRESS IoAddress;
961 ACPI_PCI_ID PciId;
962 UINT16 PciRegister;
963
964
965 /*
966 * Must have a valid pointer to a GAS structure, and
967 * a non-zero address within
968 */
969 if ((!Reg) ||
970 (!ACPI_VALID_ADDRESS (Reg->Address)))
971 {
972 return 0;
973 }
974
975
976 /*
977 * Three address spaces supported:
978 * Memory, Io, or PCI config.
979 */
980
981 switch (Reg->AddressSpaceId)
982 {
983 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
984
985 MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
986
987 AcpiOsReadMemory (MemAddress, &Value, Width);
988 break;
989
990
991 case ACPI_ADR_SPACE_SYSTEM_IO:
992
993 IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
994
995 AcpiOsReadPort (IoAddress, &Value, Width);
996 break;
997
998
999 case ACPI_ADR_SPACE_PCI_CONFIG:
1000
1001 PciId.Segment = 0;
1002 PciId.Bus = 0;
1003 PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
1004 PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
1005 PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset);
1006
1007 AcpiOsReadPciConfiguration (&PciId, PciRegister, &Value, Width);
1008 break;
1009 }
1010
1011 return Value;
1012}
1013
1014
1015/******************************************************************************
1016 *
1017 * FUNCTION: AcpiHwLowLevelWrite
1018 *
1019 * PARAMETERS: Width - 8, 16, or 32
1020 * Value - To be written
1021 * Register - GAS register structure
1022 * Offset - Offset from the base address in the GAS
1023 *
1024 *
1025 * RETURN: Value read
1026 *
1027 * DESCRIPTION: Read from either memory, IO, or PCI config space.
1028 *
1029 ******************************************************************************/
1030
1031void
1032AcpiHwLowLevelWrite (
1033 UINT32 Width,
1034 UINT32 Value,
1035 ACPI_GENERIC_ADDRESS *Reg,
1036 UINT32 Offset)
1037{
1038 ACPI_PHYSICAL_ADDRESS MemAddress;
1039 ACPI_IO_ADDRESS IoAddress;
1040 ACPI_PCI_ID PciId;
1041 UINT16 PciRegister;
1042
1043
1044 /*
1045 * Must have a valid pointer to a GAS structure, and
1046 * a non-zero address within
1047 */
1048 if ((!Reg) ||
1049 (!ACPI_VALID_ADDRESS (Reg->Address)))
1050 {
1051 return;
1052 }
1053
1054
1055 /*
1056 * Three address spaces supported:
1057 * Memory, Io, or PCI config.
1058 */
1059
1060 switch (Reg->AddressSpaceId)
1061 {
1062 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1063
1064 MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
1065
1066 AcpiOsWriteMemory (MemAddress, Value, Width);
1067 break;
1068
1069
1070 case ACPI_ADR_SPACE_SYSTEM_IO:
1071
1072 IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
1073
1074 AcpiOsWritePort (IoAddress, Value, Width);
1075 break;
1076
1077
1078 case ACPI_ADR_SPACE_PCI_CONFIG:
1079
1080 PciId.Segment = 0;
1081 PciId.Bus = 0;
1082 PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
1083 PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
1084 PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset);
1085
1086 AcpiOsWritePciConfiguration (&PciId, PciRegister, Value, Width);
1087 break;
1088 }
1089}
914 AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
915 break;
916
917
918 case SMI_CMD_BLOCK: /* 8bit */
919
920 /* For 2.0, SMI_CMD is always in IO space */
921 /* TBD: what about 1.0? 0.71? */
922
923 AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, Value, 8);
924 break;
925
926
927 default:
928 Value = 0;
929 break;
930 }
931
932
933 if (ACPI_MTX_LOCK == UseLock)
934 {
935 AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
936 }
937
938 return_VOID;
939}
940
941
942/******************************************************************************
943 *
944 * FUNCTION: AcpiHwLowLevelRead
945 *
946 * PARAMETERS: Register - GAS register structure
947 * Offset - Offset from the base address in the GAS
948 * Width - 8, 16, or 32
949 *
950 * RETURN: Value read
951 *
952 * DESCRIPTION: Read from either memory, IO, or PCI config space.
953 *
954 ******************************************************************************/
955
956UINT32
957AcpiHwLowLevelRead (
958 UINT32 Width,
959 ACPI_GENERIC_ADDRESS *Reg,
960 UINT32 Offset)
961{
962 UINT32 Value = 0;
963 ACPI_PHYSICAL_ADDRESS MemAddress;
964 ACPI_IO_ADDRESS IoAddress;
965 ACPI_PCI_ID PciId;
966 UINT16 PciRegister;
967
968
969 /*
970 * Must have a valid pointer to a GAS structure, and
971 * a non-zero address within
972 */
973 if ((!Reg) ||
974 (!ACPI_VALID_ADDRESS (Reg->Address)))
975 {
976 return 0;
977 }
978
979
980 /*
981 * Three address spaces supported:
982 * Memory, Io, or PCI config.
983 */
984
985 switch (Reg->AddressSpaceId)
986 {
987 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
988
989 MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
990
991 AcpiOsReadMemory (MemAddress, &Value, Width);
992 break;
993
994
995 case ACPI_ADR_SPACE_SYSTEM_IO:
996
997 IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
998
999 AcpiOsReadPort (IoAddress, &Value, Width);
1000 break;
1001
1002
1003 case ACPI_ADR_SPACE_PCI_CONFIG:
1004
1005 PciId.Segment = 0;
1006 PciId.Bus = 0;
1007 PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
1008 PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
1009 PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset);
1010
1011 AcpiOsReadPciConfiguration (&PciId, PciRegister, &Value, Width);
1012 break;
1013 }
1014
1015 return Value;
1016}
1017
1018
1019/******************************************************************************
1020 *
1021 * FUNCTION: AcpiHwLowLevelWrite
1022 *
1023 * PARAMETERS: Width - 8, 16, or 32
1024 * Value - To be written
1025 * Register - GAS register structure
1026 * Offset - Offset from the base address in the GAS
1027 *
1028 *
1029 * RETURN: Value read
1030 *
1031 * DESCRIPTION: Read from either memory, IO, or PCI config space.
1032 *
1033 ******************************************************************************/
1034
1035void
1036AcpiHwLowLevelWrite (
1037 UINT32 Width,
1038 UINT32 Value,
1039 ACPI_GENERIC_ADDRESS *Reg,
1040 UINT32 Offset)
1041{
1042 ACPI_PHYSICAL_ADDRESS MemAddress;
1043 ACPI_IO_ADDRESS IoAddress;
1044 ACPI_PCI_ID PciId;
1045 UINT16 PciRegister;
1046
1047
1048 /*
1049 * Must have a valid pointer to a GAS structure, and
1050 * a non-zero address within
1051 */
1052 if ((!Reg) ||
1053 (!ACPI_VALID_ADDRESS (Reg->Address)))
1054 {
1055 return;
1056 }
1057
1058
1059 /*
1060 * Three address spaces supported:
1061 * Memory, Io, or PCI config.
1062 */
1063
1064 switch (Reg->AddressSpaceId)
1065 {
1066 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1067
1068 MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
1069
1070 AcpiOsWriteMemory (MemAddress, Value, Width);
1071 break;
1072
1073
1074 case ACPI_ADR_SPACE_SYSTEM_IO:
1075
1076 IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
1077
1078 AcpiOsWritePort (IoAddress, Value, Width);
1079 break;
1080
1081
1082 case ACPI_ADR_SPACE_PCI_CONFIG:
1083
1084 PciId.Segment = 0;
1085 PciId.Bus = 0;
1086 PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
1087 PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
1088 PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset);
1089
1090 AcpiOsWritePciConfiguration (&PciId, PciRegister, Value, Width);
1091 break;
1092 }
1093}