intel_bios_reader: prepare for dumping all sections
authorJani Nikula <jani.nikula@intel.com>
Tue, 8 Oct 2013 18:15:27 +0000 (21:15 +0300)
committerRodrigo Vivi <rodrigo.vivi@gmail.com>
Mon, 21 Oct 2013 11:42:20 +0000 (09:42 -0200)
Dump sections through a table based on the section id.

Hex dump the section. This works also for unknown sections.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
tools/intel_bios_reader.c

index d30026e..30c3470 100644 (file)
@@ -70,6 +70,7 @@ struct bdb_block {
 };
 
 struct bdb_header *bdb;
+struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
 static int tv_present;
 static int lvds_present;
 static int panel_type;
@@ -115,19 +116,9 @@ static struct bdb_block *find_section(int section_id, int length)
        return NULL;
 }
 
-static void dump_general_features(int length)
+static void dump_general_features(const struct bdb_block *block)
 {
-       struct bdb_general_features *features;
-       struct bdb_block *block;
-
-       block = find_section(BDB_GENERAL_FEATURES, length);
-
-       if (!block)
-               return;
-
-       features = block->data;
-
-       printf("General features block:\n");
+       struct bdb_general_features *features = block->data;
 
        printf("\tPanel fitting: ");
        switch (features->panel_fitting) {
@@ -172,25 +163,13 @@ static void dump_general_features(int length)
 
        tv_present = 1;         /* should be based on whether TV DAC exists */
        lvds_present = 1;       /* should be based on IS_MOBILE() */
-
-       free(block);
 }
 
-static void dump_backlight_info(int length)
+static void dump_backlight_info(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct bdb_lvds_backlight *backlight;
+       struct bdb_lvds_backlight *backlight = block->data;
        struct blc_struct *blc;
 
-       block = find_section(BDB_LVDS_BACKLIGHT, length);
-
-       if (!block)
-               return;
-
-       backlight = block->data;
-
-       printf("Backlight info block (len %d):\n", block->size);
-
        if (sizeof(struct blc_struct) != backlight->blcstruct_size) {
                printf("\tBacklight struct sizes don't match (expected %zu, got %u), skipping\n",
                     sizeof(struct blc_struct), backlight->blcstruct_size);
@@ -345,23 +324,13 @@ static void dump_child_device(struct child_device_config *child)
        }
 }
 
-static void dump_general_definitions(int length)
+static void dump_general_definitions(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct bdb_general_definitions *defs;
+       struct bdb_general_definitions *defs = block->data;
        struct child_device_config *child;
        int i;
        int child_device_num;
 
-       block = find_section(BDB_GENERAL_DEFINITIONS, length);
-
-       if (!block)
-               return;
-
-       defs = block->data;
-
-       printf("General definitions block:\n");
-
        printf("\tCRT DDC GMBUS addr: 0x%02x\n", defs->crt_ddc_gmbus_pin);
        printf("\tUse ACPI DPMS CRT power states: %s\n",
               YESNO(defs->dpms_acpi));
@@ -374,25 +343,14 @@ static void dump_general_definitions(int length)
        child_device_num = (block->size - sizeof(*defs)) / sizeof(*child);
        for (i = 0; i < child_device_num; i++)
                dump_child_device(&defs->devices[i]);
-       free(block);
 }
 
-static void dump_child_devices(int length)
+static void dump_child_devices(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct bdb_child_devices *child_devs;
+       struct bdb_child_devices *child_devs = block->data;
        struct child_device_config *child;
        int i;
 
-       block = find_section(BDB_CHILD_DEVICE_TABLE, length);
-       if (!block) {
-               printf("No child device table found\n");
-               return;
-       }
-
-       child_devs = block->data;
-
-       printf("Child devices block:\n");
        for (i = 0; i < DEVICE_CHILD_SIZE; i++) {
                child = &child_devs->children[i];
                /* Skip nonexistent children */
@@ -408,24 +366,11 @@ static void dump_child_devices(int length)
                printf("\t\tDVO config: 0x%02x\n", child->dvo_cfg);
                printf("\t\tDVO wiring: 0x%02x\n", child->dvo_wiring);
        }
-
-       free(block);
 }
 
-static void dump_lvds_options(int length)
+static void dump_lvds_options(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct bdb_lvds_options *options;
-
-       block = find_section(BDB_LVDS_OPTIONS, length);
-       if (!block) {
-               printf("No LVDS options block\n");
-               return;
-       }
-
-       options = block->data;
-
-       printf("LVDS options block:\n");
+       struct bdb_lvds_options *options = block->data;
 
        panel_type = options->panel_type;
        printf("\tPanel type: %d\n", panel_type);
@@ -437,54 +382,22 @@ static void dump_lvds_options(int length)
        printf("\tPFIT enhanced text mode: %s\n",
               YESNO(options->pfit_text_mode_enhanced));
        printf("\tPFIT mode: %d\n", options->pfit_mode);
-
-       free(block);
 }
 
-static void dump_lvds_ptr_data(int length)
+static void dump_lvds_ptr_data(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct bdb_lvds_lfp_data *lvds_data;
-       struct bdb_lvds_lfp_data_ptrs *ptrs;
-       struct lvds_fp_timing *fp_timing;
-       struct bdb_lvds_lfp_data_entry *entry;
-       int lfp_data_size;
+       struct bdb_lvds_lfp_data_ptrs *ptrs = block->data;
 
-       block = find_section(BDB_LVDS_LFP_DATA_PTRS, length);
-       if (!block) {
-               printf("No LFP data pointers block\n");
-               return;
-       }
-       ptrs = block->data;
+       printf("\tNumber of entries: %d\n", ptrs->lvds_entries);
 
-       block = find_section(BDB_LVDS_LFP_DATA, length);
-       if (!block) {
-               printf("No LVDS data block\n");
-               return;
-       }
-       lvds_data = block->data;
-
-       lfp_data_size =
-           ptrs->ptr[1].fp_timing_offset - ptrs->ptr[0].fp_timing_offset;
-       entry =
-           (struct bdb_lvds_lfp_data_entry *)((uint8_t *) lvds_data->data +
-                                              (lfp_data_size * panel_type));
-       fp_timing = &entry->fp_timing;
-
-       printf("LVDS timing pointer data:\n");
-       printf("  Number of entries: %d\n", ptrs->lvds_entries);
-
-       printf("\tpanel type %02i: %dx%d\n", panel_type, fp_timing->x_res,
-              fp_timing->y_res);
-
-       free(block);
+       /* save for use by dump_lvds_data() */
+       lvds_lfp_data_ptrs = ptrs;
 }
 
-static void dump_lvds_data(int length)
+static void dump_lvds_data(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct bdb_lvds_lfp_data *lvds_data;
-       struct bdb_lvds_lfp_data_ptrs *ptrs;
+       struct bdb_lvds_lfp_data *lvds_data = block->data;
+       struct bdb_lvds_lfp_data_ptrs *ptrs = lvds_lfp_data_ptrs;
        int num_entries;
        int i;
        int hdisplay, hsyncstart, hsyncend, htotal;
@@ -492,29 +405,20 @@ static void dump_lvds_data(int length)
        float clock;
        int lfp_data_size, dvo_offset;
 
-       block = find_section(BDB_LVDS_LFP_DATA_PTRS, length);
-       if (!block) {
+       if (!ptrs) {
                printf("No LVDS ptr block\n");
                return;
        }
-       ptrs = block->data;
+
        lfp_data_size =
            ptrs->ptr[1].fp_timing_offset - ptrs->ptr[0].fp_timing_offset;
        dvo_offset =
            ptrs->ptr[0].dvo_timing_offset - ptrs->ptr[0].fp_timing_offset;
-       free(block);
 
-       block = find_section(BDB_LVDS_LFP_DATA, length);
-       if (!block) {
-               printf("No LVDS data block\n");
-               return;
-       }
-
-       lvds_data = block->data;
        num_entries = block->size / lfp_data_size;
 
-       printf("LVDS panel data block (preferred block marked with '*'):\n");
-       printf("  Number of entries: %d\n", num_entries);
+       printf("  Number of entries: %d (preferred block marked with '*')\n",
+              num_entries);
 
        for (i = 0; i < num_entries; i++) {
                uint8_t *lfp_data_ptr =
@@ -560,22 +464,12 @@ static void dump_lvds_data(int length)
                       (hsyncend > htotal || vsyncend > vtotal) ?
                       "BAD!" : "good");
        }
-       free(block);
 }
 
-static void dump_driver_feature(int length)
+static void dump_driver_feature(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct bdb_driver_feature *feature;
-
-       block = find_section(BDB_DRIVER_FEATURES, length);
-       if (!block) {
-               printf("No Driver feature data block\n");
-               return;
-       }
-       feature = block->data;
+       struct bdb_driver_feature *feature = block->data;
 
-       printf("Driver feature Data Block:\n");
        printf("\tBoot Device Algorithm: %s\n", feature->boot_dev_algorithm ?
               "driver default" : "os default");
        printf("\tBlock display switching when DVD active: %s\n",
@@ -636,23 +530,14 @@ static void dump_driver_feature(int length)
        printf("\tLegacy CRT max Y: %d\n", feature->legacy_crt_max_y);
        printf("\tLegacy CRT max refresh: %d\n",
               feature->legacy_crt_max_refresh);
-       free(block);
 }
 
-static void dump_edp(int length)
+static void dump_edp(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct bdb_edp *edp;
+       struct bdb_edp *edp = block->data;
        int bpp;
 
-       block = find_section(BDB_EDP, length);
-       if (!block) {
-               printf("No EDP data block\n");
-               return;
-       }
-       edp = block->data;
-
-       printf("eDP block: type %d\n", panel_type);
+       printf("\tPanel type %d\n", panel_type);
        printf("\tPower Sequence: T3 %d T7 %d T9 %d T10 %d T12 %d\n",
                edp->power_seqs[panel_type].t3,
                edp->power_seqs[panel_type].t7,
@@ -674,6 +559,7 @@ static void dump_edp(int length)
                printf("30bpp\n");
                break;
        }
+
        printf("\teDP sDRRs MSA timing delay: %d\n", edp->sdrrs_msa_timing_delay);
        printf("\tLink params:\n");
        printf("\t\trate: ");
@@ -723,7 +609,6 @@ static void dump_edp(int length)
                printf("1.2V\n");
                break;
        }
-       free(block);
 }
 
 static void
@@ -755,43 +640,22 @@ print_detail_timing_data(struct lvds_dvo_timing2 *dvo_timing)
        printf("\tclock: %d\n", dvo_timing->clock * 10);
 }
 
