diff options
author | Matthias Hopf <mhopf@suse.de> | 2009-06-30 16:42:55 +0200 |
---|---|---|
committer | Matthias Hopf <mhopf@suse.de> | 2009-06-30 16:42:55 +0200 |
commit | b8e5af57e1bb905d8bb9513be6532aeb0da33bf0 (patch) | |
tree | b85ba83993d0ca532af8737a782c67e9e8d09c92 | |
parent | b8350b86a1ea6c39c6f5213a7956f3b459bcdefd (diff) |
Add support for dynamically sized data structures. Describe using pragmas.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | atombios_rev.h | 39 | ||||
-rw-r--r-- | datastructs.c | 1 | ||||
-rw-r--r-- | datastructs_factory.pl | 45 |
4 files changed, 68 insertions, 19 deletions
@@ -12,7 +12,7 @@ atomdis: $(SRC:.c=.o) # Autogenerated files datastructs_gen.c: atombios.h atombios_rev.h datastructs_factory.pl - cat atombios.h atombios_rev.h | cpp | perl ./datastructs_factory.pl > datastructs_gen.c + cpp atombios_rev.h | perl ./datastructs_factory.pl > datastructs_gen.c # Clean diff --git a/atombios_rev.h b/atombios_rev.h index a86e8cb..5d1403e 100644 --- a/atombios_rev.h +++ b/atombios_rev.h @@ -1,15 +1,34 @@ /* * Reverse engineered AtomBIOS entries. + * Plus addon information for dynamic data tables. + */ + +/* + * Dynamic data tables: + * Modify table sizes and offset positions by replacing access code + * (e.g. &d->asPowerUnknownInfo[i]) by custom code. + * d is the current data structure, data as a char *, i is counter. + * + * #pragma count ATOM_POWERPLAY_INFO_V4 asPowerIndexInfo (d->NumPowerIndexEntries) + * #pragma offset ATOM_POWERPLAY_INFO_V4 asPowerIndexInfo (data + d->OffsetPowerIndexEntries + i*d->SizeOfPowerIndexEntry) + * #pragma return ATOM_POWERPLAY_INFO_V4 - (d->OffsetPowerUnknownEntries + ATOM_MAX_NUMBEROF_POWERUNKNOWN_BLOCK_V4*d->SizeOfPowerUnknownEntry) + * + * Has to be issued *before* the offset is encountered. And outside structures. */ typedef struct { unsigned char u[2]; } U16; +#define _U16(x) (((x).u[1]<<8)|(x).u[0]) + typedef struct { unsigned char u[3]; } U24; +#define _U24(x) (((x).u[2]<<16)|((x).u[1]<<8)|(x).u[0]) + +#include "atombios.h" //ucTableFormatRevision=4 //ucTableContentRevision=1 @@ -33,20 +52,20 @@ typedef struct _ATOM_POWERMODE_INFO_V4 typedef struct _ATOM_POWERUNKNOWN_INFO_V4 { - UCHAR unknown0; - UCHAR unknown1; - UCHAR unknown2; - UCHAR unknown3; - U16 unknown4; - U16 unknown6; - UCHAR unknown8; - UCHAR unknown9; - U16 unknown10; + UCHAR unknown[12]; }ATOM_POWERUNKNOWN_INFO_V4; #define ATOM_MAX_NUMBEROF_POWERMODE_BLOCK_V4 10 #define ATOM_MAX_NUMBEROF_POWERUNKNOWN_BLOCK_V4 4 +#pragma count ATOM_POWERPLAY_INFO_V4 asPowerIndexInfo (d->NumPowerIndexEntries) +#pragma offset ATOM_POWERPLAY_INFO_V4 asPowerIndexInfo *(data + _U16(d->OffsetPowerIndexEntries) + i*d->SizeOfPowerIndexEntry) +#pragma count ATOM_POWERPLAY_INFO_V4 asPowerModeInfo ((_U16(d->OffsetPowerUnknownEntries) - _U16(d->OffsetPowerModeEntries)) / d->SizeOfPowerModeEntry) +#pragma offset ATOM_POWERPLAY_INFO_V4 asPowerModeInfo *(data + _U16(d->OffsetPowerModeEntries) + i*d->SizeOfPowerModeEntry) +#pragma count ATOM_POWERPLAY_INFO_V4 asPowerUnknownInfo ((d->sHeader.usStructureSize - _U16(d->OffsetPowerUnknownEntries)) / d->SizeOfPowerUnknownEntry) +#pragma offset ATOM_POWERPLAY_INFO_V4 asPowerUnknownInfo *(data + _U16(d->OffsetPowerUnknownEntries) + i*d->SizeOfPowerUnknownEntry) +#pragma return ATOM_POWERPLAY_INFO_V4 - (_U16(d->OffsetPowerUnknownEntries) + ((d->sHeader.usStructureSize - _U16(d->OffsetPowerUnknownEntries)) / d->SizeOfPowerUnknownEntry)*d->SizeOfPowerUnknownEntry) + typedef struct _ATOM_POWERPLAY_INFO_V4 { ATOM_COMMON_TABLE_HEADER sHeader; @@ -68,3 +87,5 @@ typedef struct _ATOM_POWERPLAY_INFO_V4 ATOM_POWERMODE_INFO_V4 asPowerModeInfo[ATOM_MAX_NUMBEROF_POWERMODE_BLOCK_V4]; ATOM_POWERUNKNOWN_INFO_V4 asPowerUnknownInfo[ATOM_MAX_NUMBEROF_POWERUNKNOWN_BLOCK_V4]; }ATOM_POWERPLAY_INFO_V4; + + diff --git a/datastructs.c b/datastructs.c index fc2b759..9a3d5a0 100644 --- a/datastructs.c +++ b/datastructs.c @@ -16,7 +16,6 @@ #include "atombios_types.h" #ifdef USE_ATOMBIOS_RELATED_STUFF -# include "atombios.h" # include "atombios_rev.h" #endif diff --git a/datastructs_factory.pl b/datastructs_factory.pl index 3826efe..6d76e7d 100644 --- a/datastructs_factory.pl +++ b/datastructs_factory.pl @@ -15,7 +15,29 @@ while (<>) { $l++; - next if /^#/; + # #pragma count ATOM_POWERPLAY_INFO_V4 asPowerIndexInfo (d->NumPowerIndexEntries) + # #pragma offset ATOM_POWERPLAY_INFO_V4 asPowerIndexInfo (data + d->OffsetPowerIndexEntries + i*d->SizeOfPowerIndexEntry) + # #pragma return ATOM_POWERPLAY_INFO_V4 - (d->OffsetPowerUnknownEntries + ATOM_MAX_NUMBEROF_POWERUNKNOWN_BLOCK_V4*d->SizeOfPowerUnknownEntry) + if (/^\s*#\s*pragma\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*?)\s*$/) { + $t = $1; + $s = $2; + $v = $3; + $r = $4; + if ($t eq "count") { + ${$count{$s}}{$v} = $r; + next; + } elsif ($t eq "offset") { + ${$offset{$s}}{$v} = $r; + next; + } elsif ($t eq "return") { + $return{$s} = $r; + next; + } else { + chomp; + print STDERR "Unknown $_ in line $l\n"; + } + } + next if /^\s*#/; if (/^\s*typedef\s+(struct|union)\s+_(\w+)/) { $t = $1; $tv= $t eq "union" ? "(union) " : ""; @@ -49,9 +71,11 @@ while (<>) { $e = $1; $n = $2; $b = $4; - $a = $6; - if ($a == 0) { - $loop_dst = "d->$n"; + $a = ${$count{$s}}{$n}; + $a = $6 if $a eq ""; + if ($a eq "" || $a eq "0") { + $loop_dst = ${$offset{$s}}{$n}; + $loop_dst = "d->$n" if $loop_dst eq ""; $loop_beg = " printf (\"%s"; $loop_beg.= "%04x: " if $b eq ""; $loop_beg.= " " if $b ne ""; @@ -61,7 +85,8 @@ while (<>) { $loop_arg.= ", FILL(".length($tv.$e.$n.$b).")"; $loop_end = ""; } else { - $loop_dst = "d->${n}[i]"; + $loop_dst = ${$offset{$s}}{$n}; + $loop_dst = "d->${n}[i]" if $loop_dst eq ""; $loop_beg = " for (i = 0; i < $a; i++) {\n printf (\"%s"; $loop_beg.= "%04x: " if $b eq ""; $loop_beg.= " " if $b ne ""; @@ -76,9 +101,9 @@ while (<>) { } elsif ($e eq "USHORT") { print "$loop_beg = 0x%04x (%d)\\n\"$loop_arg, $loop_dst, $loop_dst);$loop_end\n"; } elsif ($e eq "U16") { - print "$loop_beg = 0x%04x (%d)\\n\"$loop_arg, ($loop_dst.u[0])|(($loop_dst.u[1])<<8), ($loop_dst.u[0])|(($loop_dst.u[1])<<8));$loop_end\n"; + print "$loop_beg = 0x%04x (%d)\\n\"$loop_arg, _U16($loop_dst), _U16($loop_dst));$loop_end\n"; } elsif ($e eq "U24") { - print "$loop_beg = 0x%06x (%d)\\n\"$loop_arg, ($loop_dst.u[0])|(($loop_dst.u[1])<<8)|(($loop_dst.u[2])<<16), ($loop_dst.u[0])|(($loop_dst.u[1])<<8)|(($loop_dst.u[2])<<16));$loop_end\n"; + print "$loop_beg = 0x%06x (%d)\\n\"$loop_arg, _U24($loop_dst), _U24($loop_dst));$loop_end\n"; } elsif ($e eq "ULONG") { print "$loop_beg = 0x%08x (%d)\\n\"$loop_arg, $loop_dst, $loop_dst);$loop_end\n"; } else { @@ -97,6 +122,10 @@ while (<>) { } } print " }\n"; - print " return sizeof ($s);\n}\n"; + if (defined $return{$s}) { + print " return ".$return{$s}.";\n}\n"; + } else { + print " return sizeof ($s);\n}\n"; + } } } |