ReactOS  0.4.14-dev-384-g5b37caa
exutils.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: exutils - interpreter/scanner utilities
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2019, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  * notice, this list of conditions, and the following disclaimer,
16  * without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  * substantially similar to the "NO WARRANTY" disclaimer below
19  * ("Disclaimer") and any redistribution must be conditioned upon
20  * including a substantially similar Disclaimer requirement for further
21  * binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  * of any contributors may be used to endorse or promote products derived
24  * from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 /*
45  * DEFINE_AML_GLOBALS is tested in amlcode.h
46  * to determine whether certain global names should be "defined" or only
47  * "declared" in the current compilation. This enhances maintainability
48  * by enabling a single header file to embody all knowledge of the names
49  * in question.
50  *
51  * Exactly one module of any executable should #define DEFINE_GLOBALS
52  * before #including the header files which use this convention. The
53  * names in question will be defined and initialized in that module,
54  * and declared as extern in all other modules which #include those
55  * header files.
56  */
57 
58 #define DEFINE_AML_GLOBALS
59 
60 #include "acpi.h"
61 #include "accommon.h"
62 #include "acinterp.h"
63 #include "amlcode.h"
64 
65 #define _COMPONENT ACPI_EXECUTER
66  ACPI_MODULE_NAME ("exutils")
67 
68 /* Local prototypes */
69 
70 static UINT32
72  UINT64 Value,
73  UINT32 Base);
74 
75 
76 /*******************************************************************************
77  *
78  * FUNCTION: AcpiExEnterInterpreter
79  *
80  * PARAMETERS: None
81  *
82  * RETURN: None
83  *
84  * DESCRIPTION: Enter the interpreter execution region. Failure to enter
85  * the interpreter region is a fatal system error. Used in
86  * conjunction with ExitInterpreter.
87  *
88  ******************************************************************************/
89 
90 void
92  void)
93 {
95 
96 
97  ACPI_FUNCTION_TRACE (ExEnterInterpreter);
98 
99 
101  if (ACPI_FAILURE (Status))
102  {
103  ACPI_ERROR ((AE_INFO, "Could not acquire AML Interpreter mutex"));
104  }
106  if (ACPI_FAILURE (Status))
107  {
108  ACPI_ERROR ((AE_INFO, "Could not acquire AML Namespace mutex"));
109  }
110 
111  return_VOID;
112 }
113 
114 
115 /*******************************************************************************
116  *
117  * FUNCTION: AcpiExExitInterpreter
118  *
119  * PARAMETERS: None
120  *
121  * RETURN: None
122  *
123  * DESCRIPTION: Exit the interpreter execution region. This is the top level
124  * routine used to exit the interpreter when all processing has
125  * been completed, or when the method blocks.
126  *
127  * Cases where the interpreter is unlocked internally:
128  * 1) Method will be blocked on a Sleep() AML opcode
129  * 2) Method will be blocked on an Acquire() AML opcode
130  * 3) Method will be blocked on a Wait() AML opcode
131  * 4) Method will be blocked to acquire the global lock
132  * 5) Method will be blocked waiting to execute a serialized control
133  * method that is currently executing
134  * 6) About to invoke a user-installed opregion handler
135  *
136  ******************************************************************************/
137 
138 void
140  void)
141 {
143 
144 
145  ACPI_FUNCTION_TRACE (ExExitInterpreter);
146 
147 
149  if (ACPI_FAILURE (Status))
150  {
151  ACPI_ERROR ((AE_INFO, "Could not release AML Namespace mutex"));
152  }
154  if (ACPI_FAILURE (Status))
155  {
156  ACPI_ERROR ((AE_INFO, "Could not release AML Interpreter mutex"));
157  }
158 
159  return_VOID;
160 }
161 
162 
163 /*******************************************************************************
164  *
165  * FUNCTION: AcpiExTruncateFor32bitTable
166  *
167  * PARAMETERS: ObjDesc - Object to be truncated
168  *
169  * RETURN: TRUE if a truncation was performed, FALSE otherwise.
170  *
171  * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is
172  * 32-bit, as determined by the revision of the DSDT.
173  *
174  ******************************************************************************/
175 
176 BOOLEAN
178  ACPI_OPERAND_OBJECT *ObjDesc)
179 {
180 
182 
183 
184  /*
185  * Object must be a valid number and we must be executing
186  * a control method. Object could be NS node for AML_INT_NAMEPATH_OP.
187  */
188  if ((!ObjDesc) ||
190  (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
191  {
192  return (FALSE);
193  }
194 
195  if ((AcpiGbl_IntegerByteWidth == 4) &&
196  (ObjDesc->Integer.Value > (UINT64) ACPI_UINT32_MAX))
197  {
198  /*
199  * We are executing in a 32-bit ACPI table. Truncate
200  * the value to 32 bits by zeroing out the upper 32-bit field
201  */
202  ObjDesc->Integer.Value &= (UINT64) ACPI_UINT32_MAX;
203  return (TRUE);
204  }
205 
206  return (FALSE);
207 }
208 
209 
210 /*******************************************************************************
211  *
212  * FUNCTION: AcpiExAcquireGlobalLock
213  *
214  * PARAMETERS: FieldFlags - Flags with Lock rule:
215  * AlwaysLock or NeverLock
216  *
217  * RETURN: None
218  *
219  * DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field
220  * flags specify that it is to be obtained before field access.
221  *
222  ******************************************************************************/
223 
224 void
226  UINT32 FieldFlags)
227 {
229 
230 
231  ACPI_FUNCTION_TRACE (ExAcquireGlobalLock);
232 
233 
234  /* Only use the lock if the AlwaysLock bit is set */
235 
236  if (!(FieldFlags & AML_FIELD_LOCK_RULE_MASK))
237  {
238  return_VOID;
239  }
240 
241  /* Attempt to get the global lock, wait forever */
242 
244  AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
245 
246  if (ACPI_FAILURE (Status))
247  {
249  "Could not acquire Global Lock"));
250  }
251 
252  return_VOID;
253 }
254 
255 
256 /*******************************************************************************
257  *
258  * FUNCTION: AcpiExReleaseGlobalLock
259  *
260  * PARAMETERS: FieldFlags - Flags with Lock rule:
261  * AlwaysLock or NeverLock
262  *
263  * RETURN: None
264  *
265  * DESCRIPTION: Release the ACPI hardware Global Lock
266  *
267  ******************************************************************************/
268 
269 void
271  UINT32 FieldFlags)
272 {
274 
275 
276  ACPI_FUNCTION_TRACE (ExReleaseGlobalLock);
277 
278 
279  /* Only use the lock if the AlwaysLock bit is set */
280 
281  if (!(FieldFlags & AML_FIELD_LOCK_RULE_MASK))
282  {
283  return_VOID;
284  }
285 
286  /* Release the global lock */
287 
288  Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
289  if (ACPI_FAILURE (Status))
290  {
291  /* Report the error, but there isn't much else we can do */
292 
294  "Could not release Global Lock"));
295  }
296 
297  return_VOID;
298 }
299 
300 
301 /*******************************************************************************
302  *
303  * FUNCTION: AcpiExDigitsNeeded
304  *
305  * PARAMETERS: Value - Value to be represented
306  * Base - Base of representation
307  *
308  * RETURN: The number of digits.
309  *
310  * DESCRIPTION: Calculate the number of digits needed to represent the Value
311  * in the given Base (Radix)
312  *
313  ******************************************************************************/
314 
315 static UINT32
317  UINT64 Value,
318  UINT32 Base)
319 {
320  UINT32 NumDigits;
321  UINT64 CurrentValue;
322 
323 
324  ACPI_FUNCTION_TRACE (ExDigitsNeeded);
325 
326 
327  /* UINT64 is unsigned, so we don't worry about a '-' prefix */
328 
329  if (Value == 0)
330  {
331  return_UINT32 (1);
332  }
333 
334  CurrentValue = Value;
335  NumDigits = 0;
336 
337  /* Count the digits in the requested base */
338 
339  while (CurrentValue)
340  {
341  (void) AcpiUtShortDivide (CurrentValue, Base, &CurrentValue, NULL);
342  NumDigits++;
343  }
344 
345  return_UINT32 (NumDigits);
346 }
347 
348 
349 /*******************************************************************************
350  *
351  * FUNCTION: AcpiExEisaIdToString
352  *
353  * PARAMETERS: OutString - Where to put the converted string (8 bytes)
354  * CompressedId - EISAID to be converted
355  *
356  * RETURN: None
357  *
358  * DESCRIPTION: Convert a numeric EISAID to string representation. Return
359  * buffer must be large enough to hold the string. The string
360  * returned is always exactly of length ACPI_EISAID_STRING_SIZE
361  * (includes null terminator). The EISAID is always 32 bits.
362  *
363  ******************************************************************************/
364 
365 void
367  char *OutString,
368  UINT64 CompressedId)
369 {
370  UINT32 SwappedId;
371 
372 
374 
375 
376  /* The EISAID should be a 32-bit integer */
377 
378  if (CompressedId > ACPI_UINT32_MAX)
379  {
381  "Expected EISAID is larger than 32 bits: "
382  "0x%8.8X%8.8X, truncating",
383  ACPI_FORMAT_UINT64 (CompressedId)));
384  }
385 
386  /* Swap ID to big-endian to get contiguous bits */
387 
388  SwappedId = AcpiUtDwordByteSwap ((UINT32) CompressedId);
389 
390  /* First 3 bytes are uppercase letters. Next 4 bytes are hexadecimal */
391 
392  OutString[0] = (char) (0x40 + (((unsigned long) SwappedId >> 26) & 0x1F));
393  OutString[1] = (char) (0x40 + ((SwappedId >> 21) & 0x1F));
394  OutString[2] = (char) (0x40 + ((SwappedId >> 16) & 0x1F));
395  OutString[3] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 12);
396  OutString[4] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 8);
397  OutString[5] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 4);
398  OutString[6] = AcpiUtHexToAsciiChar ((UINT64) SwappedId, 0);
399  OutString[7] = 0;
400 }
401 
402 
403 /*******************************************************************************
404  *
405  * FUNCTION: AcpiExIntegerToString
406  *
407  * PARAMETERS: OutString - Where to put the converted string. At least
408  * 21 bytes are needed to hold the largest
409  * possible 64-bit integer.
410  * Value - Value to be converted
411  *
412  * RETURN: Converted string in OutString
413  *
414  * DESCRIPTION: Convert a 64-bit integer to decimal string representation.
415  * Assumes string buffer is large enough to hold the string. The
416  * largest string is (ACPI_MAX64_DECIMAL_DIGITS + 1).
417  *
418  ******************************************************************************/
419 
420 void
422  char *OutString,
423  UINT64 Value)
424 {
425  UINT32 Count;
426  UINT32 DigitsNeeded;
428 
429 
431 
432 
433  DigitsNeeded = AcpiExDigitsNeeded (Value, 10);
434  OutString[DigitsNeeded] = 0;
435 
436  for (Count = DigitsNeeded; Count > 0; Count--)
437  {
439  OutString[Count-1] = (char) ('0' + Remainder);\
440  }
441 }
442 
443 
444 /*******************************************************************************
445  *
446  * FUNCTION: AcpiExPciClsToString
447  *
448  * PARAMETERS: OutString - Where to put the converted string (7 bytes)
449  * ClassCode - PCI class code to be converted (3 bytes)
450  *
451  * RETURN: Converted string in OutString
452  *
453  * DESCRIPTION: Convert 3-bytes PCI class code to string representation.
454  * Return buffer must be large enough to hold the string. The
455  * string returned is always exactly of length
456  * ACPI_PCICLS_STRING_SIZE (includes null terminator).
457  *
458  ******************************************************************************/
459 
460 void
462  char *OutString,
463  UINT8 ClassCode[3])
464 {
465 
467 
468 
469  /* All 3 bytes are hexadecimal */
470 
471  OutString[0] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[0], 4);
472  OutString[1] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[0], 0);
473  OutString[2] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[1], 4);
474  OutString[3] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[1], 0);
475  OutString[4] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[2], 4);
476  OutString[5] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[2], 0);
477  OutString[6] = 0;
478 }
479 
480 
481 /*******************************************************************************
482  *
483  * FUNCTION: AcpiIsValidSpaceId
484  *
485  * PARAMETERS: SpaceId - ID to be validated
486  *
487  * RETURN: TRUE if SpaceId is a valid/supported ID.
488  *
489  * DESCRIPTION: Validate an operation region SpaceID.
490  *
491  ******************************************************************************/
492 
493 BOOLEAN
495  UINT8 SpaceId)
496 {
497 
502  {
503  return (FALSE);
504  }
505 
506  return (TRUE);
507 }
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
void AcpiExReleaseGlobalLock(UINT32 FieldFlags)
Definition: exutils.c:270
#define TRUE
Definition: types.h:120
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
ACPI_THREAD_ID AcpiOsGetThreadId(void)
Definition: osl.c:217
#define ACPI_WARNING(plist)
Definition: acoutput.h:238
#define ACPI_TYPE_INTEGER
Definition: actypes.h:679
#define return_UINT32(s)
Definition: acoutput.h:501
BOOLEAN AcpiIsValidSpaceId(UINT8 SpaceId)
Definition: exutils.c:494
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define ACPI_ADR_SPACE_DATA_TABLE
Definition: actypes.h:873
UINT32 ACPI_STATUS
Definition: actypes.h:460
void AcpiExIntegerToString(char *OutString, UINT64 Value)
Definition: exutils.c:421
void AcpiExPciClsToString(char *OutString, UINT8 ClassCode[3])
Definition: exutils.c:461
ACPI_STATUS AcpiExReleaseMutexObject(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: exmutex.c:344
UINT32 AcpiUtDwordByteSwap(UINT32 Value)
Definition: utmisc.c:136
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE ACPI_HANDLE *OutHandle ACPI_HANDLE *OutHandle void *Context void *Context ACPI_EVENT_HANDLER Handler UINT32 UINT32 ACPI_GPE_HANDLER void *Context UINT32 ACPI_NOTIFY_HANDLER void *Context ACPI_ADR_SPACE_TYPE SpaceId
Definition: acpixf.h:828
ACPI_STATUS AcpiUtReleaseMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:348
ACPI_STATUS AcpiUtAcquireMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:256
unsigned int UINT32
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define AE_INFO
Definition: acoutput.h:230
unsigned char
Definition: typeof.h:29
void AcpiExAcquireGlobalLock(UINT32 FieldFlags)
Definition: exutils.c:225
#define ACPI_FUNCTION_ENTRY()
Definition: acoutput.h:484
ACPI_STATUS AcpiExAcquireMutexObject(UINT16 Timeout, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_THREAD_ID ThreadId)
Definition: exmutex.c:176
#define ACPI_DESC_TYPE_OPERAND
Definition: acobject.h:573
ACPI_STATUS AcpiUtShortDivide(UINT64 InDividend, UINT32 Divisor, UINT64 *OutQuotient, UINT32 *OutRemainder)
Definition: utmath.c:337
#define ACPI_WAIT_FOREVER
Definition: actypes.h:501
#define ACPI_UINT32_MAX
Definition: actypes.h:66
#define ACPI_USER_REGION_BEGIN
Definition: acconfig.h:197
#define return_VOID
Definition: acoutput.h:495
#define AML_FIELD_LOCK_RULE_MASK
Definition: amlcode.h:443
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:517
Status
Definition: gdiplustypes.h:24
static UINT32 AcpiExDigitsNeeded(UINT64 Value, UINT32 Base)
Definition: exutils.c:316
#define ACPI_MTX_INTERPRETER
Definition: aclocal.h:84
BOOLEAN AcpiExTruncateFor32bitTable(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: exutils.c:177
void AcpiExExitInterpreter(void)
Definition: exutils.c:139
void AcpiExEnterInterpreter(void)
Definition: exutils.c:91
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
char AcpiUtHexToAsciiChar(UINT64 Integer, UINT32 Position)
Definition: uthex.c:74
ACPI_OBJECT_COMMON Common
Definition: acobject.h:516
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define ACPI_NUM_PREDEFINED_REGIONS
Definition: actypes.h:863
unsigned long long UINT64
void AcpiExEisaIdToString(char *OutString, UINT64 CompressedId)
Definition: exutils.c:366
#define ACPI_MTX_NAMESPACE
Definition: aclocal.h:85
unsigned char UINT8
#define ACPI_ADR_SPACE_FIXED_HARDWARE
Definition: actypes.h:874
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3046
#define ACPI_GET_DESCRIPTOR_TYPE(d)
Definition: acmacros.h:414