mirror of
https://github.com/acpica/acpica/
synced 2025-01-15 22:09:17 +03:00
Major update for new disassembler (produces compilable ASL).
date 2002.07.15.20.51.00; author rmoore1; state Exp;
This commit is contained in:
parent
f3d5a3c4cf
commit
54e0380bbd
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: adexec - AcpiDump utility, top level parse and execute routines
|
||||
* Module Name: adisasm - Application-level disassembler routines
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -118,11 +118,13 @@
|
||||
#include "acparser.h"
|
||||
#include "amlcode.h"
|
||||
#include "acdebug.h"
|
||||
#include "acdisasm.h"
|
||||
#include "acdispat.h"
|
||||
#include "acnamesp.h"
|
||||
#include "adisasm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#define _COMPONENT ACPI_TOOLS
|
||||
@ -136,7 +138,7 @@ UINT32 AmlLength;
|
||||
UINT8 *DsdtPtr;
|
||||
UINT32 DsdtLength;
|
||||
|
||||
|
||||
#ifndef _ACPI_ASL_COMPILER
|
||||
BOOLEAN
|
||||
AcpiDsIsResultUsed (
|
||||
ACPI_PARSE_OBJECT *Op,
|
||||
@ -144,6 +146,7 @@ AcpiDsIsResultUsed (
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
ACPI_STATUS
|
||||
AcpiDsRestartControlMethod (
|
||||
@ -178,6 +181,57 @@ AcpiDsMethodDataInitArgs (
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
#define FILE_SUFFIX_DISASSEMBLY "dsl"
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: FlGenerateFilename
|
||||
*
|
||||
* PARAMETERS: InputFilename - Original ASL source filename
|
||||
* Suffix - New extension.
|
||||
*
|
||||
* RETURN: New filename containing the original base + the new suffix
|
||||
*
|
||||
* DESCRIPTION: Generate a new filename from the ASL source filename and a new
|
||||
* extension. Used to create the *.LST, *.TXT, etc. files.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
char *
|
||||
FlGenerateFilename (
|
||||
char *InputFilename,
|
||||
char *Suffix)
|
||||
{
|
||||
char *Position;
|
||||
char *NewFilename;
|
||||
|
||||
|
||||
/* Copy the original filename to a new buffer */
|
||||
|
||||
NewFilename = ACPI_MEM_CALLOCATE (strlen (InputFilename) + strlen (Suffix));
|
||||
strcpy (NewFilename, InputFilename);
|
||||
|
||||
/* Try to find the last dot in the filename */
|
||||
|
||||
Position = strrchr (NewFilename, '.');
|
||||
if (Position)
|
||||
{
|
||||
/* Tack on the new suffix */
|
||||
Position++;
|
||||
*Position = 0;
|
||||
strcat (Position, Suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No dot, add one and then the suffix */
|
||||
|
||||
strcat (NewFilename, ".");
|
||||
strcat (NewFilename, Suffix);
|
||||
}
|
||||
|
||||
return NewFilename;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
@ -197,6 +251,10 @@ AdAmlDisassemble (
|
||||
char *Filename)
|
||||
{
|
||||
ACPI_STATUS Status;
|
||||
char *OutFilename;
|
||||
FILE *File;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Get the ACPI Tables (always) */
|
||||
@ -214,17 +272,35 @@ AdAmlDisassemble (
|
||||
Status = AdGetTables (Filename);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
AcpiOsPrintf ("Could not get ACPI tables %s\n", AcpiFormatException (Status));
|
||||
AcpiOsPrintf ("Could not get ACPI tables, %s\n",
|
||||
AcpiFormatException (Status));
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Create/Open a combined source output file */
|
||||
|
||||
OutFilename = FlGenerateFilename (Filename, FILE_SUFFIX_DISASSEMBLY);
|
||||
if (!OutFilename)
|
||||
{
|
||||
fprintf (stderr, "Could not generate output filename\n");
|
||||
}
|
||||
File = fopen (OutFilename, "w+");
|
||||
if (!File)
|
||||
{
|
||||
fprintf (stderr, "Could not open output filen\n");
|
||||
}
|
||||
|
||||
AcpiOsRedirectOutput (File);
|
||||
|
||||
/* Always parse the tables, only option is what to display */
|
||||
|
||||
Status = AdParseTables ();
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
AcpiOsPrintf ("Could not parse ACPI tables %s\n", AcpiFormatException (Status));
|
||||
AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
|
||||
AcpiFormatException (Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
@ -232,17 +308,17 @@ AdAmlDisassemble (
|
||||
|
||||
if (AcpiGbl_DbOpt_disasm)
|
||||
{
|
||||
AdDisplayTables ();
|
||||
AdDisplayTables (Filename);
|
||||
fprintf (stderr, "Disassembly completed, written to \"%s\"\n", OutFilename);
|
||||
}
|
||||
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: AdCreateTableHeaders
|
||||
* FUNCTION: AdCreateTableHeader
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
@ -253,48 +329,24 @@ AdAmlDisassemble (
|
||||
*****************************************************************************/
|
||||
|
||||
void
|
||||
AdCreateTableHeaders (void)
|
||||
AdCreateTableHeader (
|
||||
char *Filename,
|
||||
ACPI_TABLE_HEADER *Table)
|
||||
{
|
||||
time_t Timer;
|
||||
|
||||
AcpiOsPrintf ("%s\n", "DefinitionBlock(\"SE0005B.aml\",\"DSDT\",1,\"Intel\",\"Seattl\",2)");
|
||||
AcpiOsPrintf ("%s\n", "{");
|
||||
time (&Timer);
|
||||
|
||||
AcpiOsPrintf ("/*\n * Intel ACPI Component Architecture AML Disassembler\n");
|
||||
AcpiOsPrintf (" * Version %8.8X\n", ACPI_CA_VERSION);
|
||||
AcpiOsPrintf (" *\n * Disassembly of %s, %s */\n", Filename, ctime (&Timer));
|
||||
|
||||
AcpiOsPrintf ("DefinitionBlock (\"DSDT.aml\", \"%4.4s\", %d, \"%.6s\", \"%.8s\", %d)\n",
|
||||
Table->Signature, Table->Revision,
|
||||
Table->OemId, Table->OemTableId, Table->OemRevision);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: AdBlockType
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define BLOCK_PAREN 1
|
||||
#define BLOCK_BRACE 2
|
||||
|
||||
INT32
|
||||
c (
|
||||
ACPI_PARSE_OBJECT *Op)
|
||||
{
|
||||
|
||||
switch (Op->Common.AmlOpcode)
|
||||
{
|
||||
case AML_METHOD_OP:
|
||||
return BLOCK_BRACE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return BLOCK_PAREN;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: AdDisplayTables
|
||||
@ -308,7 +360,8 @@ c (
|
||||
*****************************************************************************/
|
||||
|
||||
ACPI_STATUS
|
||||
AdDisplayTables (void)
|
||||
AdDisplayTables (
|
||||
char *Filename)
|
||||
{
|
||||
|
||||
|
||||
@ -320,17 +373,19 @@ AdDisplayTables (void)
|
||||
|
||||
if (!AcpiGbl_DbOpt_verbose)
|
||||
{
|
||||
AdCreateTableHeaders ();
|
||||
AdCreateTableHeader (Filename, AcpiGbl_DSDT);
|
||||
}
|
||||
|
||||
AcpiDbDisplayOp (NULL, AcpiPsGetChild (AcpiGbl_ParsedNamespaceRoot), ACPI_UINT32_MAX);
|
||||
AcpiDmDisassemble (NULL, AcpiGbl_ParsedNamespaceRoot, ACPI_UINT32_MAX);
|
||||
|
||||
AcpiOsPrintf ("\n\nDSDT Header:\n");
|
||||
AcpiUtDumpBuffer ((UINT8 *) AcpiGbl_DSDT, sizeof (ACPI_TABLE_HEADER), DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
|
||||
|
||||
AcpiOsPrintf ("DSDT Body (Length 0x%X)\n", AmlLength);
|
||||
AcpiUtDumpBuffer ((UINT8 *) AmlStart, AmlLength, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
|
||||
if (AcpiGbl_DbOpt_verbose)
|
||||
{
|
||||
AcpiOsPrintf ("\n\nDSDT Header:\n");
|
||||
AcpiUtDumpBuffer ((UINT8 *) AcpiGbl_DSDT, sizeof (ACPI_TABLE_HEADER), DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
|
||||
|
||||
AcpiOsPrintf ("DSDT Body (Length 0x%X)\n", AmlLength);
|
||||
AcpiUtDumpBuffer ((UINT8 *) AmlStart, AmlLength, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
|
||||
}
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
@ -386,10 +441,127 @@ AdLoadDsdt(
|
||||
*DsdtPtr = NULL;
|
||||
*DsdtLength = 0;
|
||||
|
||||
return AE_AML_ERROR;
|
||||
return AE_NO_ACPI_TABLES;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
ACPI_STATUS
|
||||
AdDoDeferredParse (
|
||||
ACPI_PARSE_OBJECT *Op,
|
||||
UINT8 *Aml,
|
||||
UINT32 AmlLength)
|
||||
{
|
||||
ACPI_WALK_STATE *WalkState;
|
||||
ACPI_STATUS Status;
|
||||
ACPI_PARSE_OBJECT *SearchOp;
|
||||
ACPI_PARSE_OBJECT *StartOp;
|
||||
UINT32 BaseAmlOffset;
|
||||
ACPI_PARSE_OBJECT *ExtraOp;
|
||||
|
||||
|
||||
ACPI_FUNCTION_NAME ("AdDoDeferredParse");
|
||||
|
||||
|
||||
fprintf (stderr, ".");
|
||||
|
||||
if (!Aml || !AmlLength)
|
||||
{
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing %s [%4.4s]\n",
|
||||
Op->Common.AmlOpName, &Op->Named.Name));
|
||||
|
||||
WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, Op, NULL, NULL);
|
||||
if (!WalkState)
|
||||
{
|
||||
return_ACPI_STATUS (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml,
|
||||
AmlLength, NULL, NULL, 1);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
/* Parse the method */
|
||||
|
||||
Status = AcpiPsParseAml (WalkState);
|
||||
|
||||
/*
|
||||
* We need to update all of the Aml offsets, since the parser thought
|
||||
* that the method began at offset zero. In reality, it began somewhere
|
||||
* within the ACPI table, at the BaseAmlOffset. Walk the entire tree that
|
||||
* was just created and update the AmlOffset in each Op
|
||||
*/
|
||||
BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1;
|
||||
StartOp = (Op->Common.Value.Arg)->Common.Next;
|
||||
SearchOp = StartOp;
|
||||
|
||||
/* Walk the parse tree */
|
||||
|
||||
while (SearchOp)
|
||||
{
|
||||
SearchOp->Common.AmlOffset += BaseAmlOffset;
|
||||
SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
|
||||
}
|
||||
|
||||
switch (Op->Common.AmlOpcode)
|
||||
{
|
||||
case AML_BUFFER_OP:
|
||||
case AML_PACKAGE_OP:
|
||||
case AML_VAR_PACKAGE_OP:
|
||||
|
||||
switch (Op->Common.AmlOpcode)
|
||||
{
|
||||
case AML_PACKAGE_OP:
|
||||
case AML_VAR_PACKAGE_OP:
|
||||
ExtraOp = Op->Common.Value.Arg;
|
||||
ExtraOp = ExtraOp->Common.Next;
|
||||
Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
|
||||
break;
|
||||
|
||||
case AML_BUFFER_OP:
|
||||
default:
|
||||
ExtraOp = Op->Common.Value.Arg;
|
||||
Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
|
||||
break;
|
||||
}
|
||||
|
||||
StartOp = Op;
|
||||
SearchOp = StartOp;
|
||||
while (SearchOp)
|
||||
{
|
||||
if (SearchOp->Common.Parent == ExtraOp)
|
||||
{
|
||||
SearchOp->Common.Parent = Op;
|
||||
}
|
||||
SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: AdSecondPassParse
|
||||
@ -407,86 +579,60 @@ AdSecondPassParse (
|
||||
ACPI_PARSE_OBJECT *Root)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *Op = Root;
|
||||
ACPI_PARSE_OBJECT *Method;
|
||||
ACPI_PARSE_OBJECT *SearchOp;
|
||||
ACPI_PARSE_OBJECT *StartOp;
|
||||
ACPI_STATUS Status = AE_OK;
|
||||
UINT32 BaseAmlOffset;
|
||||
ACPI_WALK_STATE *WalkState;
|
||||
const ACPI_OPCODE_INFO *OpInfo;
|
||||
|
||||
|
||||
ACPI_FUNCTION_NAME ("AdSecondPassParse");
|
||||
printf ("Parsing Control Methods \n");
|
||||
fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
|
||||
|
||||
while (Op)
|
||||
{
|
||||
if (Op->Common.AmlOpcode == AML_METHOD_OP)
|
||||
OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
|
||||
if (!(OpInfo->Flags & AML_DEFER))
|
||||
{
|
||||
printf (".");
|
||||
Op = AcpiPsGetDepthNext (Root, Op);
|
||||
continue;
|
||||
}
|
||||
|
||||
Method = Op;
|
||||
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing method [%4.4s]\n", &Method->Named.Name));
|
||||
|
||||
WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT,
|
||||
Op, NULL, NULL);
|
||||
if (!WalkState)
|
||||
{
|
||||
return_ACPI_STATUS (AE_NO_MEMORY);
|
||||
}
|
||||
switch (Op->Common.AmlOpcode)
|
||||
{
|
||||
case AML_METHOD_OP:
|
||||
case AML_BUFFER_OP:
|
||||
case AML_PACKAGE_OP:
|
||||
case AML_VAR_PACKAGE_OP:
|
||||
|
||||
Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Method->Named.Data,
|
||||
Method->Named.Length, NULL, NULL, 1);
|
||||
Status = AdDoDeferredParse (Op, Op->Named.Data, Op->Named.Length);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Parse the method */
|
||||
case AML_REGION_OP:
|
||||
case AML_CREATE_QWORD_FIELD_OP:
|
||||
case AML_CREATE_DWORD_FIELD_OP:
|
||||
case AML_CREATE_WORD_FIELD_OP:
|
||||
case AML_CREATE_BYTE_FIELD_OP:
|
||||
case AML_CREATE_BIT_FIELD_OP:
|
||||
case AML_CREATE_FIELD_OP:
|
||||
|
||||
Status = AcpiPsParseAml (WalkState); //Op, Method->Data, Method->Length, 0,
|
||||
//NULL, NULL, NULL, AcpiPsFindObject, NULL);
|
||||
/* Nothing to do in these cases */
|
||||
|
||||
/*
|
||||
* We need to update all of the Aml offsets, since the parser thought
|
||||
* that the method began at offset zero. In reality, it began somewhere
|
||||
* within the ACPI table, at the BaseAmlOffset. Walk the entire tree that
|
||||
* was just created and update the AmlOffset in each Op
|
||||
*/
|
||||
break;
|
||||
|
||||
BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1;
|
||||
StartOp = (Method->Common.Value.Arg)->Common.Next;
|
||||
SearchOp = StartOp;
|
||||
default:
|
||||
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unhandled deferred opcode [%s]\n",
|
||||
Op->Common.AmlOpName));
|
||||
break;
|
||||
|
||||
/* Walk the parse tree */
|
||||
|
||||
while (SearchOp)
|
||||
{
|
||||
SearchOp->Common.AmlOffset += BaseAmlOffset;
|
||||
SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Op->Common.AmlOpcode == AML_REGION_OP)
|
||||
{
|
||||
/* TBD: Code below isn't quite the right thing to do!
|
||||
* Is there any need to parse regions here?
|
||||
*/
|
||||
|
||||
// Method = (ACPI_DEFERRED_OP *) Op;
|
||||
// Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength);
|
||||
}
|
||||
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
Op = AcpiPsGetDepthNext (Root, Op);
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
|
||||
fprintf (stderr, "\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
@ -513,7 +659,7 @@ AdGetTables (
|
||||
|
||||
if (Filename)
|
||||
{
|
||||
printf ("Loading DSDT from file %s\n", Filename);
|
||||
fprintf (stderr, "Loading DSDT from file %s\n", Filename);
|
||||
fp = fopen (Filename, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
@ -531,9 +677,9 @@ AdGetTables (
|
||||
|
||||
else
|
||||
{
|
||||
#ifdef _IA16
|
||||
#if ACPI_MACHINE_WIDTH == 16
|
||||
#include "16bit.h"
|
||||
printf ("Scanning for DSDT\n");
|
||||
fprintf (stderr, "Scanning for DSDT\n");
|
||||
|
||||
Status = AfFindDsdt (&DsdtPtr, &DsdtLength);
|
||||
|
||||
@ -544,7 +690,7 @@ AdGetTables (
|
||||
printf ("Dumped DSDT\n");
|
||||
}
|
||||
#else
|
||||
printf ("Must supply filename for ACPI tables, cannot scan memory\n");
|
||||
fprintf (stderr, "Must supply filename for ACPI tables, cannot scan memory\n");
|
||||
Status = AE_NO_ACPI_TABLES;
|
||||
#endif
|
||||
}
|
||||
@ -605,7 +751,7 @@ AdParseTables (void)
|
||||
|
||||
/* Pass 1: Parse everything except control method bodies */
|
||||
|
||||
printf ("Pass 1 parse\n");
|
||||
fprintf (stderr, "Pass 1 parse\n");
|
||||
|
||||
/* Create and initialize a new walk state */
|
||||
|
||||
@ -628,8 +774,7 @@ AdParseTables (void)
|
||||
}
|
||||
|
||||
|
||||
Status = AcpiPsParseAml (WalkState); //, AmlStart, AmlLength, 0,
|
||||
//NULL, NULL, NULL, AcpiPsFindObject, NULL);
|
||||
Status = AcpiPsParseAml (WalkState);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return Status;
|
||||
@ -637,10 +782,10 @@ AdParseTables (void)
|
||||
|
||||
/* Pass 2: Parse control methods and link their parse trees into the main parse tree */
|
||||
|
||||
printf ("Pass 2 parse\n");
|
||||
fprintf (stderr, "Pass 2 parse\n");
|
||||
Status = AdSecondPassParse (AcpiGbl_ParsedNamespaceRoot);
|
||||
|
||||
printf ("Parsing completed\n");
|
||||
fprintf (stderr, "Parsing completed\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user