-static void dump_sdvo_panel_dtds(int length)
+static void dump_sdvo_panel_dtds(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct lvds_dvo_timing2 *dvo_timing;
+       struct lvds_dvo_timing2 *dvo_timing = block->data;
        int n, count;
 
-       block = find_section(BDB_SDVO_PANEL_DTDS, length);
-       if (!block) {
-               printf("No SDVO panel dtds block\n");
-               return;
-       }
-
-       printf("SDVO panel dtds:\n");
        count = block->size / sizeof(struct lvds_dvo_timing2);
-       dvo_timing = block->data;
        for (n = 0; n < count; n++) {
                printf("%d:\n", n);
                print_detail_timing_data(dvo_timing++);
        }
-
-       free(block);
 }
 
-static void dump_sdvo_lvds_options(int length)
+static void dump_sdvo_lvds_options(const struct bdb_block *block)
 {
-       struct bdb_block *block;
-       struct bdb_sdvo_lvds_options *options;
+       struct bdb_sdvo_lvds_options *options = block->data;
 
-       block = find_section(BDB_SDVO_LVDS_OPTIONS, length);
-       if (!block) {
-               printf("No SDVO LVDS options block\n");
-               return;
-       }
-
-       options = block->data;
-
-       printf("SDVO LVDS options block:\n");
        printf("\tbacklight: %d\n", options->panel_backlight);
        printf("\th40 type: %d\n", options->h40_set_panel_type);
        printf("\ttype: %d\n", options->panel_type);
@@ -807,8 +671,6 @@ static void dump_sdvo_lvds_options(int length)
        printf("\tmisc[1]: %x\n", options->panel_misc_bits_2);
        printf("\tmisc[2]: %x\n", options->panel_misc_bits_3);
        printf("\tmisc[3]: %x\n", options->panel_misc_bits_4);
-
-       free(block);
 }
 
 static int
