1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 |
2 | /****************************************************************************** |
3 | * |
4 | * Module Name: utdecode - Utility decoding routines (value-to-string) |
5 | * |
6 | * Copyright (C) 2000 - 2023, Intel Corp. |
7 | * |
8 | *****************************************************************************/ |
9 | |
10 | #include <acpi/acpi.h> |
11 | #include "accommon.h" |
12 | #include "acnamesp.h" |
13 | #include "amlcode.h" |
14 | |
15 | #define _COMPONENT ACPI_UTILITIES |
16 | ACPI_MODULE_NAME("utdecode" ) |
17 | |
18 | /* |
19 | * Properties of the ACPI Object Types, both internal and external. |
20 | * The table is indexed by values of acpi_object_type |
21 | */ |
22 | const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES] = { |
23 | ACPI_NS_NORMAL, /* 00 Any */ |
24 | ACPI_NS_NORMAL, /* 01 Number */ |
25 | ACPI_NS_NORMAL, /* 02 String */ |
26 | ACPI_NS_NORMAL, /* 03 Buffer */ |
27 | ACPI_NS_NORMAL, /* 04 Package */ |
28 | ACPI_NS_NORMAL, /* 05 field_unit */ |
29 | ACPI_NS_NEWSCOPE, /* 06 Device */ |
30 | ACPI_NS_NORMAL, /* 07 Event */ |
31 | ACPI_NS_NEWSCOPE, /* 08 Method */ |
32 | ACPI_NS_NORMAL, /* 09 Mutex */ |
33 | ACPI_NS_NORMAL, /* 10 Region */ |
34 | ACPI_NS_NEWSCOPE, /* 11 Power */ |
35 | ACPI_NS_NEWSCOPE, /* 12 Processor */ |
36 | ACPI_NS_NEWSCOPE, /* 13 Thermal */ |
37 | ACPI_NS_NORMAL, /* 14 buffer_field */ |
38 | ACPI_NS_NORMAL, /* 15 ddb_handle */ |
39 | ACPI_NS_NORMAL, /* 16 Debug Object */ |
40 | ACPI_NS_NORMAL, /* 17 def_field */ |
41 | ACPI_NS_NORMAL, /* 18 bank_field */ |
42 | ACPI_NS_NORMAL, /* 19 index_field */ |
43 | ACPI_NS_NORMAL, /* 20 Reference */ |
44 | ACPI_NS_NORMAL, /* 21 Alias */ |
45 | ACPI_NS_NORMAL, /* 22 method_alias */ |
46 | ACPI_NS_NORMAL, /* 23 Notify */ |
47 | ACPI_NS_NORMAL, /* 24 Address Handler */ |
48 | ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */ |
49 | ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */ |
50 | ACPI_NS_NEWSCOPE, /* 27 Scope */ |
51 | ACPI_NS_NORMAL, /* 28 Extra */ |
52 | ACPI_NS_NORMAL, /* 29 Data */ |
53 | ACPI_NS_NORMAL /* 30 Invalid */ |
54 | }; |
55 | |
56 | /******************************************************************************* |
57 | * |
58 | * FUNCTION: acpi_ut_get_region_name |
59 | * |
60 | * PARAMETERS: Space ID - ID for the region |
61 | * |
62 | * RETURN: Decoded region space_id name |
63 | * |
64 | * DESCRIPTION: Translate a Space ID into a name string (Debug only) |
65 | * |
66 | ******************************************************************************/ |
67 | |
68 | /* Region type decoding */ |
69 | |
70 | const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { |
71 | "SystemMemory" , /* 0x00 */ |
72 | "SystemIO" , /* 0x01 */ |
73 | "PCI_Config" , /* 0x02 */ |
74 | "EmbeddedControl" , /* 0x03 */ |
75 | "SMBus" , /* 0x04 */ |
76 | "SystemCMOS" , /* 0x05 */ |
77 | "PCIBARTarget" , /* 0x06 */ |
78 | "IPMI" , /* 0x07 */ |
79 | "GeneralPurposeIo" , /* 0x08 */ |
80 | "GenericSerialBus" , /* 0x09 */ |
81 | "PCC" , /* 0x0A */ |
82 | "PlatformRtMechanism" /* 0x0B */ |
83 | }; |
84 | |
85 | const char *acpi_ut_get_region_name(u8 space_id) |
86 | { |
87 | |
88 | if (space_id >= ACPI_USER_REGION_BEGIN) { |
89 | return ("UserDefinedRegion" ); |
90 | } else if (space_id == ACPI_ADR_SPACE_DATA_TABLE) { |
91 | return ("DataTable" ); |
92 | } else if (space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { |
93 | return ("FunctionalFixedHW" ); |
94 | } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) { |
95 | return ("InvalidSpaceId" ); |
96 | } |
97 | |
98 | return (acpi_gbl_region_types[space_id]); |
99 | } |
100 | |
101 | /******************************************************************************* |
102 | * |
103 | * FUNCTION: acpi_ut_get_event_name |
104 | * |
105 | * PARAMETERS: event_id - Fixed event ID |
106 | * |
107 | * RETURN: Decoded event ID name |
108 | * |
109 | * DESCRIPTION: Translate a Event ID into a name string (Debug only) |
110 | * |
111 | ******************************************************************************/ |
112 | |
113 | /* Event type decoding */ |
114 | |
115 | static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = { |
116 | "PM_Timer" , |
117 | "GlobalLock" , |
118 | "PowerButton" , |
119 | "SleepButton" , |
120 | "RealTimeClock" , |
121 | }; |
122 | |
123 | const char *acpi_ut_get_event_name(u32 event_id) |
124 | { |
125 | |
126 | if (event_id > ACPI_EVENT_MAX) { |
127 | return ("InvalidEventID" ); |
128 | } |
129 | |
130 | return (acpi_gbl_event_types[event_id]); |
131 | } |
132 | |
133 | /******************************************************************************* |
134 | * |
135 | * FUNCTION: acpi_ut_get_type_name |
136 | * |
137 | * PARAMETERS: type - An ACPI object type |
138 | * |
139 | * RETURN: Decoded ACPI object type name |
140 | * |
141 | * DESCRIPTION: Translate a Type ID into a name string (Debug only) |
142 | * |
143 | ******************************************************************************/ |
144 | |
145 | /* |
146 | * Elements of acpi_gbl_ns_type_names below must match |
147 | * one-to-one with values of acpi_object_type |
148 | * |
149 | * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; |
150 | * when stored in a table it really means that we have thus far seen no |
151 | * evidence to indicate what type is actually going to be stored for this |
152 | & entry. |
153 | */ |
154 | static const char acpi_gbl_bad_type[] = "UNDEFINED" ; |
155 | |
156 | /* Printable names of the ACPI object types */ |
157 | |
158 | static const char *acpi_gbl_ns_type_names[] = { |
159 | /* 00 */ "Untyped" , |
160 | /* 01 */ "Integer" , |
161 | /* 02 */ "String" , |
162 | /* 03 */ "Buffer" , |
163 | /* 04 */ "Package" , |
164 | /* 05 */ "FieldUnit" , |
165 | /* 06 */ "Device" , |
166 | /* 07 */ "Event" , |
167 | /* 08 */ "Method" , |
168 | /* 09 */ "Mutex" , |
169 | /* 10 */ "Region" , |
170 | /* 11 */ "Power" , |
171 | /* 12 */ "Processor" , |
172 | /* 13 */ "Thermal" , |
173 | /* 14 */ "BufferField" , |
174 | /* 15 */ "DdbHandle" , |
175 | /* 16 */ "DebugObject" , |
176 | /* 17 */ "RegionField" , |
177 | /* 18 */ "BankField" , |
178 | /* 19 */ "IndexField" , |
179 | /* 20 */ "Reference" , |
180 | /* 21 */ "Alias" , |
181 | /* 22 */ "MethodAlias" , |
182 | /* 23 */ "Notify" , |
183 | /* 24 */ "AddrHandler" , |
184 | /* 25 */ "ResourceDesc" , |
185 | /* 26 */ "ResourceFld" , |
186 | /* 27 */ "Scope" , |
187 | /* 28 */ "Extra" , |
188 | /* 29 */ "Data" , |
189 | /* 30 */ "Invalid" |
190 | }; |
191 | |
192 | const char *acpi_ut_get_type_name(acpi_object_type type) |
193 | { |
194 | |
195 | if (type > ACPI_TYPE_INVALID) { |
196 | return (acpi_gbl_bad_type); |
197 | } |
198 | |
199 | return (acpi_gbl_ns_type_names[type]); |
200 | } |
201 | |
202 | const char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc) |
203 | { |
204 | ACPI_FUNCTION_TRACE(ut_get_object_type_name); |
205 | |
206 | if (!obj_desc) { |
207 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n" )); |
208 | return_STR("[NULL Object Descriptor]" ); |
209 | } |
210 | |
211 | /* These descriptor types share a common area */ |
212 | |
213 | if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) && |
214 | (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_NAMED)) { |
215 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
216 | "Invalid object descriptor type: 0x%2.2X [%s] (%p)\n" , |
217 | ACPI_GET_DESCRIPTOR_TYPE(obj_desc), |
218 | acpi_ut_get_descriptor_name(obj_desc), |
219 | obj_desc)); |
220 | |
221 | return_STR("Invalid object" ); |
222 | } |
223 | |
224 | return_STR(acpi_ut_get_type_name(obj_desc->common.type)); |
225 | } |
226 | |
227 | /******************************************************************************* |
228 | * |
229 | * FUNCTION: acpi_ut_get_node_name |
230 | * |
231 | * PARAMETERS: object - A namespace node |
232 | * |
233 | * RETURN: ASCII name of the node |
234 | * |
235 | * DESCRIPTION: Validate the node and return the node's ACPI name. |
236 | * |
237 | ******************************************************************************/ |
238 | |
239 | const char *acpi_ut_get_node_name(void *object) |
240 | { |
241 | struct acpi_namespace_node *node = (struct acpi_namespace_node *)object; |
242 | |
243 | /* Must return a string of exactly 4 characters == ACPI_NAMESEG_SIZE */ |
244 | |
245 | if (!object) { |
246 | return ("NULL" ); |
247 | } |
248 | |
249 | /* Check for Root node */ |
250 | |
251 | if ((object == ACPI_ROOT_OBJECT) || (object == acpi_gbl_root_node)) { |
252 | return ("\"\\\" " ); |
253 | } |
254 | |
255 | /* Descriptor must be a namespace node */ |
256 | |
257 | if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { |
258 | return ("####" ); |
259 | } |
260 | |
261 | /* |
262 | * Ensure name is valid. The name was validated/repaired when the node |
263 | * was created, but make sure it has not been corrupted. |
264 | */ |
265 | acpi_ut_repair_name(name: node->name.ascii); |
266 | |
267 | /* Return the name */ |
268 | |
269 | return (node->name.ascii); |
270 | } |
271 | |
272 | /******************************************************************************* |
273 | * |
274 | * FUNCTION: acpi_ut_get_descriptor_name |
275 | * |
276 | * PARAMETERS: object - An ACPI object |
277 | * |
278 | * RETURN: Decoded name of the descriptor type |
279 | * |
280 | * DESCRIPTION: Validate object and return the descriptor type |
281 | * |
282 | ******************************************************************************/ |
283 | |
284 | /* Printable names of object descriptor types */ |
285 | |
286 | static const char *acpi_gbl_desc_type_names[] = { |
287 | /* 00 */ "Not a Descriptor" , |
288 | /* 01 */ "Cached Object" , |
289 | /* 02 */ "State-Generic" , |
290 | /* 03 */ "State-Update" , |
291 | /* 04 */ "State-Package" , |
292 | /* 05 */ "State-Control" , |
293 | /* 06 */ "State-RootParseScope" , |
294 | /* 07 */ "State-ParseScope" , |
295 | /* 08 */ "State-WalkScope" , |
296 | /* 09 */ "State-Result" , |
297 | /* 10 */ "State-Notify" , |
298 | /* 11 */ "State-Thread" , |
299 | /* 12 */ "Tree Walk State" , |
300 | /* 13 */ "Parse Tree Op" , |
301 | /* 14 */ "Operand Object" , |
302 | /* 15 */ "Namespace Node" |
303 | }; |
304 | |
305 | const char *acpi_ut_get_descriptor_name(void *object) |
306 | { |
307 | |
308 | if (!object) { |
309 | return ("NULL OBJECT" ); |
310 | } |
311 | |
312 | if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) { |
313 | return ("Not a Descriptor" ); |
314 | } |
315 | |
316 | return (acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE(object)]); |
317 | } |
318 | |
319 | /******************************************************************************* |
320 | * |
321 | * FUNCTION: acpi_ut_get_reference_name |
322 | * |
323 | * PARAMETERS: object - An ACPI reference object |
324 | * |
325 | * RETURN: Decoded name of the type of reference |
326 | * |
327 | * DESCRIPTION: Decode a reference object sub-type to a string. |
328 | * |
329 | ******************************************************************************/ |
330 | |
331 | /* Printable names of reference object sub-types */ |
332 | |
333 | static const char *acpi_gbl_ref_class_names[] = { |
334 | /* 00 */ "Local" , |
335 | /* 01 */ "Argument" , |
336 | /* 02 */ "RefOf" , |
337 | /* 03 */ "Index" , |
338 | /* 04 */ "DdbHandle" , |
339 | /* 05 */ "Named Object" , |
340 | /* 06 */ "Debug" |
341 | }; |
342 | |
343 | const char *acpi_ut_get_reference_name(union acpi_operand_object *object) |
344 | { |
345 | |
346 | if (!object) { |
347 | return ("NULL Object" ); |
348 | } |
349 | |
350 | if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) { |
351 | return ("Not an Operand object" ); |
352 | } |
353 | |
354 | if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE) { |
355 | return ("Not a Reference object" ); |
356 | } |
357 | |
358 | if (object->reference.class > ACPI_REFCLASS_MAX) { |
359 | return ("Unknown Reference class" ); |
360 | } |
361 | |
362 | return (acpi_gbl_ref_class_names[object->reference.class]); |
363 | } |
364 | |
365 | /******************************************************************************* |
366 | * |
367 | * FUNCTION: acpi_ut_get_mutex_name |
368 | * |
369 | * PARAMETERS: mutex_id - The predefined ID for this mutex. |
370 | * |
371 | * RETURN: Decoded name of the internal mutex |
372 | * |
373 | * DESCRIPTION: Translate a mutex ID into a name string (Debug only) |
374 | * |
375 | ******************************************************************************/ |
376 | |
377 | /* Names for internal mutex objects, used for debug output */ |
378 | |
379 | static const char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = { |
380 | "ACPI_MTX_Interpreter" , |
381 | "ACPI_MTX_Namespace" , |
382 | "ACPI_MTX_Tables" , |
383 | "ACPI_MTX_Events" , |
384 | "ACPI_MTX_Caches" , |
385 | "ACPI_MTX_Memory" , |
386 | }; |
387 | |
388 | const char *acpi_ut_get_mutex_name(u32 mutex_id) |
389 | { |
390 | |
391 | if (mutex_id > ACPI_MAX_MUTEX) { |
392 | return ("Invalid Mutex ID" ); |
393 | } |
394 | |
395 | return (acpi_gbl_mutex_names[mutex_id]); |
396 | } |
397 | |
398 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) |
399 | |
400 | /* |
401 | * Strings and procedures used for debug only |
402 | */ |
403 | |
404 | /******************************************************************************* |
405 | * |
406 | * FUNCTION: acpi_ut_get_notify_name |
407 | * |
408 | * PARAMETERS: notify_value - Value from the Notify() request |
409 | * |
410 | * RETURN: Decoded name for the notify value |
411 | * |
412 | * DESCRIPTION: Translate a Notify Value to a notify namestring. |
413 | * |
414 | ******************************************************************************/ |
415 | |
416 | /* Names for Notify() values, used for debug output */ |
417 | |
418 | static const char *acpi_gbl_generic_notify[ACPI_GENERIC_NOTIFY_MAX + 1] = { |
419 | /* 00 */ "Bus Check" , |
420 | /* 01 */ "Device Check" , |
421 | /* 02 */ "Device Wake" , |
422 | /* 03 */ "Eject Request" , |
423 | /* 04 */ "Device Check Light" , |
424 | /* 05 */ "Frequency Mismatch" , |
425 | /* 06 */ "Bus Mode Mismatch" , |
426 | /* 07 */ "Power Fault" , |
427 | /* 08 */ "Capabilities Check" , |
428 | /* 09 */ "Device PLD Check" , |
429 | /* 0A */ "Reserved" , |
430 | /* 0B */ "System Locality Update" , |
431 | /* 0C */ "Reserved (was previously Shutdown Request)" , |
432 | /* Reserved in ACPI 6.0 */ |
433 | /* 0D */ "System Resource Affinity Update" , |
434 | /* 0E */ "Heterogeneous Memory Attributes Update" , |
435 | /* ACPI 6.2 */ |
436 | /* 0F */ "Error Disconnect Recover" |
437 | /* ACPI 6.3 */ |
438 | }; |
439 | |
440 | static const char *acpi_gbl_device_notify[5] = { |
441 | /* 80 */ "Status Change" , |
442 | /* 81 */ "Information Change" , |
443 | /* 82 */ "Device-Specific Change" , |
444 | /* 83 */ "Device-Specific Change" , |
445 | /* 84 */ "Reserved" |
446 | }; |
447 | |
448 | static const char *acpi_gbl_processor_notify[5] = { |
449 | /* 80 */ "Performance Capability Change" , |
450 | /* 81 */ "C-State Change" , |
451 | /* 82 */ "Throttling Capability Change" , |
452 | /* 83 */ "Guaranteed Change" , |
453 | /* 84 */ "Minimum Excursion" |
454 | }; |
455 | |
456 | static const char *acpi_gbl_thermal_notify[5] = { |
457 | /* 80 */ "Thermal Status Change" , |
458 | /* 81 */ "Thermal Trip Point Change" , |
459 | /* 82 */ "Thermal Device List Change" , |
460 | /* 83 */ "Thermal Relationship Change" , |
461 | /* 84 */ "Reserved" |
462 | }; |
463 | |
464 | const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type) |
465 | { |
466 | |
467 | /* 00 - 0F are "common to all object types" (from ACPI Spec) */ |
468 | |
469 | if (notify_value <= ACPI_GENERIC_NOTIFY_MAX) { |
470 | return (acpi_gbl_generic_notify[notify_value]); |
471 | } |
472 | |
473 | /* 10 - 7F are reserved */ |
474 | |
475 | if (notify_value <= ACPI_MAX_SYS_NOTIFY) { |
476 | return ("Reserved" ); |
477 | } |
478 | |
479 | /* 80 - 84 are per-object-type */ |
480 | |
481 | if (notify_value <= ACPI_SPECIFIC_NOTIFY_MAX) { |
482 | switch (type) { |
483 | case ACPI_TYPE_ANY: |
484 | case ACPI_TYPE_DEVICE: |
485 | return (acpi_gbl_device_notify[notify_value - 0x80]); |
486 | |
487 | case ACPI_TYPE_PROCESSOR: |
488 | return (acpi_gbl_processor_notify[notify_value - 0x80]); |
489 | |
490 | case ACPI_TYPE_THERMAL: |
491 | return (acpi_gbl_thermal_notify[notify_value - 0x80]); |
492 | |
493 | default: |
494 | return ("Target object type does not support notifies" ); |
495 | } |
496 | } |
497 | |
498 | /* 84 - BF are device-specific */ |
499 | |
500 | if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { |
501 | return ("Device-Specific" ); |
502 | } |
503 | |
504 | /* C0 and above are hardware-specific */ |
505 | |
506 | return ("Hardware-Specific" ); |
507 | } |
508 | |
509 | /******************************************************************************* |
510 | * |
511 | * FUNCTION: acpi_ut_get_argument_type_name |
512 | * |
513 | * PARAMETERS: arg_type - an ARGP_* parser argument type |
514 | * |
515 | * RETURN: Decoded ARGP_* type |
516 | * |
517 | * DESCRIPTION: Decode an ARGP_* parser type, as defined in the amlcode.h file, |
518 | * and used in the acopcode.h file. For example, ARGP_TERMARG. |
519 | * Used for debug only. |
520 | * |
521 | ******************************************************************************/ |
522 | |
523 | static const char *acpi_gbl_argument_type[20] = { |
524 | /* 00 */ "Unknown ARGP" , |
525 | /* 01 */ "ByteData" , |
526 | /* 02 */ "ByteList" , |
527 | /* 03 */ "CharList" , |
528 | /* 04 */ "DataObject" , |
529 | /* 05 */ "DataObjectList" , |
530 | /* 06 */ "DWordData" , |
531 | /* 07 */ "FieldList" , |
532 | /* 08 */ "Name" , |
533 | /* 09 */ "NameString" , |
534 | /* 0A */ "ObjectList" , |
535 | /* 0B */ "PackageLength" , |
536 | /* 0C */ "SuperName" , |
537 | /* 0D */ "Target" , |
538 | /* 0E */ "TermArg" , |
539 | /* 0F */ "TermList" , |
540 | /* 10 */ "WordData" , |
541 | /* 11 */ "QWordData" , |
542 | /* 12 */ "SimpleName" , |
543 | /* 13 */ "NameOrRef" |
544 | }; |
545 | |
546 | const char *acpi_ut_get_argument_type_name(u32 arg_type) |
547 | { |
548 | |
549 | if (arg_type > ARGP_MAX) { |
550 | return ("Unknown ARGP" ); |
551 | } |
552 | |
553 | return (acpi_gbl_argument_type[arg_type]); |
554 | } |
555 | |
556 | #endif |
557 | |
558 | /******************************************************************************* |
559 | * |
560 | * FUNCTION: acpi_ut_valid_object_type |
561 | * |
562 | * PARAMETERS: type - Object type to be validated |
563 | * |
564 | * RETURN: TRUE if valid object type, FALSE otherwise |
565 | * |
566 | * DESCRIPTION: Validate an object type |
567 | * |
568 | ******************************************************************************/ |
569 | |
570 | u8 acpi_ut_valid_object_type(acpi_object_type type) |
571 | { |
572 | |
573 | if (type > ACPI_TYPE_LOCAL_MAX) { |
574 | |
575 | /* Note: Assumes all TYPEs are contiguous (external/local) */ |
576 | |
577 | return (FALSE); |
578 | } |
579 | |
580 | return (TRUE); |
581 | } |
582 | |