123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- /*++
- Copyright (c) 2012 Minoca Corp. All Rights Reserved
- Module Name:
- acpiext.c
- Abstract:
- This module implements ACPI related debugger extensions.
- Author:
- Evan Green 27-Nov-2012
- Environment:
- Debug Client
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- //
- // Define away KERNEL_API to avoid it being defined as an import or export.
- //
- #define KERNEL_API
- #include <minoca/lib/types.h>
- #include <minoca/lib/status.h>
- #include <minoca/lib/rtl.h>
- #include <minoca/lib/im.h>
- #include <minoca/debug/dbgext.h>
- #include "../../drivers/acpi/acpiobj.h"
- #include <errno.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define ROOT_NAMESPACE_OBJECT_SYMBOL "acpi!AcpiNamespaceRoot"
- #define MALLOC(_x) malloc(_x)
- #define FREE(_x) free(_x)
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- VOID
- ExtAcpiNamespace (
- PDEBUGGER_CONTEXT Context,
- ULONG ArgumentCount,
- PSTR *ArgumentValues
- );
- INT
- ExtpPrintNamespaceAtRoot (
- PDEBUGGER_CONTEXT Context,
- ULONGLONG Address,
- PULONGLONG NextSibling,
- ULONG IndentationLevel
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // ------------------------------------------------------------------ Functions
- //
- INT
- ExtAcpi (
- PDEBUGGER_CONTEXT Context,
- PSTR Command,
- ULONG ArgumentCount,
- PSTR *ArgumentValues
- )
- /*++
- Routine Description:
- This routine implements the ACPI debugger extension.
- Arguments:
- Context - Supplies a pointer to the debugger applicaton context, which is
- an argument to most of the API functions.
- Command - Supplies the subcommand entered.
- ArgumentCount - Supplies the number of arguments in the ArgumentValues
- array.
- ArgumentValues - Supplies the values of each argument. This memory will be
- reused when the function returns, so extensions must not touch this
- memory after returning from this call.
- Return Value:
- 0 if the debugger extension command was successful.
- Returns an error code if a failure occurred along the way.
- --*/
- {
- if (Command == NULL) {
- DbgOut("Error: A valid subcommand must be supplied. Try one of these:\n"
- "\t!acpi.ns\n\n");
- return EINVAL;
- }
- if (strcmp(Command, "ns") == 0) {
- ExtAcpiNamespace(Context, ArgumentCount - 1, ArgumentValues + 1);
- } else {
- DbgOut("Error: A valid subcommand must be supplied. Try one of these:\n"
- "\t!acpi.ns\n\n");
- }
- return 0;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- VOID
- ExtAcpiNamespace (
- PDEBUGGER_CONTEXT Context,
- ULONG ArgumentCount,
- PSTR *ArgumentValues
- )
- /*++
- Routine Description:
- This routine implements the ACPI namespace debugger extension.
- Arguments:
- Context - Supplies a pointer to the debugger application context.
- ArgumentCount - Supplies the number of arguments in the ArgumentValues
- array.
- ArgumentValues - Supplies the values of each argument. This memory will be
- reused when the function returns, so extensions must not touch this
- memory after returning from this call.
- Return Value:
- None.
- --*/
- {
- ULONG AddressSize;
- ULONG ArgumentIndex;
- ULONG BytesRead;
- BOOL Result;
- ULONGLONG RootAddress;
- ULONGLONG RootAddressAddress;
- INT Success;
- RootAddress = 0;
- RootAddressAddress = 0;
- AddressSize = DbgGetTargetPointerSize(Context);
- //
- // If there are no arguments, try to find the root.
- //
- if (ArgumentCount == 0) {
- Result = DbgEvaluate(Context,
- ROOT_NAMESPACE_OBJECT_SYMBOL,
- &RootAddressAddress);
- if (Result != 0) {
- DbgOut("Error: Could not evaluate %s\n",
- ROOT_NAMESPACE_OBJECT_SYMBOL);
- return;
- }
- //
- // Now given the address of the pointer, read the value to get the
- // actual address of the root object.
- //
- Success = DbgReadMemory(Context,
- TRUE,
- RootAddressAddress,
- AddressSize,
- &RootAddress,
- &BytesRead);
- if ((Success != 0) || (BytesRead != AddressSize)) {
- DbgOut("Error: Could not read root object at 0x%I64x.\n",
- RootAddressAddress);
- return;
- }
- if (RootAddress == (UINTN)NULL) {
- DbgOut("ACPI Object root is NULL.\n");
- return;
- }
- DbgOut("%s: %I64x\n", ROOT_NAMESPACE_OBJECT_SYMBOL, RootAddress);
- ExtpPrintNamespaceAtRoot(Context, RootAddress, NULL, 0);
- } else {
- //
- // Loop through each argument, evaluate the address, and print the
- // namespace tree at that object.
- //
- for (ArgumentIndex = 0;
- ArgumentIndex < ArgumentCount;
- ArgumentIndex += 1) {
- Result = DbgEvaluate(Context,
- ArgumentValues[ArgumentIndex],
- &RootAddress);
- if (Result != 0) {
- DbgOut("Failed to evaluate address at \"%s\".\n",
- ArgumentValues[ArgumentIndex]);
- }
- ExtpPrintNamespaceAtRoot(Context, RootAddress, NULL, 0);
- if (ArgumentIndex != ArgumentCount - 1) {
- DbgOut("\n----");
- }
- }
- }
- return;
- }
- INT
- ExtpPrintNamespaceAtRoot (
- PDEBUGGER_CONTEXT Context,
- ULONGLONG Address,
- PULONGLONG NextSibling,
- ULONG IndentationLevel
- )
- /*++
- Routine Description:
- This routine prints out the ACPI namespace rooted at the given object.
- Arguments:
- Context - Supplies a pointer to the application context.
- Address - Supplies the address of the root object to print.
- NextSibling - Supplies an optional pointer where the next sibling pointer
- will be returned.
- IndentationLevel - Supplies the indentation level to print the object at.
- Return Value:
- 0 on success.
- Returns an error code on failure.
- --*/
- {
- PTYPE_SYMBOL AcpiObjectType;
- ULONGLONG ChildListHead;
- ULONG ChildListOffset;
- PVOID Data;
- ULONG DataSize;
- ULONG ListEntryOffset;
- ULONG Name;
- INT Status;
- ULONGLONG Value;
- //
- // Bail out if the indentation seems too deep.
- //
- if (IndentationLevel > 50) {
- return EINVAL;
- }
- //
- // Print out the indentation.
- //
- DbgOut("%*s", IndentationLevel, "");
- Status = DbgReadTypeByName(Context,
- Address,
- "acpi!ACPI_OBJECT",
- &AcpiObjectType,
- &Data,
- &DataSize);
- if (Status != 0) {
- DbgOut("Error: Could not read object at 0x%I64x: %s.\n",
- Address,
- strerror(Status));
- goto PrintNamespaceAtRootEnd;
- }
- //
- // Print the object.
- //
- Status = DbgReadIntegerMember(Context,
- AcpiObjectType,
- "Name",
- Address,
- Data,
- DataSize,
- &Value);
- if (Status != 0) {
- goto PrintNamespaceAtRootEnd;
- }
- Name = Value;
- DbgOut("%08I64x %c%c%c%c ",
- Address,
- (UCHAR)Name,
- (UCHAR)(Name >> 8),
- (UCHAR)(Name >> 16),
- (UCHAR)(Name >> 24));
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "Type",
- 0,
- 0);
- if (Status != 0) {
- goto PrintNamespaceAtRootEnd;
- }
- DbgOut(" ");
- Status = DbgReadIntegerMember(Context,
- AcpiObjectType,
- "Type",
- Address,
- Data,
- DataSize,
- &Value);
- switch (Value) {
- case AcpiObjectInteger:
- DbgOut("Value: ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.Integer.Value",
- 0,
- 0);
- break;
- case AcpiObjectString:
- DbgOut("Address: ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.String.String",
- 0,
- 0);
- break;
- case AcpiObjectBuffer:
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.Buffer.Buffer",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(" Length: ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.Buffer.Length",
- 0,
- 0);
- break;
- case AcpiObjectPackage:
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.Package.Array",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(" Count: ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.Package.ElementCount",
- 0,
- 0);
- break;
- case AcpiObjectFieldUnit:
- DbgOut("OpRegion ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.FieldUnit.OperationRegion",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(" ( ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.FieldUnit.BitOffset",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(", ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.FieldUnit.BitLength",
- 0,
- 0);
- DbgOut(")");
- break;
- case AcpiObjectMethod:
- DbgOut("Args: ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.Method.ArgumentCount",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(", at ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.Method.AmlCode",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(" length ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.Method.AmlCodeSize",
- 0,
- 0);
- break;
- case AcpiObjectOperationRegion:
- DbgOut("(");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.OperationRegion.Space",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(", ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.OperationRegion.Offset",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(", ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.OperationRegion.Length",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(")");
- break;
- case AcpiObjectBufferField:
- DbgOut("Destination Object: ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.BufferField.DestinationObject",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(", Bit Offset: ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.BufferField.BitOffset",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- DbgOut(", Bit Length ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.BufferField.BitLength",
- 0,
- 0);
- if (Status != 0) {
- break;
- }
- break;
- case AcpiObjectAlias:
- DbgOut("Destination: ");
- Status = DbgPrintTypeMember(Context,
- Address,
- Data,
- DataSize,
- AcpiObjectType,
- "U.Alias.DestinationObject",
- 0,
- 0);
- break;
- default:
- break;
- }
- DbgOut("\n");
- if (Status != 0) {
- goto PrintNamespaceAtRootEnd;
- }
- //
- // Get offsets into the structure for the list head and list entries.
- //
- IndentationLevel += 1;
- Status = DbgGetMemberOffset(AcpiObjectType,
- "ChildListHead",
- &ChildListOffset,
- NULL);
- if (Status != 0) {
- goto PrintNamespaceAtRootEnd;
- }
- ChildListHead = Address + (ChildListOffset / BITS_PER_BYTE);
- Status = DbgGetMemberOffset(AcpiObjectType,
- "SiblingListEntry",
- &ListEntryOffset,
- NULL);
- if (Status != 0) {
- goto PrintNamespaceAtRootEnd;
- }
- ListEntryOffset /= BITS_PER_BYTE;
- //
- // Read the sibling list entry's next pointer for the caller.
- //
- if (NextSibling != NULL) {
- Status = DbgReadIntegerMember(Context,
- AcpiObjectType,
- "SiblingListEntry.Next",
- Address,
- Data,
- DataSize,
- NextSibling);
- if (Status != 0) {
- goto PrintNamespaceAtRootEnd;
- }
- }
- //
- // Read the first element on the child list.
- //
- Status = DbgReadIntegerMember(Context,
- AcpiObjectType,
- "ChildListHead.Next",
- Address,
- Data,
- DataSize,
- &Address);
- free(Data);
- Data = NULL;
- //
- // Loop printing all children.
- //
- while (Address != ChildListHead) {
- Address -= ListEntryOffset;
- Status = ExtpPrintNamespaceAtRoot(Context,
- Address,
- &Address,
- IndentationLevel);
- if (Status != 0) {
- goto PrintNamespaceAtRootEnd;
- }
- }
- PrintNamespaceAtRootEnd:
- if (Data != NULL) {
- free(Data);
- }
- return Status;
- }
|