1/*******************************************************************************
2 *
3 * Module Name: dbcmds - Miscellaneous debug commands and output routines
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, 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#include <contrib/dev/acpica/include/acpi.h>
46#include <contrib/dev/acpica/include/accommon.h>
47#include <contrib/dev/acpica/include/acevents.h>
48#include <contrib/dev/acpica/include/acdebug.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50#include <contrib/dev/acpica/include/acresrc.h>
51#include <contrib/dev/acpica/include/actables.h>
52
53#ifdef ACPI_DEBUGGER
54
55#define _COMPONENT ACPI_CA_DEBUGGER
56 ACPI_MODULE_NAME ("dbcmds")
57
58
59/* Local prototypes */
60
61static void
62AcpiDmCompareAmlResources (
63 UINT8 *Aml1Buffer,
64 ACPI_RSDESC_SIZE Aml1BufferLength,
65 UINT8 *Aml2Buffer,
66 ACPI_RSDESC_SIZE Aml2BufferLength);
67
68static ACPI_STATUS
69AcpiDmTestResourceConversion (
70 ACPI_NAMESPACE_NODE *Node,
71 char *Name);
72
73static ACPI_STATUS
74AcpiDbResourceCallback (
75 ACPI_RESOURCE *Resource,
76 void *Context);
77
78static ACPI_STATUS
79AcpiDbDeviceResources (
80 ACPI_HANDLE ObjHandle,
81 UINT32 NestingLevel,
82 void *Context,
83 void **ReturnValue);
84
85
86/*******************************************************************************
87 *
88 * FUNCTION: AcpiDbConvertToNode
89 *
90 * PARAMETERS: InString - String to convert
91 *
92 * RETURN: Pointer to a NS node
93 *
94 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
95 * alpha strings.
96 *
97 ******************************************************************************/
98
99ACPI_NAMESPACE_NODE *
100AcpiDbConvertToNode (
101 char *InString)
102{
103 ACPI_NAMESPACE_NODE *Node;
104
105
106 if ((*InString >= 0x30) && (*InString <= 0x39))
107 {
108 /* Numeric argument, convert */
109
110 Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
111 if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
112 {
113 AcpiOsPrintf ("Address %p is invalid in this address space\n",
114 Node);
115 return (NULL);
116 }
117
118 /* Make sure pointer is valid NS node */
119
120 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
121 {
122 AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
123 Node, AcpiUtGetDescriptorName (Node));
124 return (NULL);
125 }
126 }
127 else
128 {
129 /* Alpha argument */
130 /* The parameter is a name string that must be resolved to a
131 * Named obj
132 */
133 Node = AcpiDbLocalNsLookup (InString);
134 if (!Node)
135 {
136 Node = AcpiGbl_RootNode;
137 }
138 }
139
140 return (Node);
141}
142
143
144/*******************************************************************************
145 *
146 * FUNCTION: AcpiDbSleep
147 *
148 * PARAMETERS: ObjectArg - Desired sleep state (0-5)
149 *
150 * RETURN: Status
151 *
152 * DESCRIPTION: Simulate a sleep/wake sequence
153 *
154 ******************************************************************************/
155
156ACPI_STATUS
157AcpiDbSleep (
158 char *ObjectArg)
159{
160 ACPI_STATUS Status;
161 UINT8 SleepState;
162
163
164 ACPI_FUNCTION_TRACE (AcpiDbSleep);
165
166
167 SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
168
169 AcpiOsPrintf ("**** Prepare to sleep ****\n");
170 Status = AcpiEnterSleepStatePrep (SleepState);
171 if (ACPI_FAILURE (Status))
172 {
173 goto ErrorExit;
174 }
175
176 AcpiOsPrintf ("**** Going to sleep ****\n");
177 Status = AcpiEnterSleepState (SleepState);
178 if (ACPI_FAILURE (Status))
179 {
180 goto ErrorExit;
181 }
182
183 AcpiOsPrintf ("**** Prepare to return from sleep ****\n");
184 Status = AcpiLeaveSleepStatePrep (SleepState);
185 if (ACPI_FAILURE (Status))
186 {
187 goto ErrorExit;
188 }
189
190 AcpiOsPrintf ("**** Returning from sleep ****\n");
191 Status = AcpiLeaveSleepState (SleepState);
192 if (ACPI_FAILURE (Status))
193 {
194 goto ErrorExit;
195 }
196
197 return (Status);
198
199
200ErrorExit:
201
202 ACPI_EXCEPTION ((AE_INFO, Status, "During sleep test"));
203 return (Status);
204}
205
206
207/*******************************************************************************
208 *
209 * FUNCTION: AcpiDbDisplayLocks
210 *
211 * PARAMETERS: None
212 *
213 * RETURN: None
214 *
215 * DESCRIPTION: Display information about internal mutexes.
216 *
217 ******************************************************************************/
218
219void
220AcpiDbDisplayLocks (
221 void)
222{
223 UINT32 i;
224
225
226 for (i = 0; i < ACPI_MAX_MUTEX; i++)
227 {
228 AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
229 AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
230 ? "Locked" : "Unlocked");
231 }
232}
233
234
235/*******************************************************************************
236 *
237 * FUNCTION: AcpiDbDisplayTableInfo
238 *
239 * PARAMETERS: TableArg - String with name of table to be displayed
240 *
241 * RETURN: None
242 *
243 * DESCRIPTION: Display information about loaded tables. Current
244 * implementation displays all loaded tables.
245 *
246 ******************************************************************************/
247
248void
249AcpiDbDisplayTableInfo (
250 char *TableArg)
251{
252 UINT32 i;
253 ACPI_TABLE_DESC *TableDesc;
254 ACPI_STATUS Status;
255
256
257 /* Header */
258
259 AcpiOsPrintf ("Idx ID Status Type Sig Address Len Header\n");
260
261 /* Walk the entire root table list */
262
263 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
264 {
265 TableDesc = &AcpiGbl_RootTableList.Tables[i];
266
267 /* Index and Table ID */
268
269 AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId);
270
271 /* Decode the table flags */
272
273 if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED))
274 {
275 AcpiOsPrintf ("NotLoaded ");
276 }
277 else
278 {
279 AcpiOsPrintf (" Loaded ");
280 }
281
282 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
283 {
284 case ACPI_TABLE_ORIGIN_UNKNOWN:
285 AcpiOsPrintf ("Unknown ");
286 break;
287
288 case ACPI_TABLE_ORIGIN_MAPPED:
289 AcpiOsPrintf ("Mapped ");
290 break;
291
292 case ACPI_TABLE_ORIGIN_ALLOCATED:
293 AcpiOsPrintf ("Allocated ");
294 break;
295
296 case ACPI_TABLE_ORIGIN_OVERRIDE:
297 AcpiOsPrintf ("Override ");
298 break;
299
300 default:
301 AcpiOsPrintf ("INVALID ");
302 break;
303 }
304
305 /* Make sure that the table is mapped */
306
307 Status = AcpiTbVerifyTable (TableDesc);
308 if (ACPI_FAILURE (Status))
309 {
310 return;
311 }
312
313 /* Dump the table header */
314
315 if (TableDesc->Pointer)
316 {
317 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
318 }
319 else
320 {
321 /* If the pointer is null, the table has been unloaded */
322
323 ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
324 TableDesc->Signature.Ascii));
325 }
326 }
327}
328
329
330/*******************************************************************************
331 *
332 * FUNCTION: AcpiDbUnloadAcpiTable
333 *
334 * PARAMETERS: ObjectName - Namespace pathname for an object that
335 * is owned by the table to be unloaded
336 *
337 * RETURN: None
338 *
339 * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
340 * by the table.
341 *
342 ******************************************************************************/
343
344void
345AcpiDbUnloadAcpiTable (
346 char *ObjectName)
347{
348 ACPI_NAMESPACE_NODE *Node;
349 ACPI_STATUS Status;
350
351
352 /* Translate name to an Named object */
353
354 Node = AcpiDbConvertToNode (ObjectName);
355 if (!Node)
356 {
357 AcpiOsPrintf ("Could not find [%s] in namespace\n",
358 ObjectName);
359 return;
360 }
361
362 Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node));
363 if (ACPI_SUCCESS (Status))
364 {
365 AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n",
366 ObjectName, Node);
367 }
368 else
369 {
370 AcpiOsPrintf ("%s, while unloading parent table of [%s]\n",
371 AcpiFormatException (Status), ObjectName);
372 }
373}
374
375
376/*******************************************************************************
377 *
378 * FUNCTION: AcpiDbSendNotify
379 *
380 * PARAMETERS: Name - Name of ACPI object to send the notify to
381 * Value - Value of the notify to send.
382 *
383 * RETURN: None
384 *
385 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
386 * named object as an ACPI notify.
387 *
388 ******************************************************************************/
389
390void
391AcpiDbSendNotify (
392 char *Name,
393 UINT32 Value)
394{
395 ACPI_NAMESPACE_NODE *Node;
396 ACPI_STATUS Status;
397
398
399 /* Translate name to an Named object */
400
401 Node = AcpiDbConvertToNode (Name);
402 if (!Node)
403 {
404 return;
405 }
406
407 /* Dispatch the notify if legal */
408
409 if (AcpiEvIsNotifyObject (Node))
410 {
411 Status = AcpiEvQueueNotifyRequest (Node, Value);
412 if (ACPI_FAILURE (Status))
413 {
414 AcpiOsPrintf ("Could not queue notify\n");
415 }
416 }
417 else
418 {
419 AcpiOsPrintf ("Named object [%4.4s] Type %s, must be Device/Thermal/Processor type\n",
420 AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type));
421 }
422}
423
424
425/*******************************************************************************
426 *
427 * FUNCTION: AcpiDbDisplayInterfaces
428 *
429 * PARAMETERS: ActionArg - Null, "install", or "remove"
430 * InterfaceNameArg - Name for install/remove options
431 *
432 * RETURN: None
433 *
434 * DESCRIPTION: Display or modify the global _OSI interface list
435 *
436 ******************************************************************************/
437
438void
439AcpiDbDisplayInterfaces (
440 char *ActionArg,
441 char *InterfaceNameArg)
442{
443 ACPI_INTERFACE_INFO *NextInterface;
444 char *SubString;
445 ACPI_STATUS Status;
446
447
448 /* If no arguments, just display current interface list */
449
450 if (!ActionArg)
451 {
452 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex,
453 ACPI_WAIT_FOREVER);
454
455 NextInterface = AcpiGbl_SupportedInterfaces;
456
457 while (NextInterface)
458 {
459 if (!(NextInterface->Flags & ACPI_OSI_INVALID))
460 {
461 AcpiOsPrintf ("%s\n", NextInterface->Name);
462 }
463 NextInterface = NextInterface->Next;
464 }
465
466 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
467 return;
468 }
469
470 /* If ActionArg exists, so must InterfaceNameArg */
471
472 if (!InterfaceNameArg)
473 {
474 AcpiOsPrintf ("Missing Interface Name argument\n");
475 return;
476 }
477
478 /* Uppercase the action for match below */
479
480 AcpiUtStrupr (ActionArg);
481
482 /* Install - install an interface */
483
484 SubString = ACPI_STRSTR ("INSTALL", ActionArg);
485 if (SubString)
486 {
487 Status = AcpiInstallInterface (InterfaceNameArg);
488 if (ACPI_FAILURE (Status))
489 {
490 AcpiOsPrintf ("%s, while installing \"%s\"\n",
491 AcpiFormatException (Status), InterfaceNameArg);
492 }
493 return;
494 }
495
496 /* Remove - remove an interface */
497
498 SubString = ACPI_STRSTR ("REMOVE", ActionArg);
499 if (SubString)
500 {
501 Status = AcpiRemoveInterface (InterfaceNameArg);
502 if (ACPI_FAILURE (Status))
503 {
504 AcpiOsPrintf ("%s, while removing \"%s\"\n",
505 AcpiFormatException (Status), InterfaceNameArg);
506 }
507 return;
508 }
509
510 /* Invalid ActionArg */
511
512 AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg);
513 return;
514}
515
516
517/*******************************************************************************
518 *
519 * FUNCTION: AcpiDbDisplayTemplate
520 *
521 * PARAMETERS: BufferArg - Buffer name or addrss
522 *
523 * RETURN: None
524 *
525 * DESCRIPTION: Dump a buffer that contains a resource template
526 *
527 ******************************************************************************/
528
529void
530AcpiDbDisplayTemplate (
531 char *BufferArg)
532{
533 ACPI_NAMESPACE_NODE *Node;
534 ACPI_STATUS Status;
535 ACPI_BUFFER ReturnObj;
536
537
538 /* Translate BufferArg to an Named object */
539
540 Node = AcpiDbConvertToNode (BufferArg);
541 if (!Node || (Node == AcpiGbl_RootNode))
542 {
543 AcpiOsPrintf ("Invalid argument: %s\n", BufferArg);
544 return;
545 }
546
547 /* We must have a buffer object */
548
549 if (Node->Type != ACPI_TYPE_BUFFER)
550 {
551 AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n",
552 BufferArg);
553 return;
554 }
555
556 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
557 ReturnObj.Pointer = AcpiGbl_DbBuffer;
558
559 /* Attempt to convert the raw buffer to a resource list */
560
561 Status = AcpiRsCreateResourceList (Node->Object, &ReturnObj);
562
563 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
564 AcpiDbgLevel |= ACPI_LV_RESOURCES;
565
566 if (ACPI_FAILURE (Status))
567 {
568 AcpiOsPrintf ("Could not convert Buffer to a resource list: %s, %s\n",
569 BufferArg, AcpiFormatException (Status));
570 goto DumpBuffer;
571 }
572
573 /* Now we can dump the resource list */
574
575 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
576 ReturnObj.Pointer));
577
578DumpBuffer:
579 AcpiOsPrintf ("\nRaw data buffer:\n");
580 AcpiUtDumpBuffer ((UINT8 *) Node->Object->Buffer.Pointer,
581 Node->Object->Buffer.Length,
582 DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
583
584 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
585 return;
586}
587
588
589/*******************************************************************************
590 *
591 * FUNCTION: AcpiDmCompareAmlResources
592 *
593 * PARAMETERS: Aml1Buffer - Contains first resource list
594 * Aml1BufferLength - Length of first resource list
595 * Aml2Buffer - Contains second resource list
596 * Aml2BufferLength - Length of second resource list
597 *
598 * RETURN: None
599 *
600 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
601 * order to isolate a miscompare to an individual resource)
602 *
603 ******************************************************************************/
604
605static void
606AcpiDmCompareAmlResources (
607 UINT8 *Aml1Buffer,
608 ACPI_RSDESC_SIZE Aml1BufferLength,
609 UINT8 *Aml2Buffer,
610 ACPI_RSDESC_SIZE Aml2BufferLength)
611{
612 UINT8 *Aml1;
613 UINT8 *Aml2;
614 UINT8 *Aml1End;
615 UINT8 *Aml2End;
616 ACPI_RSDESC_SIZE Aml1Length;
617 ACPI_RSDESC_SIZE Aml2Length;
618 ACPI_RSDESC_SIZE Offset = 0;
619 UINT8 ResourceType;
620 UINT32 Count = 0;
621 UINT32 i;
622
623
624 /* Compare overall buffer sizes (may be different due to size rounding) */
625
626 if (Aml1BufferLength != Aml2BufferLength)
627 {
628 AcpiOsPrintf (
629 "**** Buffer length mismatch in converted AML: Original %X, New %X ****\n",
630 Aml1BufferLength, Aml2BufferLength);
631 }
632
633 Aml1 = Aml1Buffer;
634 Aml2 = Aml2Buffer;
635 Aml1End = Aml1Buffer + Aml1BufferLength;
636 Aml2End = Aml2Buffer + Aml2BufferLength;
637
638 /* Walk the descriptor lists, comparing each descriptor */
639
640 while ((Aml1 < Aml1End) && (Aml2 < Aml2End))
641 {
642 /* Get the lengths of each descriptor */
643
644 Aml1Length = AcpiUtGetDescriptorLength (Aml1);
645 Aml2Length = AcpiUtGetDescriptorLength (Aml2);
646 ResourceType = AcpiUtGetResourceType (Aml1);
647
648 /* Check for descriptor length match */
649
650 if (Aml1Length != Aml2Length)
651 {
652 AcpiOsPrintf (
653 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X Len1 %X, Len2 %X ****\n",
654 Count, ResourceType, Offset, Aml1Length, Aml2Length);
655 }
656
657 /* Check for descriptor byte match */
658
659 else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
660 {
661 AcpiOsPrintf (
662 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
663 Count, ResourceType, Offset);
664
665 for (i = 0; i < Aml1Length; i++)
666 {
667 if (Aml1[i] != Aml2[i])
668 {
669 AcpiOsPrintf ("Mismatch at byte offset %.2X: is %2.2X, should be %2.2X\n",
670 i, Aml2[i], Aml1[i]);
671 }
672 }
673 }
674
675 /* Exit on EndTag descriptor */
676
677 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
678 {
679 return;
680 }
681
682 /* Point to next descriptor in each buffer */
683
684 Count++;
685 Offset += Aml1Length;
686 Aml1 += Aml1Length;
687 Aml2 += Aml2Length;
688 }
689}
690
691
692/*******************************************************************************
693 *
694 * FUNCTION: AcpiDmTestResourceConversion
695 *
696 * PARAMETERS: Node - Parent device node
697 * Name - resource method name (_CRS)
698 *
699 * RETURN: Status
700 *
701 * DESCRIPTION: Compare the original AML with a conversion of the AML to
702 * internal resource list, then back to AML.
703 *
704 ******************************************************************************/
705
706static ACPI_STATUS
707AcpiDmTestResourceConversion (
708 ACPI_NAMESPACE_NODE *Node,
709 char *Name)
710{
711 ACPI_STATUS Status;
712 ACPI_BUFFER ReturnObj;
713 ACPI_BUFFER ResourceObj;
714 ACPI_BUFFER NewAml;
715 ACPI_OBJECT *OriginalAml;
716
717
718 AcpiOsPrintf ("Resource Conversion Comparison:\n");
719
720 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
721 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
722 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
723
724 /* Get the original _CRS AML resource template */
725
726 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
727 if (ACPI_FAILURE (Status))
728 {
729 AcpiOsPrintf ("Could not obtain %s: %s\n",
730 Name, AcpiFormatException (Status));
731 return (Status);
732 }
733
734 /* Get the AML resource template, converted to internal resource structs */
735
736 Status = AcpiGetCurrentResources (Node, &ResourceObj);
737 if (ACPI_FAILURE (Status))
738 {
739 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
740 AcpiFormatException (Status));
741 goto Exit1;
742 }
743
744 /* Convert internal resource list to external AML resource template */
745
746 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
747 if (ACPI_FAILURE (Status))
748 {
749 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
750 AcpiFormatException (Status));
751 goto Exit2;
752 }
753
754 /* Compare original AML to the newly created AML resource list */
755
756 OriginalAml = ReturnObj.Pointer;
757
758 AcpiDmCompareAmlResources (
759 OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
760 NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
761
762 /* Cleanup and exit */
763
764 ACPI_FREE (NewAml.Pointer);
765Exit2:
766 ACPI_FREE (ResourceObj.Pointer);
767Exit1:
768 ACPI_FREE (ReturnObj.Pointer);
769 return (Status);
770}
771
772
773/*******************************************************************************
774 *
775 * FUNCTION: AcpiDbResourceCallback
776 *
777 * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK
778 *
779 * RETURN: Status
780 *
781 * DESCRIPTION: Simple callback to exercise AcpiWalkResources
782 *
783 ******************************************************************************/
784
785static ACPI_STATUS
786AcpiDbResourceCallback (
787 ACPI_RESOURCE *Resource,
788 void *Context)
789{
790
791 return (AE_OK);
792}
793
794
795/*******************************************************************************
796 *
797 * FUNCTION: AcpiDbDeviceResources
798 *
799 * PARAMETERS: ACPI_WALK_CALLBACK
800 *
801 * RETURN: Status
802 *
803 * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
804 *
805 ******************************************************************************/
806
807static ACPI_STATUS
808AcpiDbDeviceResources (
809 ACPI_HANDLE ObjHandle,
810 UINT32 NestingLevel,
811 void *Context,
812 void **ReturnValue)
813{
814 ACPI_NAMESPACE_NODE *Node;
815 ACPI_NAMESPACE_NODE *PrtNode = NULL;
816 ACPI_NAMESPACE_NODE *CrsNode = NULL;
817 ACPI_NAMESPACE_NODE *PrsNode = NULL;
818 ACPI_NAMESPACE_NODE *AeiNode = NULL;
819 char *ParentPath;
820 ACPI_BUFFER ReturnObj;
821 ACPI_STATUS Status;
822
823
824 Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
825 ParentPath = AcpiNsGetExternalPathname (Node);
826 if (!ParentPath)
827 {
828 return (AE_NO_MEMORY);
829 }
830
831 /* Get handles to the resource methods for this device */
832
833 (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode));
834 (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode));
835 (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode));
836 (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode));
837 if (!PrtNode && !CrsNode && !PrsNode && !AeiNode)
838 {
839 goto Cleanup; /* Nothing to do */
840 }
841
842 AcpiOsPrintf ("\nDevice: %s\n", ParentPath);
843
844 /* Prepare for a return object of arbitrary size */
845
846 ReturnObj.Pointer = AcpiGbl_DbBuffer;
847 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
848
849
850 /* _PRT */
851
852 if (PrtNode)
853 {
854 AcpiOsPrintf ("Evaluating _PRT\n");
855
856 Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnObj);
857 if (ACPI_FAILURE (Status))
858 {
859 AcpiOsPrintf ("Could not evaluate _PRT: %s\n",
860 AcpiFormatException (Status));
861 goto GetCrs;
862 }
863
864 ReturnObj.Pointer = AcpiGbl_DbBuffer;
865 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
866
867 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
868 if (ACPI_FAILURE (Status))
869 {
870 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
871 AcpiFormatException (Status));
872 goto GetCrs;
873 }
874
875 AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
876 }
877
878
879 /* _CRS */
880
881GetCrs:
882 if (CrsNode)
883 {
884 AcpiOsPrintf ("Evaluating _CRS\n");
885
886 ReturnObj.Pointer = AcpiGbl_DbBuffer;
887 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
888
889 Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnObj);
890 if (ACPI_FAILURE (Status))
891 {
892 AcpiOsPrintf ("Could not evaluate _CRS: %s\n",
893 AcpiFormatException (Status));
894 goto GetPrs;
895 }
896
897 /* This code is here to exercise the AcpiWalkResources interface */
898
899 Status = AcpiWalkResources (Node, METHOD_NAME__CRS,
900 AcpiDbResourceCallback, NULL);
901 if (ACPI_FAILURE (Status))
902 {
903 AcpiOsPrintf ("AcpiWalkResources failed: %s\n",
904 AcpiFormatException (Status));
905 goto GetPrs;
906 }
907
908 /* Get the _CRS resource list */
909
910 ReturnObj.Pointer = AcpiGbl_DbBuffer;
911 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
912
913 Status = AcpiGetCurrentResources (Node, &ReturnObj);
914 if (ACPI_FAILURE (Status))
915 {
916 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
917 AcpiFormatException (Status));
918 goto GetPrs;
919 }
920
921 /* Dump the _CRS resource list */
922
923 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
924 ReturnObj.Pointer));
925
926 /*
927 * Perform comparison of original AML to newly created AML. This tests both
928 * the AML->Resource conversion and the Resource->Aml conversion.
929 */
930 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
931
932 /* Execute _SRS with the resource list */
933
934 Status = AcpiSetCurrentResources (Node, &ReturnObj);
935 if (ACPI_FAILURE (Status))
936 {
937 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
938 AcpiFormatException (Status));
939 goto GetPrs;
940 }
941 }
942
943
944 /* _PRS */
945
946GetPrs:
947 if (PrsNode)
948 {
949 AcpiOsPrintf ("Evaluating _PRS\n");
950
951 ReturnObj.Pointer = AcpiGbl_DbBuffer;
952 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
953
954 Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnObj);
955 if (ACPI_FAILURE (Status))
956 {
957 AcpiOsPrintf ("Could not evaluate _PRS: %s\n",
958 AcpiFormatException (Status));
959 goto GetAei;
960 }
961
962 ReturnObj.Pointer = AcpiGbl_DbBuffer;
963 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
964
965 Status = AcpiGetPossibleResources (Node, &ReturnObj);
966 if (ACPI_FAILURE (Status))
967 {
968 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
969 AcpiFormatException (Status));
970 goto GetAei;
971 }
972
973 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
974 }
975
976
977 /* _AEI */
978
979GetAei:
980 if (AeiNode)
981 {
982 AcpiOsPrintf ("Evaluating _AEI\n");
983
984 ReturnObj.Pointer = AcpiGbl_DbBuffer;
985 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
986
987 Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnObj);
988 if (ACPI_FAILURE (Status))
989 {
990 AcpiOsPrintf ("Could not evaluate _AEI: %s\n",
991 AcpiFormatException (Status));
992 goto Cleanup;
993 }
994
995 ReturnObj.Pointer = AcpiGbl_DbBuffer;
996 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
997
998 Status = AcpiGetEventResources (Node, &ReturnObj);
999 if (ACPI_FAILURE (Status))
1000 {
1001 AcpiOsPrintf ("AcpiGetEventResources failed: %s\n",
1002 AcpiFormatException (Status));
1003 goto Cleanup;
1004 }
1005
1006 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1007 }
1008
1009
1010Cleanup:
1011 ACPI_FREE (ParentPath);
1012 return (AE_OK);
1013}
1014
1015
1016/*******************************************************************************
1017 *
1018 * FUNCTION: AcpiDbDisplayResources
1019 *
1020 * PARAMETERS: ObjectArg - String object name or object pointer.
1021 * "*" means "display resources for all devices"
1022 *
1023 * RETURN: None
1024 *
1025 * DESCRIPTION: Display the resource objects associated with a device.
1026 *
1027 ******************************************************************************/
1028
1029void
1030AcpiDbDisplayResources (
1031 char *ObjectArg)
1032{
1033 ACPI_NAMESPACE_NODE *Node;
1034
1035
1036 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1037 AcpiDbgLevel |= ACPI_LV_RESOURCES;
1038
1039 /* Asterisk means "display resources for all devices" */
1040
1041 if (!ACPI_STRCMP (ObjectArg, "*"))
1042 {
1043 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1044 ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL);
1045 }
1046 else
1047 {
1048 /* Convert string to object pointer */
1049
1050 Node = AcpiDbConvertToNode (ObjectArg);
1051 if (Node)
1052 {
1053 if (Node->Type != ACPI_TYPE_DEVICE)
1054 {
1055 AcpiOsPrintf ("%4.4s: Name is not a device object (%s)\n",
1056 Node->Name.Ascii, AcpiUtGetTypeName (Node->Type));
1057 }
1058 else
1059 {
1060 (void) AcpiDbDeviceResources (Node, 0, NULL, NULL);
1061 }
1062 }
1063 }
1064
1065 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1066}
1067
1068
1069#if (!ACPI_REDUCED_HARDWARE)
1070/*******************************************************************************
1071 *
1072 * FUNCTION: AcpiDbGenerateGpe
1073 *
1074 * PARAMETERS: GpeArg - Raw GPE number, ascii string
1075 * BlockArg - GPE block number, ascii string
1076 * 0 or 1 for FADT GPE blocks
1077 *
1078 * RETURN: None
1079 *
1080 * DESCRIPTION: Generate a GPE
1081 *
1082 ******************************************************************************/
1083
1084void
1085AcpiDbGenerateGpe (
1086 char *GpeArg,
1087 char *BlockArg)
1088{
1089 UINT32 BlockNumber;
1090 UINT32 GpeNumber;
1091 ACPI_GPE_EVENT_INFO *GpeEventInfo;
1092
1093
1094 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0);
1095 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1096
1097
1098 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1099 GpeNumber);
1100 if (!GpeEventInfo)
1101 {
1102 AcpiOsPrintf ("Invalid GPE\n");
1103 return;
1104 }
1105
1106 (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
1107}
1108#endif /* !ACPI_REDUCED_HARDWARE */
1109
1110#endif /* ACPI_DEBUGGER */
2 *
3 * Module Name: dbcmds - Miscellaneous debug commands and output routines
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, 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#include <contrib/dev/acpica/include/acpi.h>
46#include <contrib/dev/acpica/include/accommon.h>
47#include <contrib/dev/acpica/include/acevents.h>
48#include <contrib/dev/acpica/include/acdebug.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50#include <contrib/dev/acpica/include/acresrc.h>
51#include <contrib/dev/acpica/include/actables.h>
52
53#ifdef ACPI_DEBUGGER
54
55#define _COMPONENT ACPI_CA_DEBUGGER
56 ACPI_MODULE_NAME ("dbcmds")
57
58
59/* Local prototypes */
60
61static void
62AcpiDmCompareAmlResources (
63 UINT8 *Aml1Buffer,
64 ACPI_RSDESC_SIZE Aml1BufferLength,
65 UINT8 *Aml2Buffer,
66 ACPI_RSDESC_SIZE Aml2BufferLength);
67
68static ACPI_STATUS
69AcpiDmTestResourceConversion (
70 ACPI_NAMESPACE_NODE *Node,
71 char *Name);
72
73static ACPI_STATUS
74AcpiDbResourceCallback (
75 ACPI_RESOURCE *Resource,
76 void *Context);
77
78static ACPI_STATUS
79AcpiDbDeviceResources (
80 ACPI_HANDLE ObjHandle,
81 UINT32 NestingLevel,
82 void *Context,
83 void **ReturnValue);
84
85
86/*******************************************************************************
87 *
88 * FUNCTION: AcpiDbConvertToNode
89 *
90 * PARAMETERS: InString - String to convert
91 *
92 * RETURN: Pointer to a NS node
93 *
94 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
95 * alpha strings.
96 *
97 ******************************************************************************/
98
99ACPI_NAMESPACE_NODE *
100AcpiDbConvertToNode (
101 char *InString)
102{
103 ACPI_NAMESPACE_NODE *Node;
104
105
106 if ((*InString >= 0x30) && (*InString <= 0x39))
107 {
108 /* Numeric argument, convert */
109
110 Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
111 if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
112 {
113 AcpiOsPrintf ("Address %p is invalid in this address space\n",
114 Node);
115 return (NULL);
116 }
117
118 /* Make sure pointer is valid NS node */
119
120 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
121 {
122 AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
123 Node, AcpiUtGetDescriptorName (Node));
124 return (NULL);
125 }
126 }
127 else
128 {
129 /* Alpha argument */
130 /* The parameter is a name string that must be resolved to a
131 * Named obj
132 */
133 Node = AcpiDbLocalNsLookup (InString);
134 if (!Node)
135 {
136 Node = AcpiGbl_RootNode;
137 }
138 }
139
140 return (Node);
141}
142
143
144/*******************************************************************************
145 *
146 * FUNCTION: AcpiDbSleep
147 *
148 * PARAMETERS: ObjectArg - Desired sleep state (0-5)
149 *
150 * RETURN: Status
151 *
152 * DESCRIPTION: Simulate a sleep/wake sequence
153 *
154 ******************************************************************************/
155
156ACPI_STATUS
157AcpiDbSleep (
158 char *ObjectArg)
159{
160 ACPI_STATUS Status;
161 UINT8 SleepState;
162
163
164 ACPI_FUNCTION_TRACE (AcpiDbSleep);
165
166
167 SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
168
169 AcpiOsPrintf ("**** Prepare to sleep ****\n");
170 Status = AcpiEnterSleepStatePrep (SleepState);
171 if (ACPI_FAILURE (Status))
172 {
173 goto ErrorExit;
174 }
175
176 AcpiOsPrintf ("**** Going to sleep ****\n");
177 Status = AcpiEnterSleepState (SleepState);
178 if (ACPI_FAILURE (Status))
179 {
180 goto ErrorExit;
181 }
182
183 AcpiOsPrintf ("**** Prepare to return from sleep ****\n");
184 Status = AcpiLeaveSleepStatePrep (SleepState);
185 if (ACPI_FAILURE (Status))
186 {
187 goto ErrorExit;
188 }
189
190 AcpiOsPrintf ("**** Returning from sleep ****\n");
191 Status = AcpiLeaveSleepState (SleepState);
192 if (ACPI_FAILURE (Status))
193 {
194 goto ErrorExit;
195 }
196
197 return (Status);
198
199
200ErrorExit:
201
202 ACPI_EXCEPTION ((AE_INFO, Status, "During sleep test"));
203 return (Status);
204}
205
206
207/*******************************************************************************
208 *
209 * FUNCTION: AcpiDbDisplayLocks
210 *
211 * PARAMETERS: None
212 *
213 * RETURN: None
214 *
215 * DESCRIPTION: Display information about internal mutexes.
216 *
217 ******************************************************************************/
218
219void
220AcpiDbDisplayLocks (
221 void)
222{
223 UINT32 i;
224
225
226 for (i = 0; i < ACPI_MAX_MUTEX; i++)
227 {
228 AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
229 AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
230 ? "Locked" : "Unlocked");
231 }
232}
233
234
235/*******************************************************************************
236 *
237 * FUNCTION: AcpiDbDisplayTableInfo
238 *
239 * PARAMETERS: TableArg - String with name of table to be displayed
240 *
241 * RETURN: None
242 *
243 * DESCRIPTION: Display information about loaded tables. Current
244 * implementation displays all loaded tables.
245 *
246 ******************************************************************************/
247
248void
249AcpiDbDisplayTableInfo (
250 char *TableArg)
251{
252 UINT32 i;
253 ACPI_TABLE_DESC *TableDesc;
254 ACPI_STATUS Status;
255
256
257 /* Header */
258
259 AcpiOsPrintf ("Idx ID Status Type Sig Address Len Header\n");
260
261 /* Walk the entire root table list */
262
263 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
264 {
265 TableDesc = &AcpiGbl_RootTableList.Tables[i];
266
267 /* Index and Table ID */
268
269 AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId);
270
271 /* Decode the table flags */
272
273 if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED))
274 {
275 AcpiOsPrintf ("NotLoaded ");
276 }
277 else
278 {
279 AcpiOsPrintf (" Loaded ");
280 }
281
282 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
283 {
284 case ACPI_TABLE_ORIGIN_UNKNOWN:
285 AcpiOsPrintf ("Unknown ");
286 break;
287
288 case ACPI_TABLE_ORIGIN_MAPPED:
289 AcpiOsPrintf ("Mapped ");
290 break;
291
292 case ACPI_TABLE_ORIGIN_ALLOCATED:
293 AcpiOsPrintf ("Allocated ");
294 break;
295
296 case ACPI_TABLE_ORIGIN_OVERRIDE:
297 AcpiOsPrintf ("Override ");
298 break;
299
300 default:
301 AcpiOsPrintf ("INVALID ");
302 break;
303 }
304
305 /* Make sure that the table is mapped */
306
307 Status = AcpiTbVerifyTable (TableDesc);
308 if (ACPI_FAILURE (Status))
309 {
310 return;
311 }
312
313 /* Dump the table header */
314
315 if (TableDesc->Pointer)
316 {
317 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
318 }
319 else
320 {
321 /* If the pointer is null, the table has been unloaded */
322
323 ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
324 TableDesc->Signature.Ascii));
325 }
326 }
327}
328
329
330/*******************************************************************************
331 *
332 * FUNCTION: AcpiDbUnloadAcpiTable
333 *
334 * PARAMETERS: ObjectName - Namespace pathname for an object that
335 * is owned by the table to be unloaded
336 *
337 * RETURN: None
338 *
339 * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
340 * by the table.
341 *
342 ******************************************************************************/
343
344void
345AcpiDbUnloadAcpiTable (
346 char *ObjectName)
347{
348 ACPI_NAMESPACE_NODE *Node;
349 ACPI_STATUS Status;
350
351
352 /* Translate name to an Named object */
353
354 Node = AcpiDbConvertToNode (ObjectName);
355 if (!Node)
356 {
357 AcpiOsPrintf ("Could not find [%s] in namespace\n",
358 ObjectName);
359 return;
360 }
361
362 Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node));
363 if (ACPI_SUCCESS (Status))
364 {
365 AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n",
366 ObjectName, Node);
367 }
368 else
369 {
370 AcpiOsPrintf ("%s, while unloading parent table of [%s]\n",
371 AcpiFormatException (Status), ObjectName);
372 }
373}
374
375
376/*******************************************************************************
377 *
378 * FUNCTION: AcpiDbSendNotify
379 *
380 * PARAMETERS: Name - Name of ACPI object to send the notify to
381 * Value - Value of the notify to send.
382 *
383 * RETURN: None
384 *
385 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
386 * named object as an ACPI notify.
387 *
388 ******************************************************************************/
389
390void
391AcpiDbSendNotify (
392 char *Name,
393 UINT32 Value)
394{
395 ACPI_NAMESPACE_NODE *Node;
396 ACPI_STATUS Status;
397
398
399 /* Translate name to an Named object */
400
401 Node = AcpiDbConvertToNode (Name);
402 if (!Node)
403 {
404 return;
405 }
406
407 /* Dispatch the notify if legal */
408
409 if (AcpiEvIsNotifyObject (Node))
410 {
411 Status = AcpiEvQueueNotifyRequest (Node, Value);
412 if (ACPI_FAILURE (Status))
413 {
414 AcpiOsPrintf ("Could not queue notify\n");
415 }
416 }
417 else
418 {
419 AcpiOsPrintf ("Named object [%4.4s] Type %s, must be Device/Thermal/Processor type\n",
420 AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type));
421 }
422}
423
424
425/*******************************************************************************
426 *
427 * FUNCTION: AcpiDbDisplayInterfaces
428 *
429 * PARAMETERS: ActionArg - Null, "install", or "remove"
430 * InterfaceNameArg - Name for install/remove options
431 *
432 * RETURN: None
433 *
434 * DESCRIPTION: Display or modify the global _OSI interface list
435 *
436 ******************************************************************************/
437
438void
439AcpiDbDisplayInterfaces (
440 char *ActionArg,
441 char *InterfaceNameArg)
442{
443 ACPI_INTERFACE_INFO *NextInterface;
444 char *SubString;
445 ACPI_STATUS Status;
446
447
448 /* If no arguments, just display current interface list */
449
450 if (!ActionArg)
451 {
452 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex,
453 ACPI_WAIT_FOREVER);
454
455 NextInterface = AcpiGbl_SupportedInterfaces;
456
457 while (NextInterface)
458 {
459 if (!(NextInterface->Flags & ACPI_OSI_INVALID))
460 {
461 AcpiOsPrintf ("%s\n", NextInterface->Name);
462 }
463 NextInterface = NextInterface->Next;
464 }
465
466 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
467 return;
468 }
469
470 /* If ActionArg exists, so must InterfaceNameArg */
471
472 if (!InterfaceNameArg)
473 {
474 AcpiOsPrintf ("Missing Interface Name argument\n");
475 return;
476 }
477
478 /* Uppercase the action for match below */
479
480 AcpiUtStrupr (ActionArg);
481
482 /* Install - install an interface */
483
484 SubString = ACPI_STRSTR ("INSTALL", ActionArg);
485 if (SubString)
486 {
487 Status = AcpiInstallInterface (InterfaceNameArg);
488 if (ACPI_FAILURE (Status))
489 {
490 AcpiOsPrintf ("%s, while installing \"%s\"\n",
491 AcpiFormatException (Status), InterfaceNameArg);
492 }
493 return;
494 }
495
496 /* Remove - remove an interface */
497
498 SubString = ACPI_STRSTR ("REMOVE", ActionArg);
499 if (SubString)
500 {
501 Status = AcpiRemoveInterface (InterfaceNameArg);
502 if (ACPI_FAILURE (Status))
503 {
504 AcpiOsPrintf ("%s, while removing \"%s\"\n",
505 AcpiFormatException (Status), InterfaceNameArg);
506 }
507 return;
508 }
509
510 /* Invalid ActionArg */
511
512 AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg);
513 return;
514}
515
516
517/*******************************************************************************
518 *
519 * FUNCTION: AcpiDbDisplayTemplate
520 *
521 * PARAMETERS: BufferArg - Buffer name or addrss
522 *
523 * RETURN: None
524 *
525 * DESCRIPTION: Dump a buffer that contains a resource template
526 *
527 ******************************************************************************/
528
529void
530AcpiDbDisplayTemplate (
531 char *BufferArg)
532{
533 ACPI_NAMESPACE_NODE *Node;
534 ACPI_STATUS Status;
535 ACPI_BUFFER ReturnObj;
536
537
538 /* Translate BufferArg to an Named object */
539
540 Node = AcpiDbConvertToNode (BufferArg);
541 if (!Node || (Node == AcpiGbl_RootNode))
542 {
543 AcpiOsPrintf ("Invalid argument: %s\n", BufferArg);
544 return;
545 }
546
547 /* We must have a buffer object */
548
549 if (Node->Type != ACPI_TYPE_BUFFER)
550 {
551 AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n",
552 BufferArg);
553 return;
554 }
555
556 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
557 ReturnObj.Pointer = AcpiGbl_DbBuffer;
558
559 /* Attempt to convert the raw buffer to a resource list */
560
561 Status = AcpiRsCreateResourceList (Node->Object, &ReturnObj);
562
563 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
564 AcpiDbgLevel |= ACPI_LV_RESOURCES;
565
566 if (ACPI_FAILURE (Status))
567 {
568 AcpiOsPrintf ("Could not convert Buffer to a resource list: %s, %s\n",
569 BufferArg, AcpiFormatException (Status));
570 goto DumpBuffer;
571 }
572
573 /* Now we can dump the resource list */
574
575 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
576 ReturnObj.Pointer));
577
578DumpBuffer:
579 AcpiOsPrintf ("\nRaw data buffer:\n");
580 AcpiUtDumpBuffer ((UINT8 *) Node->Object->Buffer.Pointer,
581 Node->Object->Buffer.Length,
582 DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
583
584 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
585 return;
586}
587
588
589/*******************************************************************************
590 *
591 * FUNCTION: AcpiDmCompareAmlResources
592 *
593 * PARAMETERS: Aml1Buffer - Contains first resource list
594 * Aml1BufferLength - Length of first resource list
595 * Aml2Buffer - Contains second resource list
596 * Aml2BufferLength - Length of second resource list
597 *
598 * RETURN: None
599 *
600 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
601 * order to isolate a miscompare to an individual resource)
602 *
603 ******************************************************************************/
604
605static void
606AcpiDmCompareAmlResources (
607 UINT8 *Aml1Buffer,
608 ACPI_RSDESC_SIZE Aml1BufferLength,
609 UINT8 *Aml2Buffer,
610 ACPI_RSDESC_SIZE Aml2BufferLength)
611{
612 UINT8 *Aml1;
613 UINT8 *Aml2;
614 UINT8 *Aml1End;
615 UINT8 *Aml2End;
616 ACPI_RSDESC_SIZE Aml1Length;
617 ACPI_RSDESC_SIZE Aml2Length;
618 ACPI_RSDESC_SIZE Offset = 0;
619 UINT8 ResourceType;
620 UINT32 Count = 0;
621 UINT32 i;
622
623
624 /* Compare overall buffer sizes (may be different due to size rounding) */
625
626 if (Aml1BufferLength != Aml2BufferLength)
627 {
628 AcpiOsPrintf (
629 "**** Buffer length mismatch in converted AML: Original %X, New %X ****\n",
630 Aml1BufferLength, Aml2BufferLength);
631 }
632
633 Aml1 = Aml1Buffer;
634 Aml2 = Aml2Buffer;
635 Aml1End = Aml1Buffer + Aml1BufferLength;
636 Aml2End = Aml2Buffer + Aml2BufferLength;
637
638 /* Walk the descriptor lists, comparing each descriptor */
639
640 while ((Aml1 < Aml1End) && (Aml2 < Aml2End))
641 {
642 /* Get the lengths of each descriptor */
643
644 Aml1Length = AcpiUtGetDescriptorLength (Aml1);
645 Aml2Length = AcpiUtGetDescriptorLength (Aml2);
646 ResourceType = AcpiUtGetResourceType (Aml1);
647
648 /* Check for descriptor length match */
649
650 if (Aml1Length != Aml2Length)
651 {
652 AcpiOsPrintf (
653 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X Len1 %X, Len2 %X ****\n",
654 Count, ResourceType, Offset, Aml1Length, Aml2Length);
655 }
656
657 /* Check for descriptor byte match */
658
659 else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
660 {
661 AcpiOsPrintf (
662 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
663 Count, ResourceType, Offset);
664
665 for (i = 0; i < Aml1Length; i++)
666 {
667 if (Aml1[i] != Aml2[i])
668 {
669 AcpiOsPrintf ("Mismatch at byte offset %.2X: is %2.2X, should be %2.2X\n",
670 i, Aml2[i], Aml1[i]);
671 }
672 }
673 }
674
675 /* Exit on EndTag descriptor */
676
677 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
678 {
679 return;
680 }
681
682 /* Point to next descriptor in each buffer */
683
684 Count++;
685 Offset += Aml1Length;
686 Aml1 += Aml1Length;
687 Aml2 += Aml2Length;
688 }
689}
690
691
692/*******************************************************************************
693 *
694 * FUNCTION: AcpiDmTestResourceConversion
695 *
696 * PARAMETERS: Node - Parent device node
697 * Name - resource method name (_CRS)
698 *
699 * RETURN: Status
700 *
701 * DESCRIPTION: Compare the original AML with a conversion of the AML to
702 * internal resource list, then back to AML.
703 *
704 ******************************************************************************/
705
706static ACPI_STATUS
707AcpiDmTestResourceConversion (
708 ACPI_NAMESPACE_NODE *Node,
709 char *Name)
710{
711 ACPI_STATUS Status;
712 ACPI_BUFFER ReturnObj;
713 ACPI_BUFFER ResourceObj;
714 ACPI_BUFFER NewAml;
715 ACPI_OBJECT *OriginalAml;
716
717
718 AcpiOsPrintf ("Resource Conversion Comparison:\n");
719
720 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
721 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
722 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
723
724 /* Get the original _CRS AML resource template */
725
726 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
727 if (ACPI_FAILURE (Status))
728 {
729 AcpiOsPrintf ("Could not obtain %s: %s\n",
730 Name, AcpiFormatException (Status));
731 return (Status);
732 }
733
734 /* Get the AML resource template, converted to internal resource structs */
735
736 Status = AcpiGetCurrentResources (Node, &ResourceObj);
737 if (ACPI_FAILURE (Status))
738 {
739 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
740 AcpiFormatException (Status));
741 goto Exit1;
742 }
743
744 /* Convert internal resource list to external AML resource template */
745
746 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
747 if (ACPI_FAILURE (Status))
748 {
749 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
750 AcpiFormatException (Status));
751 goto Exit2;
752 }
753
754 /* Compare original AML to the newly created AML resource list */
755
756 OriginalAml = ReturnObj.Pointer;
757
758 AcpiDmCompareAmlResources (
759 OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
760 NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
761
762 /* Cleanup and exit */
763
764 ACPI_FREE (NewAml.Pointer);
765Exit2:
766 ACPI_FREE (ResourceObj.Pointer);
767Exit1:
768 ACPI_FREE (ReturnObj.Pointer);
769 return (Status);
770}
771
772
773/*******************************************************************************
774 *
775 * FUNCTION: AcpiDbResourceCallback
776 *
777 * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK
778 *
779 * RETURN: Status
780 *
781 * DESCRIPTION: Simple callback to exercise AcpiWalkResources
782 *
783 ******************************************************************************/
784
785static ACPI_STATUS
786AcpiDbResourceCallback (
787 ACPI_RESOURCE *Resource,
788 void *Context)
789{
790
791 return (AE_OK);
792}
793
794
795/*******************************************************************************
796 *
797 * FUNCTION: AcpiDbDeviceResources
798 *
799 * PARAMETERS: ACPI_WALK_CALLBACK
800 *
801 * RETURN: Status
802 *
803 * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
804 *
805 ******************************************************************************/
806
807static ACPI_STATUS
808AcpiDbDeviceResources (
809 ACPI_HANDLE ObjHandle,
810 UINT32 NestingLevel,
811 void *Context,
812 void **ReturnValue)
813{
814 ACPI_NAMESPACE_NODE *Node;
815 ACPI_NAMESPACE_NODE *PrtNode = NULL;
816 ACPI_NAMESPACE_NODE *CrsNode = NULL;
817 ACPI_NAMESPACE_NODE *PrsNode = NULL;
818 ACPI_NAMESPACE_NODE *AeiNode = NULL;
819 char *ParentPath;
820 ACPI_BUFFER ReturnObj;
821 ACPI_STATUS Status;
822
823
824 Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
825 ParentPath = AcpiNsGetExternalPathname (Node);
826 if (!ParentPath)
827 {
828 return (AE_NO_MEMORY);
829 }
830
831 /* Get handles to the resource methods for this device */
832
833 (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode));
834 (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode));
835 (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode));
836 (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode));
837 if (!PrtNode && !CrsNode && !PrsNode && !AeiNode)
838 {
839 goto Cleanup; /* Nothing to do */
840 }
841
842 AcpiOsPrintf ("\nDevice: %s\n", ParentPath);
843
844 /* Prepare for a return object of arbitrary size */
845
846 ReturnObj.Pointer = AcpiGbl_DbBuffer;
847 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
848
849
850 /* _PRT */
851
852 if (PrtNode)
853 {
854 AcpiOsPrintf ("Evaluating _PRT\n");
855
856 Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnObj);
857 if (ACPI_FAILURE (Status))
858 {
859 AcpiOsPrintf ("Could not evaluate _PRT: %s\n",
860 AcpiFormatException (Status));
861 goto GetCrs;
862 }
863
864 ReturnObj.Pointer = AcpiGbl_DbBuffer;
865 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
866
867 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
868 if (ACPI_FAILURE (Status))
869 {
870 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
871 AcpiFormatException (Status));
872 goto GetCrs;
873 }
874
875 AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
876 }
877
878
879 /* _CRS */
880
881GetCrs:
882 if (CrsNode)
883 {
884 AcpiOsPrintf ("Evaluating _CRS\n");
885
886 ReturnObj.Pointer = AcpiGbl_DbBuffer;
887 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
888
889 Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnObj);
890 if (ACPI_FAILURE (Status))
891 {
892 AcpiOsPrintf ("Could not evaluate _CRS: %s\n",
893 AcpiFormatException (Status));
894 goto GetPrs;
895 }
896
897 /* This code is here to exercise the AcpiWalkResources interface */
898
899 Status = AcpiWalkResources (Node, METHOD_NAME__CRS,
900 AcpiDbResourceCallback, NULL);
901 if (ACPI_FAILURE (Status))
902 {
903 AcpiOsPrintf ("AcpiWalkResources failed: %s\n",
904 AcpiFormatException (Status));
905 goto GetPrs;
906 }
907
908 /* Get the _CRS resource list */
909
910 ReturnObj.Pointer = AcpiGbl_DbBuffer;
911 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
912
913 Status = AcpiGetCurrentResources (Node, &ReturnObj);
914 if (ACPI_FAILURE (Status))
915 {
916 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
917 AcpiFormatException (Status));
918 goto GetPrs;
919 }
920
921 /* Dump the _CRS resource list */
922
923 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
924 ReturnObj.Pointer));
925
926 /*
927 * Perform comparison of original AML to newly created AML. This tests both
928 * the AML->Resource conversion and the Resource->Aml conversion.
929 */
930 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
931
932 /* Execute _SRS with the resource list */
933
934 Status = AcpiSetCurrentResources (Node, &ReturnObj);
935 if (ACPI_FAILURE (Status))
936 {
937 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
938 AcpiFormatException (Status));
939 goto GetPrs;
940 }
941 }
942
943
944 /* _PRS */
945
946GetPrs:
947 if (PrsNode)
948 {
949 AcpiOsPrintf ("Evaluating _PRS\n");
950
951 ReturnObj.Pointer = AcpiGbl_DbBuffer;
952 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
953
954 Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnObj);
955 if (ACPI_FAILURE (Status))
956 {
957 AcpiOsPrintf ("Could not evaluate _PRS: %s\n",
958 AcpiFormatException (Status));
959 goto GetAei;
960 }
961
962 ReturnObj.Pointer = AcpiGbl_DbBuffer;
963 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
964
965 Status = AcpiGetPossibleResources (Node, &ReturnObj);
966 if (ACPI_FAILURE (Status))
967 {
968 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
969 AcpiFormatException (Status));
970 goto GetAei;
971 }
972
973 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
974 }
975
976
977 /* _AEI */
978
979GetAei:
980 if (AeiNode)
981 {
982 AcpiOsPrintf ("Evaluating _AEI\n");
983
984 ReturnObj.Pointer = AcpiGbl_DbBuffer;
985 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
986
987 Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnObj);
988 if (ACPI_FAILURE (Status))
989 {
990 AcpiOsPrintf ("Could not evaluate _AEI: %s\n",
991 AcpiFormatException (Status));
992 goto Cleanup;
993 }
994
995 ReturnObj.Pointer = AcpiGbl_DbBuffer;
996 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
997
998 Status = AcpiGetEventResources (Node, &ReturnObj);
999 if (ACPI_FAILURE (Status))
1000 {
1001 AcpiOsPrintf ("AcpiGetEventResources failed: %s\n",
1002 AcpiFormatException (Status));
1003 goto Cleanup;
1004 }
1005
1006 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1007 }
1008
1009
1010Cleanup:
1011 ACPI_FREE (ParentPath);
1012 return (AE_OK);
1013}
1014
1015
1016/*******************************************************************************
1017 *
1018 * FUNCTION: AcpiDbDisplayResources
1019 *
1020 * PARAMETERS: ObjectArg - String object name or object pointer.
1021 * "*" means "display resources for all devices"
1022 *
1023 * RETURN: None
1024 *
1025 * DESCRIPTION: Display the resource objects associated with a device.
1026 *
1027 ******************************************************************************/
1028
1029void
1030AcpiDbDisplayResources (
1031 char *ObjectArg)
1032{
1033 ACPI_NAMESPACE_NODE *Node;
1034
1035
1036 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1037 AcpiDbgLevel |= ACPI_LV_RESOURCES;
1038
1039 /* Asterisk means "display resources for all devices" */
1040
1041 if (!ACPI_STRCMP (ObjectArg, "*"))
1042 {
1043 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1044 ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL);
1045 }
1046 else
1047 {
1048 /* Convert string to object pointer */
1049
1050 Node = AcpiDbConvertToNode (ObjectArg);
1051 if (Node)
1052 {
1053 if (Node->Type != ACPI_TYPE_DEVICE)
1054 {
1055 AcpiOsPrintf ("%4.4s: Name is not a device object (%s)\n",
1056 Node->Name.Ascii, AcpiUtGetTypeName (Node->Type));
1057 }
1058 else
1059 {
1060 (void) AcpiDbDeviceResources (Node, 0, NULL, NULL);
1061 }
1062 }
1063 }
1064
1065 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1066}
1067
1068
1069#if (!ACPI_REDUCED_HARDWARE)
1070/*******************************************************************************
1071 *
1072 * FUNCTION: AcpiDbGenerateGpe
1073 *
1074 * PARAMETERS: GpeArg - Raw GPE number, ascii string
1075 * BlockArg - GPE block number, ascii string
1076 * 0 or 1 for FADT GPE blocks
1077 *
1078 * RETURN: None
1079 *
1080 * DESCRIPTION: Generate a GPE
1081 *
1082 ******************************************************************************/
1083
1084void
1085AcpiDbGenerateGpe (
1086 char *GpeArg,
1087 char *BlockArg)
1088{
1089 UINT32 BlockNumber;
1090 UINT32 GpeNumber;
1091 ACPI_GPE_EVENT_INFO *GpeEventInfo;
1092
1093
1094 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0);
1095 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1096
1097
1098 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1099 GpeNumber);
1100 if (!GpeEventInfo)
1101 {
1102 AcpiOsPrintf ("Invalid GPE\n");
1103 return;
1104 }
1105
1106 (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
1107}
1108#endif /* !ACPI_REDUCED_HARDWARE */
1109
1110#endif /* ACPI_DEBUGGER */