summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Hopf <mhopf@suse.de>2009-06-30 16:42:55 +0200
committerMatthias Hopf <mhopf@suse.de>2009-06-30 16:42:55 +0200
commitb8e5af57e1bb905d8bb9513be6532aeb0da33bf0 (patch)
treeb85ba83993d0ca532af8737a782c67e9e8d09c92
parentb8350b86a1ea6c39c6f5213a7956f3b459bcdefd (diff)
Add support for dynamically sized data structures. Describe using pragmas.
-rw-r--r--Makefile2
-rw-r--r--atombios_rev.h39
-rw-r--r--datastructs.c1
-rw-r--r--datastructs_factory.pl45
4 files changed, 68 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index 40fcd12..b1ed8d9 100644
--- a/Makefile
+++ b/Makefile
@@ -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";
+ }
}
}