1 /*******************************************************************************
2 *
3 * Module Name: dbtest - Various debug-related tests
4 *
5 ******************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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 #include "acpi.h"
45 #include "accommon.h"
46 #include "acdebug.h"
47 #include "acnamesp.h"
48 #include "acpredef.h"
49 #include "acinterp.h"
50
51
52 #define _COMPONENT ACPI_CA_DEBUGGER
53 ACPI_MODULE_NAME ("dbtest")
54
55
56 /* Local prototypes */
57
58 static void
59 AcpiDbTestAllObjects (
60 void);
61
62 static ACPI_STATUS
63 AcpiDbTestOneObject (
64 ACPI_HANDLE ObjHandle,
65 UINT32 NestingLevel,
66 void *Context,
67 void **ReturnValue);
68
69 static ACPI_STATUS
70 AcpiDbTestIntegerType (
71 ACPI_NAMESPACE_NODE *Node,
72 UINT32 BitLength);
73
74 static ACPI_STATUS
75 AcpiDbTestBufferType (
76 ACPI_NAMESPACE_NODE *Node,
77 UINT32 BitLength);
78
79 static ACPI_STATUS
80 AcpiDbTestStringType (
81 ACPI_NAMESPACE_NODE *Node,
82 UINT32 ByteLength);
83
84 static ACPI_STATUS
85 AcpiDbTestPackageType (
86 ACPI_NAMESPACE_NODE *Node);
87
88 static ACPI_STATUS
89 AcpiDbTestFieldUnitType (
90 ACPI_OPERAND_OBJECT *ObjDesc);
91
92 static ACPI_STATUS
93 AcpiDbReadFromObject (
94 ACPI_NAMESPACE_NODE *Node,
95 ACPI_OBJECT_TYPE ExpectedType,
96 ACPI_OBJECT **Value);
97
98 static ACPI_STATUS
99 AcpiDbWriteToObject (
100 ACPI_NAMESPACE_NODE *Node,
101 ACPI_OBJECT *Value);
102
103 static void
104 AcpiDbEvaluateAllPredefinedNames (
105 char *CountArg);
106
107 static ACPI_STATUS
108 AcpiDbEvaluateOnePredefinedName (
109 ACPI_HANDLE ObjHandle,
110 UINT32 NestingLevel,
111 void *Context,
112 void **ReturnValue);
113
114 /*
115 * Test subcommands
116 */
117 static ACPI_DB_ARGUMENT_INFO AcpiDbTestTypes [] =
118 {
119 {"OBJECTS"},
120 {"PREDEFINED"},
121 {NULL} /* Must be null terminated */
122 };
123
124 #define CMD_TEST_OBJECTS 0
125 #define CMD_TEST_PREDEFINED 1
126
127 #define BUFFER_FILL_VALUE 0xFF
128
129 /*
130 * Support for the special debugger read/write control methods.
131 * These methods are installed into the current namespace and are
132 * used to read and write the various namespace objects. The point
133 * is to force the AML interpreter do all of the work.
134 */
135 #define ACPI_DB_READ_METHOD "\\_T98"
136 #define ACPI_DB_WRITE_METHOD "\\_T99"
137
138 static ACPI_HANDLE ReadHandle = NULL;
139 static ACPI_HANDLE WriteHandle = NULL;
140
141 /* ASL Definitions of the debugger read/write control methods. AML below. */
142
143 #if 0
144 DefinitionBlock ("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
145 {
146 Method (_T98, 1, NotSerialized) /* Read */
147 {
148 Return (DeRefOf (Arg0))
149 }
150 }
151 DefinitionBlock ("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
152 {
153 Method (_T99, 2, NotSerialized) /* Write */
154 {
155 Store (Arg1, Arg0)
156 }
157 }
158 #endif
159
160 static unsigned char ReadMethodCode[] =
161 {
162 0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00, /* 00000000 "SSDT...." */
163 0x02,0xC9,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
164 0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00, /* 00000010 "DEBUG..." */
165 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
166 0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54, /* 00000020 "... .._T" */
167 0x39,0x38,0x01,0xA4,0x83,0x68 /* 00000028 "98...h" */
168 };
169
170 static unsigned char WriteMethodCode[] =
171 {
172 0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00, /* 00000000 "SSDT...." */
173 0x02,0x15,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
174 0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00, /* 00000010 "DEBUG..." */
175 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
176 0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54, /* 00000020 "... .._T" */
177 0x39,0x39,0x02,0x70,0x69,0x68 /* 00000028 "99.pih" */
178 };
179
180
181 /*******************************************************************************
182 *
183 * FUNCTION: AcpiDbExecuteTest
184 *
185 * PARAMETERS: TypeArg - Subcommand
186 *
187 * RETURN: None
188 *
189 * DESCRIPTION: Execute various debug tests.
190 *
191 * Note: Code is prepared for future expansion of the TEST command.
192 *
193 ******************************************************************************/
194
195 void
AcpiDbExecuteTest(char * TypeArg)196 AcpiDbExecuteTest (
197 char *TypeArg)
198 {
199 UINT32 Temp;
200
201
202 AcpiUtStrupr (TypeArg);
203 Temp = AcpiDbMatchArgument (TypeArg, AcpiDbTestTypes);
204 if (Temp == ACPI_TYPE_NOT_FOUND)
205 {
206 AcpiOsPrintf ("Invalid or unsupported argument\n");
207 return;
208 }
209
210 switch (Temp)
211 {
212 case CMD_TEST_OBJECTS:
213
214 AcpiDbTestAllObjects ();
215 break;
216
217 case CMD_TEST_PREDEFINED:
218
219 AcpiDbEvaluateAllPredefinedNames (NULL);
220 break;
221
222 default:
223 break;
224 }
225 }
226
227
228 /*******************************************************************************
229 *
230 * FUNCTION: AcpiDbTestAllObjects
231 *
232 * PARAMETERS: None
233 *
234 * RETURN: None
235 *
236 * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
237 * namespace by reading/writing/comparing all data objects such
238 * as integers, strings, buffers, fields, buffer fields, etc.
239 *
240 ******************************************************************************/
241
242 static void
AcpiDbTestAllObjects(void)243 AcpiDbTestAllObjects (
244 void)
245 {
246 ACPI_STATUS Status;
247
248
249 /* Install the debugger read-object control method if necessary */
250
251 if (!ReadHandle)
252 {
253 Status = AcpiInstallMethod (ReadMethodCode);
254 if (ACPI_FAILURE (Status))
255 {
256 AcpiOsPrintf ("%s, Could not install debugger read method\n",
257 AcpiFormatException (Status));
258 return;
259 }
260
261 Status = AcpiGetHandle (NULL, ACPI_DB_READ_METHOD, &ReadHandle);
262 if (ACPI_FAILURE (Status))
263 {
264 AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
265 ACPI_DB_READ_METHOD);
266 return;
267 }
268 }
269
270 /* Install the debugger write-object control method if necessary */
271
272 if (!WriteHandle)
273 {
274 Status = AcpiInstallMethod (WriteMethodCode);
275 if (ACPI_FAILURE (Status))
276 {
277 AcpiOsPrintf ("%s, Could not install debugger write method\n",
278 AcpiFormatException (Status));
279 return;
280 }
281
282 Status = AcpiGetHandle (NULL, ACPI_DB_WRITE_METHOD, &WriteHandle);
283 if (ACPI_FAILURE (Status))
284 {
285 AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
286 ACPI_DB_WRITE_METHOD);
287 return;
288 }
289 }
290
291 /* Walk the entire namespace, testing each supported named data object */
292
293 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
294 ACPI_UINT32_MAX, AcpiDbTestOneObject, NULL, NULL, NULL);
295 }
296
297
298 /*******************************************************************************
299 *
300 * FUNCTION: AcpiDbTestOneObject
301 *
302 * PARAMETERS: ACPI_WALK_CALLBACK
303 *
304 * RETURN: Status
305 *
306 * DESCRIPTION: Test one namespace object. Supported types are Integer,
307 * String, Buffer, Package, BufferField, and FieldUnit.
308 * All other object types are simply ignored.
309 *
310 ******************************************************************************/
311
312 static ACPI_STATUS
AcpiDbTestOneObject(ACPI_HANDLE ObjHandle,UINT32 NestingLevel,void * Context,void ** ReturnValue)313 AcpiDbTestOneObject (
314 ACPI_HANDLE ObjHandle,
315 UINT32 NestingLevel,
316 void *Context,
317 void **ReturnValue)
318 {
319 ACPI_NAMESPACE_NODE *Node;
320 ACPI_OPERAND_OBJECT *ObjDesc;
321 ACPI_OBJECT_TYPE LocalType;
322 UINT32 BitLength = 0;
323 UINT32 ByteLength = 0;
324 ACPI_STATUS Status = AE_OK;
325
326
327 Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
328 ObjDesc = Node->Object;
329
330 /*
331 * For the supported types, get the actual bit length or
332 * byte length. Map the type to one of Integer/String/Buffer.
333 */
334 switch (Node->Type)
335 {
336 case ACPI_TYPE_INTEGER:
337
338 /* Integer width is either 32 or 64 */
339
340 LocalType = ACPI_TYPE_INTEGER;
341 BitLength = AcpiGbl_IntegerBitWidth;
342 break;
343
344 case ACPI_TYPE_STRING:
345
346 LocalType = ACPI_TYPE_STRING;
347 ByteLength = ObjDesc->String.Length;
348 break;
349
350 case ACPI_TYPE_BUFFER:
351
352 LocalType = ACPI_TYPE_BUFFER;
353 ByteLength = ObjDesc->Buffer.Length;
354 BitLength = ByteLength * 8;
355 break;
356
357 case ACPI_TYPE_PACKAGE:
358
359 LocalType = ACPI_TYPE_PACKAGE;
360 break;
361
362 case ACPI_TYPE_FIELD_UNIT:
363 case ACPI_TYPE_LOCAL_REGION_FIELD:
364 case ACPI_TYPE_LOCAL_INDEX_FIELD:
365 case ACPI_TYPE_LOCAL_BANK_FIELD:
366
367 LocalType = ACPI_TYPE_FIELD_UNIT;
368 break;
369
370 case ACPI_TYPE_BUFFER_FIELD:
371 /*
372 * The returned object will be a Buffer if the field length
373 * is larger than the size of an Integer (32 or 64 bits
374 * depending on the DSDT version).
375 */
376 LocalType = ACPI_TYPE_INTEGER;
377 if (ObjDesc)
378 {
379 BitLength = ObjDesc->CommonField.BitLength;
380 ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
381 if (BitLength > AcpiGbl_IntegerBitWidth)
382 {
383 LocalType = ACPI_TYPE_BUFFER;
384 }
385 }
386 break;
387
388 default:
389
390 /* Ignore all non-data types - Methods, Devices, Scopes, etc. */
391
392 return (AE_OK);
393 }
394
395 /* Emit the common prefix: Type:Name */
396
397 AcpiOsPrintf ("%14s: %4.4s",
398 AcpiUtGetTypeName (Node->Type), Node->Name.Ascii);
399
400 if (!ObjDesc)
401 {
402 AcpiOsPrintf (" No attached sub-object, ignoring\n");
403 return (AE_OK);
404 }
405
406 /* At this point, we have resolved the object to one of the major types */
407
408 switch (LocalType)
409 {
410 case ACPI_TYPE_INTEGER:
411
412 Status = AcpiDbTestIntegerType (Node, BitLength);
413 break;
414
415 case ACPI_TYPE_STRING:
416
417 Status = AcpiDbTestStringType (Node, ByteLength);
418 break;
419
420 case ACPI_TYPE_BUFFER:
421
422 Status = AcpiDbTestBufferType (Node, BitLength);
423 break;
424
425 case ACPI_TYPE_PACKAGE:
426
427 Status = AcpiDbTestPackageType (Node);
428 break;
429
430 case ACPI_TYPE_FIELD_UNIT:
431
432 Status = AcpiDbTestFieldUnitType (ObjDesc);
433 break;
434
435 default:
436
437 AcpiOsPrintf (" Ignoring, type not implemented (%2.2X)",
438 LocalType);
439 break;
440 }
441
442 /* Exit on error, but don't abort the namespace walk */
443
444 if (ACPI_FAILURE (Status))
445 {
446 Status = AE_OK;
447 }
448
449 AcpiOsPrintf ("\n");
450 return (Status);
451 }
452
453
454 /*******************************************************************************
455 *
456 * FUNCTION: AcpiDbTestIntegerType
457 *
458 * PARAMETERS: Node - Parent NS node for the object
459 * BitLength - Actual length of the object. Used for
460 * support of arbitrary length FieldUnit
461 * and BufferField objects.
462 *
463 * RETURN: Status
464 *
465 * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
466 * write/read/compare of an arbitrary new value, then performs
467 * a write/read/compare of the original value.
468 *
469 ******************************************************************************/
470
471 static ACPI_STATUS
AcpiDbTestIntegerType(ACPI_NAMESPACE_NODE * Node,UINT32 BitLength)472 AcpiDbTestIntegerType (
473 ACPI_NAMESPACE_NODE *Node,
474 UINT32 BitLength)
475 {
476 ACPI_OBJECT *Temp1 = NULL;
477 ACPI_OBJECT *Temp2 = NULL;
478 ACPI_OBJECT *Temp3 = NULL;
479 ACPI_OBJECT WriteValue;
480 UINT64 ValueToWrite;
481 ACPI_STATUS Status;
482
483
484 if (BitLength > 64)
485 {
486 AcpiOsPrintf (" Invalid length for an Integer: %u", BitLength);
487 return (AE_OK);
488 }
489
490 /* Read the original value */
491
492 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp1);
493 if (ACPI_FAILURE (Status))
494 {
495 return (Status);
496 }
497
498 AcpiOsPrintf (ACPI_DEBUG_LENGTH_FORMAT " %8.8X%8.8X",
499 BitLength, ACPI_ROUND_BITS_UP_TO_BYTES (BitLength),
500 ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
501
502 ValueToWrite = ACPI_UINT64_MAX >> (64 - BitLength);
503 if (Temp1->Integer.Value == ValueToWrite)
504 {
505 ValueToWrite = 0;
506 }
507 /* Write a new value */
508
509 WriteValue.Type = ACPI_TYPE_INTEGER;
510 WriteValue.Integer.Value = ValueToWrite;
511 Status = AcpiDbWriteToObject (Node, &WriteValue);
512 if (ACPI_FAILURE (Status))
513 {
514 goto Exit;
515 }
516
517 /* Ensure that we can read back the new value */
518
519 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp2);
520 if (ACPI_FAILURE (Status))
521 {
522 goto Exit;
523 }
524
525 if (Temp2->Integer.Value != ValueToWrite)
526 {
527 AcpiOsPrintf (" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
528 ACPI_FORMAT_UINT64 (Temp2->Integer.Value),
529 ACPI_FORMAT_UINT64 (ValueToWrite));
530 }
531
532 /* Write back the original value */
533
534 WriteValue.Integer.Value = Temp1->Integer.Value;
535 Status = AcpiDbWriteToObject (Node, &WriteValue);
536 if (ACPI_FAILURE (Status))
537 {
538 goto Exit;
539 }
540
541 /* Ensure that we can read back the original value */
542
543 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp3);
544 if (ACPI_FAILURE (Status))
545 {
546 goto Exit;
547 }
548
549 if (Temp3->Integer.Value != Temp1->Integer.Value)
550 {
551 AcpiOsPrintf (" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
552 ACPI_FORMAT_UINT64 (Temp3->Integer.Value),
553 ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
554 }
555
556 Exit:
557 if (Temp1) {AcpiOsFree (Temp1);}
558 if (Temp2) {AcpiOsFree (Temp2);}
559 if (Temp3) {AcpiOsFree (Temp3);}
560 return (AE_OK);
561 }
562
563
564 /*******************************************************************************
565 *
566 * FUNCTION: AcpiDbTestBufferType
567 *
568 * PARAMETERS: Node - Parent NS node for the object
569 * BitLength - Actual length of the object.
570 *
571 * RETURN: Status
572 *
573 * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
574 * write/read/compare of an arbitrary new value, then performs
575 * a write/read/compare of the original value.
576 *
577 ******************************************************************************/
578
579 static ACPI_STATUS
AcpiDbTestBufferType(ACPI_NAMESPACE_NODE * Node,UINT32 BitLength)580 AcpiDbTestBufferType (
581 ACPI_NAMESPACE_NODE *Node,
582 UINT32 BitLength)
583 {
584 ACPI_OBJECT *Temp1 = NULL;
585 ACPI_OBJECT *Temp2 = NULL;
586 ACPI_OBJECT *Temp3 = NULL;
587 UINT8 *Buffer;
588 ACPI_OBJECT WriteValue;
589 ACPI_STATUS Status;
590 UINT32 ByteLength;
591 UINT32 i;
592 UINT8 ExtraBits;
593
594
595 ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
596 if (ByteLength == 0)
597 {
598 AcpiOsPrintf (" Ignoring zero length buffer");
599 return (AE_OK);
600 }
601
602 /* Allocate a local buffer */
603
604 Buffer = ACPI_ALLOCATE_ZEROED (ByteLength);
605 if (!Buffer)
606 {
607 return (AE_NO_MEMORY);
608 }
609
610 /* Read the original value */
611
612 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp1);
613 if (ACPI_FAILURE (Status))
614 {
615 goto Exit;
616 }
617
618 /* Emit a few bytes of the buffer */
619
620 AcpiOsPrintf (ACPI_DEBUG_LENGTH_FORMAT, BitLength, Temp1->Buffer.Length);
621 for (i = 0; ((i < 8) && (i < ByteLength)); i++)
622 {
623 AcpiOsPrintf (" %2.2X", Temp1->Buffer.Pointer[i]);
624 }
625 AcpiOsPrintf ("... ");
626
627 /*
628 * Write a new value.
629 *
630 * Handle possible extra bits at the end of the buffer. Can
631 * happen for FieldUnits larger than an integer, but the bit
632 * count is not an integral number of bytes. Zero out the
633 * unused bits.
634 */
635 memset (Buffer, BUFFER_FILL_VALUE, ByteLength);
636 ExtraBits = BitLength % 8;
637 if (ExtraBits)
638 {
639 Buffer [ByteLength - 1] = ACPI_MASK_BITS_ABOVE (ExtraBits);
640 }
641
642 WriteValue.Type = ACPI_TYPE_BUFFER;
643 WriteValue.Buffer.Length = ByteLength;
644 WriteValue.Buffer.Pointer = Buffer;
645
646 Status = AcpiDbWriteToObject (Node, &WriteValue);
647 if (ACPI_FAILURE (Status))
648 {
649 goto Exit;
650 }
651
652 /* Ensure that we can read back the new value */
653
654 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp2);
655 if (ACPI_FAILURE (Status))
656 {
657 goto Exit;
658 }
659
660 if (memcmp (Temp2->Buffer.Pointer, Buffer, ByteLength))
661 {
662 AcpiOsPrintf (" MISMATCH 2: New buffer value");
663 }
664
665 /* Write back the original value */
666
667 WriteValue.Buffer.Length = ByteLength;
668 WriteValue.Buffer.Pointer = Temp1->Buffer.Pointer;
669
670 Status = AcpiDbWriteToObject (Node, &WriteValue);
671 if (ACPI_FAILURE (Status))
672 {
673 goto Exit;
674 }
675
676 /* Ensure that we can read back the original value */
677
678 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp3);
679 if (ACPI_FAILURE (Status))
680 {
681 goto Exit;
682 }
683
684 if (memcmp (Temp1->Buffer.Pointer,
685 Temp3->Buffer.Pointer, ByteLength))
686 {
687 AcpiOsPrintf (" MISMATCH 3: While restoring original buffer");
688 }
689
690 Exit:
691 ACPI_FREE (Buffer);
692 if (Temp1) {AcpiOsFree (Temp1);}
693 if (Temp2) {AcpiOsFree (Temp2);}
694 if (Temp3) {AcpiOsFree (Temp3);}
695 return (Status);
696 }
697
698
699 /*******************************************************************************
700 *
701 * FUNCTION: AcpiDbTestStringType
702 *
703 * PARAMETERS: Node - Parent NS node for the object
704 * ByteLength - Actual length of the object.
705 *
706 * RETURN: Status
707 *
708 * DESCRIPTION: Test read/write for an String-valued object. Performs a
709 * write/read/compare of an arbitrary new value, then performs
710 * a write/read/compare of the original value.
711 *
712 ******************************************************************************/
713
714 static ACPI_STATUS
AcpiDbTestStringType(ACPI_NAMESPACE_NODE * Node,UINT32 ByteLength)715 AcpiDbTestStringType (
716 ACPI_NAMESPACE_NODE *Node,
717 UINT32 ByteLength)
718 {
719 ACPI_OBJECT *Temp1 = NULL;
720 ACPI_OBJECT *Temp2 = NULL;
721 ACPI_OBJECT *Temp3 = NULL;
722 char *ValueToWrite = __UNCONST("Test String from AML Debugger");
723 ACPI_OBJECT WriteValue;
724 ACPI_STATUS Status;
725
726
727 /* Read the original value */
728
729 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp1);
730 if (ACPI_FAILURE (Status))
731 {
732 return (Status);
733 }
734
735 AcpiOsPrintf (ACPI_DEBUG_LENGTH_FORMAT " \"%s\"", (Temp1->String.Length * 8),
736 Temp1->String.Length, Temp1->String.Pointer);
737
738 /* Write a new value */
739
740 WriteValue.Type = ACPI_TYPE_STRING;
741 WriteValue.String.Length = strlen (ValueToWrite);
742 WriteValue.String.Pointer = ValueToWrite;
743
744 Status = AcpiDbWriteToObject (Node, &WriteValue);
745 if (ACPI_FAILURE (Status))
746 {
747 goto Exit;
748 }
749
750 /* Ensure that we can read back the new value */
751
752 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp2);
753 if (ACPI_FAILURE (Status))
754 {
755 goto Exit;
756 }
757
758 if (strcmp (Temp2->String.Pointer, ValueToWrite))
759 {
760 AcpiOsPrintf (" MISMATCH 2: %s, expecting %s",
761 Temp2->String.Pointer, ValueToWrite);
762 }
763
764 /* Write back the original value */
765
766 WriteValue.String.Length = strlen (Temp1->String.Pointer);
767 WriteValue.String.Pointer = Temp1->String.Pointer;
768
769 Status = AcpiDbWriteToObject (Node, &WriteValue);
770 if (ACPI_FAILURE (Status))
771 {
772 goto Exit;
773 }
774
775 /* Ensure that we can read back the original value */
776
777 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp3);
778 if (ACPI_FAILURE (Status))
779 {
780 goto Exit;
781 }
782
783 if (strcmp (Temp1->String.Pointer, Temp3->String.Pointer))
784 {
785 AcpiOsPrintf (" MISMATCH 3: %s, expecting %s",
786 Temp3->String.Pointer, Temp1->String.Pointer);
787 }
788
789 Exit:
790 if (Temp1) {AcpiOsFree (Temp1);}
791 if (Temp2) {AcpiOsFree (Temp2);}
792 if (Temp3) {AcpiOsFree (Temp3);}
793 return (Status);
794 }
795
796
797 /*******************************************************************************
798 *
799 * FUNCTION: AcpiDbTestPackageType
800 *
801 * PARAMETERS: Node - Parent NS node for the object
802 *
803 * RETURN: Status
804 *
805 * DESCRIPTION: Test read for a Package object.
806 *
807 ******************************************************************************/
808
809 static ACPI_STATUS
AcpiDbTestPackageType(ACPI_NAMESPACE_NODE * Node)810 AcpiDbTestPackageType (
811 ACPI_NAMESPACE_NODE *Node)
812 {
813 ACPI_OBJECT *Temp1 = NULL;
814 ACPI_STATUS Status;
815
816
817 /* Read the original value */
818
819 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_PACKAGE, &Temp1);
820 if (ACPI_FAILURE (Status))
821 {
822 return (Status);
823 }
824
825 AcpiOsPrintf (" %.2X Elements", Temp1->Package.Count);
826 AcpiOsFree (Temp1);
827 return (Status);
828 }
829
830
831 /*******************************************************************************
832 *
833 * FUNCTION: AcpiDbTestFieldUnitType
834 *
835 * PARAMETERS: ObjDesc - A field unit object
836 *
837 * RETURN: Status
838 *
839 * DESCRIPTION: Test read/write on a named field unit.
840 *
841 ******************************************************************************/
842
843 static ACPI_STATUS
AcpiDbTestFieldUnitType(ACPI_OPERAND_OBJECT * ObjDesc)844 AcpiDbTestFieldUnitType (
845 ACPI_OPERAND_OBJECT *ObjDesc)
846 {
847 ACPI_OPERAND_OBJECT *RegionObj;
848 UINT32 BitLength = 0;
849 UINT32 ByteLength = 0;
850 ACPI_STATUS Status = AE_OK;
851 ACPI_OPERAND_OBJECT *RetBufferDesc;
852
853
854 /* Supported spaces are memory/io/pci_config */
855
856 RegionObj = ObjDesc->Field.RegionObj;
857 switch (RegionObj->Region.SpaceId)
858 {
859 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
860 case ACPI_ADR_SPACE_SYSTEM_IO:
861 case ACPI_ADR_SPACE_PCI_CONFIG:
862
863 /* Need the interpreter to execute */
864
865 AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
866 AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
867
868 /* Exercise read-then-write */
869
870 Status = AcpiExReadDataFromField (NULL, ObjDesc, &RetBufferDesc);
871 if (Status == AE_OK)
872 {
873 AcpiExWriteDataToField (RetBufferDesc, ObjDesc, NULL);
874 AcpiUtRemoveReference (RetBufferDesc);
875 }
876
877 AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
878 AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
879
880 BitLength = ObjDesc->CommonField.BitLength;
881 ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
882
883 AcpiOsPrintf (ACPI_DEBUG_LENGTH_FORMAT " [%s]", BitLength,
884 ByteLength, AcpiUtGetRegionName (RegionObj->Region.SpaceId));
885 return (Status);
886
887 default:
888
889 AcpiOsPrintf (
890 " %s address space is not supported in this command [%4.4s]",
891 AcpiUtGetRegionName (RegionObj->Region.SpaceId),
892 RegionObj->Region.Node->Name.Ascii);
893 return (AE_OK);
894 }
895 }
896
897
898 /*******************************************************************************
899 *
900 * FUNCTION: AcpiDbReadFromObject
901 *
902 * PARAMETERS: Node - Parent NS node for the object
903 * ExpectedType - Object type expected from the read
904 * Value - Where the value read is returned
905 *
906 * RETURN: Status
907 *
908 * DESCRIPTION: Performs a read from the specified object by invoking the
909 * special debugger control method that reads the object. Thus,
910 * the AML interpreter is doing all of the work, increasing the
911 * validity of the test.
912 *
913 ******************************************************************************/
914
915 static ACPI_STATUS
AcpiDbReadFromObject(ACPI_NAMESPACE_NODE * Node,ACPI_OBJECT_TYPE ExpectedType,ACPI_OBJECT ** Value)916 AcpiDbReadFromObject (
917 ACPI_NAMESPACE_NODE *Node,
918 ACPI_OBJECT_TYPE ExpectedType,
919 ACPI_OBJECT **Value)
920 {
921 ACPI_OBJECT *RetValue;
922 ACPI_OBJECT_LIST ParamObjects;
923 ACPI_OBJECT Params[2];
924 ACPI_BUFFER ReturnObj;
925 ACPI_STATUS Status;
926
927
928 Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
929 Params[0].Reference.ActualType = Node->Type;
930 Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
931
932 ParamObjects.Count = 1;
933 ParamObjects.Pointer = Params;
934
935 ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
936
937 AcpiGbl_MethodExecuting = TRUE;
938 Status = AcpiEvaluateObject (ReadHandle, NULL,
939 &ParamObjects, &ReturnObj);
940
941 AcpiGbl_MethodExecuting = FALSE;
942 if (ACPI_FAILURE (Status))
943 {
944 AcpiOsPrintf ("Could not read from object, %s",
945 AcpiFormatException (Status));
946 return (Status);
947 }
948
949 RetValue = (ACPI_OBJECT *) ReturnObj.Pointer;
950
951 switch (RetValue->Type)
952 {
953 case ACPI_TYPE_INTEGER:
954 case ACPI_TYPE_BUFFER:
955 case ACPI_TYPE_STRING:
956 case ACPI_TYPE_PACKAGE:
957 /*
958 * Did we receive the type we wanted? Most important for the
959 * Integer/Buffer case (when a field is larger than an Integer,
960 * it should return a Buffer).
961 */
962 if (RetValue->Type != ExpectedType)
963 {
964 AcpiOsPrintf (" Type mismatch: Expected %s, Received %s",
965 AcpiUtGetTypeName (ExpectedType),
966 AcpiUtGetTypeName (RetValue->Type));
967
968 AcpiOsFree (ReturnObj.Pointer);
969 return (AE_TYPE);
970 }
971
972 *Value = RetValue;
973 break;
974
975 default:
976
977 AcpiOsPrintf (" Unsupported return object type, %s",
978 AcpiUtGetTypeName (RetValue->Type));
979
980 AcpiOsFree (ReturnObj.Pointer);
981 return (AE_TYPE);
982 }
983
984 return (Status);
985 }
986
987
988 /*******************************************************************************
989 *
990 * FUNCTION: AcpiDbWriteToObject
991 *
992 * PARAMETERS: Node - Parent NS node for the object
993 * Value - Value to be written
994 *
995 * RETURN: Status
996 *
997 * DESCRIPTION: Performs a write to the specified object by invoking the
998 * special debugger control method that writes the object. Thus,
999 * the AML interpreter is doing all of the work, increasing the
1000 * validity of the test.
1001 *
1002 ******************************************************************************/
1003
1004 static ACPI_STATUS
AcpiDbWriteToObject(ACPI_NAMESPACE_NODE * Node,ACPI_OBJECT * Value)1005 AcpiDbWriteToObject (
1006 ACPI_NAMESPACE_NODE *Node,
1007 ACPI_OBJECT *Value)
1008 {
1009 ACPI_OBJECT_LIST ParamObjects;
1010 ACPI_OBJECT Params[2];
1011 ACPI_STATUS Status;
1012
1013
1014 Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
1015 Params[0].Reference.ActualType = Node->Type;
1016 Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
1017
1018 /* Copy the incoming user parameter */
1019
1020 memcpy (&Params[1], Value, sizeof (ACPI_OBJECT));
1021
1022 ParamObjects.Count = 2;
1023 ParamObjects.Pointer = Params;
1024
1025 AcpiGbl_MethodExecuting = TRUE;
1026 Status = AcpiEvaluateObject (WriteHandle, NULL, &ParamObjects, NULL);
1027 AcpiGbl_MethodExecuting = FALSE;
1028
1029 if (ACPI_FAILURE (Status))
1030 {
1031 AcpiOsPrintf ("Could not write to object, %s",
1032 AcpiFormatException (Status));
1033 }
1034
1035 return (Status);
1036 }
1037
1038
1039 /*******************************************************************************
1040 *
1041 * FUNCTION: AcpiDbEvaluateAllPredefinedNames
1042 *
1043 * PARAMETERS: CountArg - Max number of methods to execute
1044 *
1045 * RETURN: None
1046 *
1047 * DESCRIPTION: Namespace batch execution. Execute predefined names in the
1048 * namespace, up to the max count, if specified.
1049 *
1050 ******************************************************************************/
1051
1052 static void
AcpiDbEvaluateAllPredefinedNames(char * CountArg)1053 AcpiDbEvaluateAllPredefinedNames (
1054 char *CountArg)
1055 {
1056 ACPI_DB_EXECUTE_WALK Info;
1057
1058
1059 Info.Count = 0;
1060 Info.MaxCount = ACPI_UINT32_MAX;
1061
1062 if (CountArg)
1063 {
1064 Info.MaxCount = strtoul (CountArg, NULL, 0);
1065 }
1066
1067 /* Search all nodes in namespace */
1068
1069 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1070 ACPI_UINT32_MAX, AcpiDbEvaluateOnePredefinedName, NULL,
1071 (void *) &Info, NULL);
1072
1073 AcpiOsPrintf (
1074 "Evaluated %u predefined names in the namespace\n", Info.Count);
1075 }
1076
1077
1078 /*******************************************************************************
1079 *
1080 * FUNCTION: AcpiDbEvaluateOnePredefinedName
1081 *
1082 * PARAMETERS: Callback from WalkNamespace
1083 *
1084 * RETURN: Status
1085 *
1086 * DESCRIPTION: Batch execution module. Currently only executes predefined
1087 * ACPI names.
1088 *
1089 ******************************************************************************/
1090
1091 static ACPI_STATUS
AcpiDbEvaluateOnePredefinedName(ACPI_HANDLE ObjHandle,UINT32 NestingLevel,void * Context,void ** ReturnValue)1092 AcpiDbEvaluateOnePredefinedName (
1093 ACPI_HANDLE ObjHandle,
1094 UINT32 NestingLevel,
1095 void *Context,
1096 void **ReturnValue)
1097 {
1098 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1099 ACPI_DB_EXECUTE_WALK *Info = (ACPI_DB_EXECUTE_WALK *) Context;
1100 char *Pathname;
1101 const ACPI_PREDEFINED_INFO *Predefined;
1102 ACPI_DEVICE_INFO *ObjInfo;
1103 ACPI_OBJECT_LIST ParamObjects;
1104 ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS];
1105 ACPI_OBJECT *ThisParam;
1106 ACPI_BUFFER ReturnObj;
1107 ACPI_STATUS Status;
1108 UINT16 ArgTypeList;
1109 UINT8 ArgCount;
1110 UINT8 ArgType;
1111 UINT32 i;
1112
1113
1114 /* The name must be a predefined ACPI name */
1115
1116 Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
1117 if (!Predefined)
1118 {
1119 return (AE_OK);
1120 }
1121
1122 if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
1123 {
1124 return (AE_OK);
1125 }
1126
1127 Pathname = AcpiNsGetNormalizedPathname (Node, TRUE);
1128 if (!Pathname)
1129 {
1130 return (AE_OK);
1131 }
1132
1133 /* Get the object info for number of method parameters */
1134
1135 Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
1136 if (ACPI_FAILURE (Status))
1137 {
1138 ACPI_FREE (Pathname);
1139 return (Status);
1140 }
1141
1142 ParamObjects.Count = 0;
1143 ParamObjects.Pointer = NULL;
1144
1145 if (ObjInfo->Type == ACPI_TYPE_METHOD)
1146 {
1147 /* Setup default parameters (with proper types) */
1148
1149 ArgTypeList = Predefined->Info.ArgumentList;
1150 ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
1151
1152 /*
1153 * Setup the ACPI-required number of arguments, regardless of what
1154 * the actual method defines. If there is a difference, then the
1155 * method is wrong and a warning will be issued during execution.
1156 */
1157 ThisParam = Params;
1158 for (i = 0; i < ArgCount; i++)
1159 {
1160 ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
1161 ThisParam->Type = ArgType;
1162
1163 switch (ArgType)
1164 {
1165 case ACPI_TYPE_INTEGER:
1166
1167 ThisParam->Integer.Value = 1;
1168 break;
1169
1170 case ACPI_TYPE_STRING:
1171
1172 ThisParam->String.Pointer =
1173 __UNCONST("This is the default argument string");
1174 ThisParam->String.Length =
1175 strlen (ThisParam->String.Pointer);
1176 break;
1177
1178 case ACPI_TYPE_BUFFER:
1179
1180 ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */
1181 ThisParam->Buffer.Length = 48;
1182 break;
1183
1184 case ACPI_TYPE_PACKAGE:
1185
1186 ThisParam->Package.Elements = NULL;
1187 ThisParam->Package.Count = 0;
1188 break;
1189
1190 default:
1191
1192 AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
1193 Pathname, ArgType);
1194 break;
1195 }
1196
1197 ThisParam++;
1198 }
1199
1200 ParamObjects.Count = ArgCount;
1201 ParamObjects.Pointer = Params;
1202 }
1203
1204 ACPI_FREE (ObjInfo);
1205 ReturnObj.Pointer = NULL;
1206 ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
1207
1208 /* Do the actual method execution */
1209
1210 AcpiGbl_MethodExecuting = TRUE;
1211
1212 Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
1213
1214 AcpiOsPrintf ("%-32s returned %s\n",
1215 Pathname, AcpiFormatException (Status));
1216 AcpiGbl_MethodExecuting = FALSE;
1217 ACPI_FREE (Pathname);
1218
1219 /* Ignore status from method execution */
1220
1221 Status = AE_OK;
1222
1223 /* Update count, check if we have executed enough methods */
1224
1225 Info->Count++;
1226 if (Info->Count >= Info->MaxCount)
1227 {
1228 Status = AE_CTRL_TERMINATE;
1229 }
1230
1231 return (Status);
1232 }
1233