[SeaBIOS] [PATCH 2/4] acpi: add aml/asl parsing script
Michael S. Tsirkin
mst at redhat.com
Wed Sep 21 14:44:29 CEST 2011
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 <mst at redhat.com>
---
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<address>)
+ 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 <<EOF;
+static struct aml_ej0_data {
+ unsigned slot_mask;
+ unsigned offset;
+} aml_ej0_data[] = {
+EOF
+print join(",\n", @output);
+print <<EOF;
+
+};
+EOF
+
--
1.7.5.53.gc233e
More information about the SeaBIOS
mailing list