summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Hopf <mhopf@suse.de>2007-10-01 18:21:07 +0200
committerMatthias Hopf <mhopf@suse.de>2007-10-01 18:21:07 +0200
commit22cac9e70f576522cda040e262ee6f264764745f (patch)
tree7fc9ee2f3320adc96c2097251b41b0e895c8c74b
parent6cb3b9fbcb39aca139e0f5b1fca8a32b8148546e (diff)
Support for versioned data dumpers. Added address offsets to data dumpers.
-rw-r--r--datastructs.c98
-rw-r--r--datastructs.h6
-rw-r--r--datastructs_factory.pl23
-rw-r--r--main.c50
4 files changed, 135 insertions, 42 deletions
diff --git a/datastructs.c b/datastructs.c
index 10c8bb3..a33a42d 100644
--- a/datastructs.c
+++ b/datastructs.c
@@ -29,28 +29,86 @@ const char *space = " ";
#include "datastructs_gen.c"
#endif
-int (*data_dumpers[]) (uint8_t *data, int indent) = {
+typedef struct {
+ int id, vers, rev;
+ data_dumper_t *dumper;
+ const char *comment;
+} data_dumper_struct_t;
+
+data_dumper_struct_t data_dumpers[] = {
#ifdef USE_ATOMBIOS_RELATED_STUFF
- NULL, ATOM_MULTIMEDIA_CAPABILITY_INFO_dumper,
- ATOM_MULTIMEDIA_CONFIG_INFO_dumper, ATOM_STANDARD_VESA_TIMING_dumper,
- ATOM_FIRMWARE_INFO_dumper, ATOM_DAC_INFO_dumper, ATOM_LVDS_INFO_dumper,
- ATOM_TMDS_INFO_dumper, ATOM_ANALOG_TV_INFO_dumper,
- ATOM_SUPPORTED_DEVICES_INFO_dumper, ATOM_GPIO_I2C_INFO_dumper,
- ATOM_VRAM_USAGE_BY_FIRMWARE_dumper, ATOM_GPIO_PIN_LUT_dumper,
- ATOM_VESA_TO_INTENAL_MODE_LUT_dumper, // Typo
- ATOM_COMPONENT_VIDEO_INFO_dumper,
- ATOM_POWERPLAY_INFO_dumper, COMPASSIONATE_DATA_dumper,
- NULL /*ATOM_SAVE_RESTORE_INFO_dumper*/, NULL /*ATOM_PPLL_SS_INFO_dumper*/,
- ATOM_OEM_INFO_dumper, ATOM_XTMDS_INFO_dumper, NULL /*ATOM_MCLK_SS_INFO_dumper*/,
- ATOM_OBJECT_HEADER_dumper, INDIRECT_IO_ACCESS_dumper,
- NULL /*ATOM_MC_INIT_PARAMETER_dumper*/, NULL /*ATOM_ASIC_VDDC_INFO_dumper*/,
- ATOM_ASIC_INTERNAL_SS_INFO_dumper, NULL /*ATOM_TV_VIDEO_MODE_dumper*/,
- ATOM_VRAM_INFO_V3_dumper, ATOM_MEMORY_TRAINING_INFO_dumper,
- ATOM_INTEGRATED_SYSTEM_INFO_dumper, ATOM_ASIC_PROFILING_INFO_dumper,
- ATOM_VOLTAGE_OBJECT_INFO_dumper, ATOM_POWER_SOURCE_INFO_dumper
+ { 1, 0, 0, ATOM_MULTIMEDIA_CAPABILITY_INFO_dumper, NULL },
+ { 2, 0, 0, ATOM_MULTIMEDIA_CONFIG_INFO_dumper, NULL },
+ { 3, 0, 0, ATOM_STANDARD_VESA_TIMING_dumper, NULL },
+ { 4, 1, 1, ATOM_FIRMWARE_INFO_dumper, NULL },
+ { 4, 1, 2, ATOM_FIRMWARE_INFO_V1_2_dumper, NULL },
+ { 4, 1, 3, ATOM_FIRMWARE_INFO_V1_3_dumper, NULL },
+ { 4, 1, 4, ATOM_FIRMWARE_INFO_V1_4_dumper, NULL },
+ { 5, 0, 0, ATOM_DAC_INFO_dumper, NULL },
+ { 6, 1, 1, ATOM_LVDS_INFO_dumper, NULL },
+ { 6, 1, 2, ATOM_LVDS_INFO_V12_dumper, NULL },
+ { 7, 0, 0, ATOM_TMDS_INFO_dumper, NULL },
+ { 8, 0, 0, ATOM_ANALOG_TV_INFO_dumper, NULL },
+ { 9, 1, 0, ATOM_SUPPORTED_DEVICES_INFO_dumper, NULL },
+ { 9, 2, 0, ATOM_SUPPORTED_DEVICES_INFO_2_dumper, NULL },
+ { 9, 2, 1, ATOM_SUPPORTED_DEVICES_INFO_2d1_dumper, NULL },
+ { 10, 0, 0, ATOM_GPIO_I2C_INFO_dumper, NULL },
+ { 11, 0, 0, ATOM_VRAM_USAGE_BY_FIRMWARE_dumper, NULL },
+ { 12, 0, 0, ATOM_GPIO_PIN_LUT_dumper, NULL },
+ { 13, 0, 0, ATOM_VESA_TO_INTENAL_MODE_LUT_dumper /* Typo */, NULL },
+ { 14, 1, 0, ATOM_COMPONENT_VIDEO_INFO_dumper, NULL },
+ { 14, 2, 1, ATOM_COMPONENT_VIDEO_INFO_V21_dumper, NULL },
+ { 15, 1, 0, ATOM_POWERPLAY_INFO_dumper, NULL },
+ { 15, 2, 1, ATOM_POWERPLAY_INFO_V2_dumper, NULL },
+ { 15, 2, 2, ATOM_POWERPLAY_INFO_V3_dumper, NULL },
+ { 16, 0, 0, COMPASSIONATE_DATA_dumper, NULL },
+ { 17, 0, 0, NULL /*ATOM_SAVE_RESTORE_INFO_dumper*/, NULL },
+ { 18, 0, 0, NULL /*ATOM_PPLL_SS_INFO_dumper*/, NULL },
+ { 19, 0, 0, ATOM_OEM_INFO_dumper, NULL },
+ { 20, 0, 0, ATOM_XTMDS_INFO_dumper, NULL },
+ { 21, 0, 0, NULL /*ATOM_MCLK_SS_INFO_dumper*/, NULL },
+ { 22, 0, 0, ATOM_OBJECT_HEADER_dumper, NULL },
+ { 23, 0, 0, INDIRECT_IO_ACCESS_dumper, NULL },
+ { 24, 0, 0, NULL /*ATOM_MC_INIT_PARAMETER_dumper*/, NULL },
+ { 25, 0, 0, NULL /*ATOM_ASIC_VDDC_INFO_dumper*/, NULL },
+ { 26, 0, 0, ATOM_ASIC_INTERNAL_SS_INFO_dumper, NULL },
+ { 27, 0, 0, NULL /*ATOM_TV_VIDEO_MODE_dumper*/, NULL },
+ { 28, 1, 2, ATOM_VRAM_INFO_V2_dumper, "Completely untested" },
+ { 28, 1, 3, ATOM_VRAM_INFO_V3_dumper, "Apparently broken" },
+ { 29, 0, 0, ATOM_MEMORY_TRAINING_INFO_dumper, NULL },
+ { 30, 0, 1, ATOM_INTEGRATED_SYSTEM_INFO_dumper, NULL },
+ { 30, 0, 1, ATOM_INTEGRATED_SYSTEM_INFO_V2_dumper, NULL },
+ { 31, 0, 0, ATOM_ASIC_PROFILING_INFO_dumper, NULL },
+ { 32, 0, 0, ATOM_VOLTAGE_OBJECT_INFO_dumper, NULL },
+ { 33, 0, 0, ATOM_POWER_SOURCE_INFO_dumper, NULL },
+ { -1, 0, 0, NULL }
#endif
} ;
-int data_dumpers_sizeof (void) {
- return sizeof (data_dumpers) / sizeof (void *);
+void init_data_dumpers (void)
+{
+}
+
+data_dumper_t *get_data_dumper (int ind, int *version, int *revision,
+ const char **comment)
+{
+ data_dumper_struct_t *dt, *found = NULL;
+ for (dt = data_dumpers; dt->id >= 0 && dt->id <= ind; dt++) {
+ if (dt->id != ind)
+ continue;
+ if (dt->vers != *version && dt->vers > 0)
+ continue;
+ if (dt->rev > *revision)
+ continue;
+ found = dt;
+ }
+ if (found) {
+ *version = found->vers;
+ *revision = found->rev;
+ if (comment)
+ *comment = found->comment;
+ return found->dumper;
+ }
+ return NULL;
}
+
diff --git a/datastructs.h b/datastructs.h
index 1466ade..a4fa9c2 100644
--- a/datastructs.h
+++ b/datastructs.h
@@ -14,9 +14,11 @@
#define USE_ATOMBIOS_RELATED_STUFF
+typedef int data_dumper_t (uint8_t *start, uint8_t *data, int indent);
-extern int (*data_dumpers[]) (uint8_t *data, int indent);
+extern void init_data_dumpers (void);
-extern int data_dumpers_sizeof (void);
+extern data_dumper_t *get_data_dumper (int ind, int *version, int *revision,
+ const char **comment);
#endif
diff --git a/datastructs_factory.pl b/datastructs_factory.pl
index a2e55b1..b7ca8e9 100644
--- a/datastructs_factory.pl
+++ b/datastructs_factory.pl
@@ -16,8 +16,9 @@ while (<>) {
$l++;
if (/^\s*typedef\s+(struct|union)\s+_(\w+)/) {
$t = $1;
+ $tv= $t eq "union" ? "(union) " : "";
$s = $2;
- print "int ${s}_dumper (uint8_t *data, int indent) {\n";
+ print "int ${s}_dumper (uint8_t *start, uint8_t *data, int indent) {\n";
print " $s *d = ($s *) data;\n";
print " int i;\n";
print " if (d) {\n";
@@ -34,13 +35,23 @@ while (<>) {
$a = $6;
if ($a == 0) {
$loop_dst = "d->$n";
- $loop_beg = " printf (\"%s$e $n$b%s";
- $loop_arg = ", IND(indent), FILL(".length($e.$n.$b).")";
+ $loop_beg = " printf (\"%s";
+ $loop_beg.= "%04x: " if $b eq "";
+ $loop_beg.= " " if $b ne "";
+ $loop_beg.= "$tv$e $n$b%s";
+ $loop_arg = ", IND(indent)";
+ $loop_arg.= ", ((uint8_t*)&$loop_dst)-start" if $b eq "";
+ $loop_arg.= ", FILL(".length($tv.$e.$n.$b).")";
$loop_end = "";
} else {
$loop_dst = "d->${n}[i]";
- $loop_beg = " for (i = 0; i < $a; i++) {\n printf (\"%s$e $n$b%s [%d]";
- $loop_arg = ", IND(indent), FILL(".(length($e.$n.$b)+4)."+(i>9)), i";
+ $loop_beg = " for (i = 0; i < $a; i++) {\n printf (\"%s";
+ $loop_beg.= "%04x: " if $b eq "";
+ $loop_beg.= " " if $b ne "";
+ $loop_beg.= "$tv$e $n$b%s [%d]";
+ $loop_arg = ", IND(indent)";
+ $loop_arg.= ", ((uint8_t*)&$loop_dst)-start" if $b eq "";
+ $loop_arg.= ", FILL(".(length($tv.$e.$n.$b)+4)."+(i>9)), i";
$loop_end = " }";
}
if ($e eq "UCHAR") {
@@ -54,7 +65,7 @@ while (<>) {
print " printf (\"%s <unparsable> line $l: $_\\n%sskipping...\\n\", IND(indent), IND(indent));\n";
last;
} else {
- print "$loop_beg :\\n\"$loop_arg); ${e}_dumper ((uint8_t*) &$loop_dst, indent+1);$loop_end\n";
+ print "$loop_beg :\\n\"$loop_arg); ${e}_dumper (start, (uint8_t*) &$loop_dst, indent+1);$loop_end\n";
}
}
} else {
diff --git a/main.c b/main.c
index e096fda..cfc7e81 100644
--- a/main.c
+++ b/main.c
@@ -432,7 +432,6 @@ void do_list (bios_tables_t *tabs)
{
int i;
const char *ind;
- int dumpers_size = data_dumpers_sizeof();
fputs ("Command Tables:\n", stdout);
for (i = 0; i < sizeof (ATOM_MASTER_LIST_OF_COMMAND_TABLES) / sizeof (uint16_t); i++) {
@@ -448,16 +447,22 @@ void do_list (bios_tables_t *tabs)
}
fprintf (stdout, "\nData Tables:\n");
for (i = 0; i < sizeof (ATOM_MASTER_LIST_OF_DATA_TABLES) / sizeof (uint16_t); i++) {
- if (tabs->MasterDataTables[i])
- fprintf (stdout, " %04x: %04x Len %04x",
- i, tabs->MasterDataTables[i],
- * (uint16_t *) (tabs->base + tabs->MasterDataTables[i]));
- else
- fprintf (stdout, " %04x: - ", i);
+ data_dumper_t *dt = NULL;
+ const char *comment = NULL;
+ if (tabs->MasterDataTables[i]) {
+ uint8_t *data = tabs->base + tabs->MasterDataTables[i];
+ int frev = data[2];
+ int crev = data[3];
+ fprintf (stdout, " %04x: %04x Len %04x Rev %02x:%02x",
+ i, tabs->MasterDataTables[i], * (uint16_t *) data,
+ frev, crev);
+ dt = get_data_dumper (i, &frev, &crev, &comment);
+ } else
+ fprintf (stdout, " %04x: - ", i);
if ( (ind = get_index (INDEX_DATA_TABLE, i)) )
fprintf (stdout, " (%s)", ind);
- if (i >= 0 && i < dumpers_size && data_dumpers[i])
- fprintf (stdout, " (struct size %04x)", data_dumpers[i](NULL, 0));
+ if (dt)
+ fprintf (stdout, " (struct size %04x)", (*dt) (NULL, NULL, 0));
putc ('\n', stdout);
}
putc ('\n', stdout);
@@ -530,11 +535,24 @@ void do_dump (uint8_t *data, int start, int end)
void do_data (uint8_t *data, int off, int nr)
{
int len;
- int dumpers_size = data_dumpers_sizeof();
- if (nr >= 0 && nr < dumpers_size && data_dumpers[nr]) {
- len = data_dumpers[nr] (data+off, 1);
- fprintf (stdout, "\n Total data structure size: %04x\n\n", len);
- }
+ const char *comment = NULL;
+ int frev = data[off+2];
+ int crev = data[off+3];
+ data_dumper_t *dt = get_data_dumper (nr, &frev, &crev, &comment);
+
+ if (! dt)
+ return;
+ if (frev == 0)
+ fprintf (stdout, " NOTE: General revisionless dumper only.\n");
+ else if (frev != data[off+2] || crev != data[off+3])
+ fprintf (stdout, " NOTE: Dumper revision differs. "
+ "Used: Format Rev. %02x Content Rev. %02x\n", frev, crev);
+ if (comment)
+ fprintf (stdout, " NOTE: %s\n", comment);
+ if (frev == 0 || frev != data[off+2] || crev != data[off+3] || comment)
+ fputs ("\n", stdout);
+ len = (*dt) (data+off, data+off, 1);
+ fprintf (stdout, "\n Total data structure size: %04x\n\n", len);
}
void do_diss (uint8_t *data, int off, int size, const char *addrformat)
@@ -650,6 +668,8 @@ int main (int argc, char *argv[])
return 1;
}
+ init_data_dumpers ();
+
for (arg = &argv[optind+1]; *arg && **arg; arg++) {
last_reg_index = INDEX_NONE;
last_reg_offset = 0;
@@ -728,6 +748,7 @@ int main (int argc, char *argv[])
fputs (" *** Wrap around of table offset - multi-segment output not supported yet\n\n", stdout);
last = 0x1ffff;
}
+ fputs ("\n", stdout);
}
}
fputs ("\n*** Data Tables:\n\n", stdout);
@@ -746,6 +767,7 @@ int main (int argc, char *argv[])
fputs (" *** Wrap around of table offset - multi-segment output not supported yet\n\n", stdout);
last = 0x1ffff;
}
+ fputs ("\n", stdout);
}
}
break;