@@ -828,6 +690,121 @@ get_device_id(unsigned char *bios)
     return device;
 }
 
+struct dumper {
+       uint8_t id;
+       const char *name;
+       void (*dump)(const struct bdb_block *block);
+};
+
+struct dumper dumpers[] = {
+       {
+               .id = BDB_GENERAL_FEATURES,
+               .name = "General features block",
+               .dump = dump_general_features,
+       },
+       {
+               .id = BDB_GENERAL_DEFINITIONS,
+               .name = "General definitions block",
+               .dump = dump_general_definitions,
+       },
+       {
+               .id = BDB_CHILD_DEVICE_TABLE,
+               .name = "Child devices block",
+               .dump = dump_child_devices,
+       },
+       {
+               .id = BDB_LVDS_OPTIONS,
+               .name = "LVDS options block",
+               .dump = dump_lvds_options,
+       },
+       {
+               .id = BDB_LVDS_LFP_DATA_PTRS,
+               .name = "LVDS timing pointer data",
+               .dump = dump_lvds_ptr_data,
+       },
+       {
+               .id = BDB_LVDS_LFP_DATA,
+               .name = "LVDS panel data block",
+               .dump = dump_lvds_data,
+       },
+       {
+               .id = BDB_LVDS_BACKLIGHT,
+               .name = "Backlight info block",
+               .dump = dump_backlight_info,
+       },
+       {
+               .id = BDB_SDVO_LVDS_OPTIONS,
+               .name = "SDVO LVDS options block",
+               .dump = dump_sdvo_lvds_options,
+       },
+       {
+               .id = BDB_SDVO_PANEL_DTDS,
+               .name = "SDVO panel dtds",
+               .dump = dump_sdvo_panel_dtds,
+       },
+       {
+               .id = BDB_DRIVER_FEATURES,
+               .name = "Driver feature data block",
+               .dump = dump_driver_feature,
+       },
+       {
+               .id = BDB_EDP,
+               .name = "eDP block",
+               .dump = dump_edp,
+       },
+};
+
+static void hex_dump(const struct bdb_block *block)
+{
+       int i;
+       uint8_t *p = block->data;
+
+       for (i = 0; i < block->size; i++) {
+               if (i % 16 == 0)
+                       printf("\t%04x: ", i);
+               printf("%02x", p[i]);
+               if (i % 16 == 15) {
+                       if (i + 1 < block->size)
+                               printf("\n");
+               } else if (i % 8 == 7) {
+                       printf("  ");
+               } else {
+                       printf(" ");
+               }
+       }
+       printf("\n\n");
+}
+
+static void dump_section(int section_id, int size)
+{
+       struct dumper *dumper = NULL;
+       const struct bdb_block *block;
+       int i;
+
+       block = find_section(section_id, size);
+       if (!block) {
+               printf("No section %d\n", section_id);
+               return;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(dumpers); i++) {
+               if (block->id == dumpers[i].id) {
+                       dumper = &dumpers[i];
+                       break;
+               }
+       }
+
+       if (dumper && dumper->name)
+               printf("BDB block %d - %s:\n", block->id, dumper->name);
+       else
+               printf("BDB block %d:\n", block->id);
+
+       hex_dump(block);
+       if (dumper && dumper->dump)
+               dumper->dump(block);
+       printf("\n");
+}
+
 int main(int argc, char **argv)
 {
        int fd;
@@ -917,6 +894,7 @@ int main(int argc, char **argv)
        printf("BDB vers: %d\n", bdb->version);
 
        printf("Available sections: ");
+
        for (i = 0; i < 256; i++) {
                block = find_section(i, size);
                if (!block)
@@ -931,19 +909,19 @@ int main(int argc, char **argv)
        if (devid == -1)
            printf("Warning: could not find PCI device ID!\n");
 
-       dump_general_features(size);
-       dump_general_definitions(size);
-       dump_child_devices(size);
-       dump_lvds_options(size);
-       dump_lvds_data(size);
-       dump_lvds_ptr_data(size);
-       dump_backlight_info(size);
+       dump_section(BDB_GENERAL_FEATURES, size);
+       dump_section(BDB_GENERAL_DEFINITIONS, size);
+       dump_section(BDB_CHILD_DEVICE_TABLE, size);
+       dump_section(BDB_LVDS_OPTIONS, size);
+       dump_section(BDB_LVDS_LFP_DATA_PTRS, size);
+       dump_section(BDB_LVDS_LFP_DATA, size);
+       dump_section(BDB_LVDS_BACKLIGHT, size);
 
-       dump_sdvo_lvds_options(size);
-       dump_sdvo_panel_dtds(size);
+       dump_section(BDB_SDVO_LVDS_OPTIONS, size);
+       dump_section(BDB_SDVO_PANEL_DTDS, size);
 
-       dump_driver_feature(size);
-       dump_edp(size);
+       dump_section(BDB_DRIVER_FEATURES, size);
+       dump_section(BDB_EDP, size);
 
        return 0;
 }