From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Michael S. Tsirkin" Subject: [PATCH 2/4] acpi: add aml/asl parsing script Date: Wed, 21 Sep 2011 15:44:29 +0300 Message-ID: <408bb38ea26e509cbabc83df910e8fc804b2b7ec.1316608551.git.mst@redhat.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: "Kevin O'Connor" , seabios@seabios.org, Gleb Natapov , kvm@vger.kernel.org, jasowang@redhat.com, alex williamson , Marcelo Tosatti To: Amos Kong Return-path: Received: from mx1.redhat.com ([209.132.183.28]:4697 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753735Ab1IUMnb (ORCPT ); Wed, 21 Sep 2011 08:43:31 -0400 Content-Disposition: inline In-Reply-To: Sender: kvm-owner@vger.kernel.org List-ID: script ./src/find_ej0.pl finds all instances of method named EJ0_ and the matching _ADR information, and outputs the AML offset and slot mask of each. Signed-off-by: Michael S. Tsirkin --- src/find_ej0.pl | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 136 insertions(+), 0 deletions(-) create mode 100755 src/find_ej0.pl diff --git a/src/find_ej0.pl b/src/find_ej0.pl new file mode 100755 index 0000000..37e8a8c --- /dev/null +++ b/src/find_ej0.pl @@ -0,0 +1,136 @@ +#!/usr/bin/perl + +# Process mixed ASL/AML listing (.lst file) produced by iasl -l +# Locate all occurences of Name _ADR followed by Method EJ0_ +# Output slot info from _ADR and offset of method name in AML + +use strict; + +my @aml = (); +my @asl = (); +my @asl_lineno = (); +my @asl_to_aml_offset = (); +my @output = (); + +#Store an ASL command, matching AML offset, and input line (for debugging) +sub add_asl { + my $srcline = shift(@_); + my $line = shift(@_); + push @asl, $line; + push @asl_lineno, $.; + push @asl_to_aml_offset, $#aml + 1; +} + +#Store an AML byte sequence +#Verify that offset output by iasl matches # of bytes so far +sub add_aml { + my $offset = shift(@_); + my $line = shift(@_); + my $o = hex($offset); + # Sanity check: offset must match + die "Offset $o != " .($#aml + 1) if ($o != $#aml + 1); + # Strip any traling dots and ASCII dump after " + $line =~ s/\s*\.*\s*".*//; + + my @code = split(' ', $line); + foreach my $c (@code) { + if (not($c =~ m/^[0-9A-Fa-f][0-9A-Fa-f]$/)) { + die "Unexpected octet $c"; + } + push @aml, hex($c); + } +} + +# Process aml bytecode array, decoding AML +# Given method offset, find its name offset +sub aml_method_name { + my $lineno = shift(@_); + my $offset = shift(@_); + #0x14 MethodOp PkgLength NameString MethodFlags TermList + if ($aml[$offset] != 0x14) { + die "Method after input line $lineno offset $offset: " . + " expected 0x14 actual ". sprintf("0x%x", $aml[$offset]); + } + $offset += 1; + # PkgLength can be multibyte. Bits 8-7 give the # of extra bytes. + my $pkglenbytes = $aml[$offset] >> 6; + $offset += 1 + $pkglenbytes; + return $offset; +} + +while (<>) { + #Strip trailing newline + chomp; + #ASL listing: space, then line#, then ...., then code + if (s#^\s+([0-9]+)\.\.\.\.\s*##) { + add_asl($1, $_); + } + # AML listing: offset in hex, then ...., then code + if (s#^([0-9A-F]+)\.\.\.\.\s*##) { + add_aml($1, $_); + } + # Ignore everything else +} + +# Now go over code, look for EJ0_ methods +# For each such method, output slot mask from the +# preceding _ADR line, as well as the method name offset. +for (my $i = 0; $i <= $#asl; $i++) { + my $l = $asl[$i]; + # match: Method (EJ0_,1) + if (not $l =~ m#^Method\s*\(\s*EJ0_\s*[,)]#) { + # Make sure we do not miss any EJ0_: + # die if EJ0_ is found anywhere else in source code + if ($l =~ m#EJ0_#) { + die "Stray EJ0_ detected at input line $asl_lineno[$i]: $asl[$i]"; + } + next; + } + # EJ0_ found. Previous line must be _ADR + my $p = $i > 0 ? $asl[$i - 1] : ""; + # match: Name (_ADR, 0x
) + if (not ($p =~ m#Name\s*\(\s*_ADR\s*,\s*0x([0-9A-Fa-f]+)\s*\)#)) { + die "_ADR not found before EJ0_ ". + "at input line $asl_lineno[$i]: $asl[$i]"; + } + my $adr = hex($1); + my $slot = $adr >> 16; + if ($slot > 31) { + die "_ADR device out of range: actual $slot " . + "expected 0 to 31 at input line $asl_lineno[$i]: $asl[$i]"; + } + + # We have offset of EJ0_ method in code + # Now find EJ0_ itself + my $offset = $asl_to_aml_offset[$i]; + my $ej0 = aml_method_name($asl_lineno[$i], $offset); + # Verify AML: name must be EJ0_: + if (($aml[$ej0 + 0] != ord('E')) or + ($aml[$ej0 + 1] != ord('J')) or + ($aml[$ej0 + 2] != ord('0')) or + ($aml[$ej0 + 3] != ord('_'))) { + die "AML after input line $asl_lineno[$i] offset $ej0 " . + "does not match EJ0_"; + } + + # OK we are done. Output slot mask and offset + push @output, sprintf(" {.slot_mask = 0x%x, .offset = 0x%x}", + 0x1 << $slot, $ej0); +} + +# Pretty print output +if ($#output < 0) { + die "No EJ0_ Method found!" +} +print <