[coreboot-gerrit] New patch to review for coreboot: 66f97c2 NOTFORMERGE: WIP VBT pasrser.

Vladimir Serbinenko (phcoder@gmail.com) gerrit at coreboot.org
Sat May 24 16:34:50 CEST 2014


Vladimir Serbinenko (phcoder at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5842

-gerrit

commit 66f97c28f4003d7bc7e29703d045068d40e4af5b
Author: Vladimir Serbinenko <phcoder at gmail.com>
Date:   Sat May 24 16:34:29 2014 +0200

    NOTFORMERGE: WIP VBT pasrser.
    
    Change-Id: I32f6505dbf683478bf5a25b73db7ab0c60eff29c
    Signed-off-by: Vladimir Serbinenko <phcoder at gmail.com>
---
 util/intelvbttool/intelvbttool.c | 441 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 441 insertions(+)

diff --git a/util/intelvbttool/intelvbttool.c b/util/intelvbttool/intelvbttool.c
new file mode 100644
index 0000000..3ac2fd7
--- /dev/null
+++ b/util/intelvbttool/intelvbttool.c
@@ -0,0 +1,441 @@
+#include <stdio.h>
+#include <sys/mman.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+
+
+typedef struct {
+	u16	signature;
+	u8	size;
+	u8	reserved[21];
+	u16	pcir_offset;
+	u16	vbt_offset;
+} __attribute__((packed)) optionrom_header_t;
+
+struct vbt_header {
+	u8 signature[20];
+	u16 version;
+	u16 header_size;
+	u16 vbt_size;
+	u8 vbt_checksum;
+	u8 reserved0;
+	u32 bdb_offset;
+	u32 aim_offset[4];
+} __attribute__((packed));
+
+struct bdb_header {
+	u8 signature[16];
+	u16 version;
+	u16 header_size;
+	u16 bdb_size;
+};
+
+struct vbios_data {
+	u8 type; /* 0 == desktop, 1 == mobile */
+	u8 relstage;
+	u8 chipset;
+	u8 lvds_present:1;
+	u8 tv_present:1;
+	u8 rsvd2:6; /* finish byte */
+	u8 rsvd3[4];
+	u8 signon[155];
+	u8 copyright[61];
+	u16 code_segment;
+	u8 dos_boot_mode;
+	u8 bandwidth_percent;
+	u8 rsvd4; /* popup memory size */
+	u8 resize_pci_bios;
+	u8 rsvd5; /* is crt already on ddc2 */
+} __attribute__((packed));
+
+struct bdb_general_features {
+        /* bits 1 */
+	u8 panel_fitting:2;
+	u8 flexaim:1;
+	u8 msg_enable:1;
+	u8 clear_screen:3;
+	u8 color_flip:1;
+
+        /* bits 2 */
+	u8 download_ext_vbt:1;
+	u8 enable_ssc:1;
+	u8 ssc_freq:1;
+	u8 enable_lfp_on_override:1;
+	u8 disable_ssc_ddt:1;
+	u8 rsvd7:1;
+	u8 display_clock_mode:1;
+	u8 rsvd8:1; /* finish byte */
+
+        /* bits 3 */
+	u8 disable_smooth_vision:1;
+	u8 single_dvi:1;
+	u8 rsvd9:1;
+	u8 fdi_rx_polarity_inverted:1;
+	u8 rsvd10:4; /* finish byte */
+
+        /* bits 4 */
+	u8 legacy_monitor_detect;
+
+        /* bits 5 */
+	u8 int_crt_support:1;
+	u8 int_tv_support:1;
+	u8 int_efp_support:1;
+	u8 dp_ssc_enb:1;	/* PCH attached eDP supports SSC */
+	u8 dp_ssc_freq:1;	/* SSC freq for PCH attached eDP */
+	u8 rsvd11:3; /* finish byte */
+} __attribute__((packed));
+
+struct common_child_dev_config {
+	u16 handle;
+	u16 device_type;
+	u8 not_common1[12];
+	u8 dvo_port;
+	u8 i2c_pin;
+	u8 slave_addr;
+	u8 ddc_pin;
+	u16 edid_ptr;
+	u8 not_common3[6];
+	u8  dvo_wiring;
+	u8 not_common4[4];
+} __attribute__((packed));
+
+struct bdb_general_definitions {
+	/* DDC GPIO */
+	u8 crt_ddc_gmbus_pin;
+
+	/* DPMS bits */
+	u8 dpms_acpi:1;
+	u8 skip_boot_crt_detect:1;
+	u8 dpms_aim:1;
+	u8 rsvd1:5; /* finish byte */
+
+	/* boot device bits */
+	u8 boot_display[2];
+	u8 child_dev_size;
+
+	/*
+	 * Device info:
+	 * If TV is present, it'll be at devices[0].
+	 * LVDS will be next, either devices[0] or [1], if present.
+	 * On some platforms the number of device is 6. But could be as few as
+	 * 4 if both TV and LVDS are missing.
+	 * And the device num is related with the size of general definition
+	 * block. It is obtained by using the following formula:
+	 * number = (block_size - sizeof(bdb_general_definitions))/
+	 *	     sizeof(child_device_config);
+	 */
+	struct common_child_dev_config devices[0];
+} __attribute__((packed));
+
+struct bdb_driver_features {
+	u8 boot_dev_algorithm:1;
+	u8 block_display_switch:1;
+	u8 allow_display_switch:1;
+	u8 hotplug_dvo:1;
+	u8 dual_view_zoom:1;
+	u8 int15h_hook:1;
+	u8 sprite_in_clone:1;
+	u8 primary_lfp_id:1;
+
+	u16 boot_mode_x;
+	u16 boot_mode_y;
+	u8 boot_mode_bpp;
+	u8 boot_mode_refresh;
+
+	u16 enable_lfp_primary:1;
+	u16 selective_mode_pruning:1;
+	u16 dual_frequency:1;
+	u16 render_clock_freq:1; /* 0: high freq; 1: low freq */
+	u16 nt_clone_support:1;
+	u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */
+	u16 sprite_display_assign:1; /* 0: secondary; 1: primary */
+	u16 cui_aspect_scaling:1;
+	u16 preserve_aspect_ratio:1;
+	u16 sdvo_device_power_down:1;
+	u16 crt_hotplug:1;
+	u16 lvds_config:2;
+	u16 tv_hotplug:1;
+	u16 hdmi_config:2;
+
+	u8 static_display:1;
+	u8 reserved2:7;
+	u16 legacy_crt_max_x;
+	u16 legacy_crt_max_y;
+	u8 legacy_crt_max_refresh;
+
+	u8 hdmi_termination;
+	u8 custom_vbt_version;
+} __attribute__((packed));
+
+struct bdb_lvds_options {
+	u8 panel_type;
+	u8 rsvd1;
+	/* LVDS capabilities, stored in a dword */
+	u8 pfit_mode:2;
+	u8 pfit_text_mode_enhanced:1;
+	u8 pfit_gfx_mode_enhanced:1;
+	u8 pfit_ratio_auto:1;
+	u8 pixel_dither:1;
+	u8 lvds_edid:1;
+	u8 rsvd2:1;
+	u8 rsvd4;
+} __attribute__((packed));
+
+struct bdb_sdvo_lvds_options {
+	u8 panel_backlight;
+	u8 h40_set_panel_type;
+	u8 panel_type;
+	u8 ssc_clk_freq;
+	u16 als_low_trip;
+	u16 als_high_trip;
+	u8 sclalarcoeff_tab_row_num;
+	u8 sclalarcoeff_tab_row_size;
+	u8 coefficient[8];
+	u8 panel_misc_bits_1;
+	u8 panel_misc_bits_2;
+	u8 panel_misc_bits_3;
+	u8 panel_misc_bits_4;
+} __attribute__((packed));
+
+
+#define BDB_GENERAL_FEATURES	  1
+#define BDB_GENERAL_DEFINITIONS	  2
+
+#define BDB_DRIVER_FEATURES	 12
+#define BDB_SDVO_LVDS_OPTIONS	 22
+#define BDB_SDVO_PANEL_DTDS	 23
+#define BDB_LVDS_OPTIONS	 40
+#define BDB_LVDS_LFP_DATA_PTRS	 41
+#define BDB_LVDS_LFP_DATA	 42
+
+#define BDB_SKIP		254
+
+static void parse_vbt(const void *vbt)
+{
+	const struct vbt_header *head = vbt;
+	const struct bdb_header *bdb;
+	int i;
+	const u8 *ptr;
+	int is_first_skip = 1;
+
+	if (memcmp(head->signature, "$VBT", 4) != 0) {
+		fprintf (stderr, "invalid VBT signature\n");
+		exit(1);
+	}
+	printf ("signature: <%20.20s>\n", head->signature);
+	printf ("version: %d.%02d\n", head->version / 100,
+		head->version % 100);
+	if (head->header_size != sizeof (struct vbt_header))
+		printf ("header size: 0x%x\n", head->header_size);
+	printf ("VBT size: 0x%x\n", head->vbt_size);
+	printf ("VBT checksum: 0x%x\n", head->vbt_checksum);
+	if (head->reserved0)
+		printf ("header reserved0: 0x%x\n", head->reserved0);
+	if (head->bdb_offset != sizeof (struct vbt_header))
+		printf ("BDB offset: 0x%x\n", head->bdb_offset);
+
+	for (i = 0; i < 4; i++)
+		if (head->aim_offset[i])
+			printf ("AIM[%d] offset: 0x%x\n", i,
+				head->aim_offset[i]);
+	bdb = (const void *) ((const char *) vbt + head->bdb_offset);
+
+	if (memcmp ("BIOS_DATA_BLOCK ", bdb->signature, 16) != 0) {
+		fprintf(stderr, "invalid BDB signature:%s\n",
+			bdb->signature);
+		exit (1);
+	}
+	printf ("BDB version: %d.%02d\n", bdb->version / 100,
+		bdb->version % 100);
+	if (bdb->header_size != sizeof (struct bdb_header))
+		printf ("BDB header size: 0x%x\n", bdb->header_size);
+	if (bdb->bdb_size != head->vbt_size - head->bdb_offset)
+		printf ("BDB size: 0x%x\n", bdb->bdb_size);
+	for (ptr = (const u8 *) bdb + bdb->header_size;
+	     ptr < (const u8 *) bdb + bdb->bdb_size;) {
+		u16 secsz = (ptr[1] | (ptr[2] << 8));
+		u8 sectype = ptr[0];
+		const u8 *section = ptr + 3;
+		
+		printf ("section type %d, size 0x%x\n", sectype, secsz);
+		ptr += secsz + 3;
+		switch(sectype)
+		{
+		case BDB_GENERAL_FEATURES: {
+			const struct bdb_general_features *sec = (const void *) section;
+			printf ("General features:\n");
+
+			if(sec->panel_fitting) printf("\tpanel_fitting = 0x%x\n", sec->panel_fitting);
+			if(sec->flexaim) printf("\tflexaim = 0x%x\n", sec->flexaim);
+			if(sec->msg_enable) printf("\tmsg_enable = 0x%x\n", sec->msg_enable);
+			if(sec->clear_screen) printf("\tclear_screen = 0x%x\n", sec->clear_screen);
+			if(sec->color_flip) printf("\tcolor_flip = 0x%x\n", sec->color_flip);
+			if(sec->download_ext_vbt) printf("\tdownload_ext_vbt = 0x%x\n", sec->download_ext_vbt);
+			printf("\t*enable_ssc = 0x%x\n", sec->enable_ssc);
+			printf("\t*ssc_freq = 0x%x\n", sec->ssc_freq);
+			if(sec->enable_lfp_on_override) printf("\tenable_lfp_on_override = 0x%x\n", sec->enable_lfp_on_override);
+			if(sec->disable_ssc_ddt) printf("\tdisable_ssc_ddt = 0x%x\n", sec->disable_ssc_ddt);
+			if(sec->rsvd7) printf("\trsvd7 = 0x%x\n", sec->rsvd7);
+			printf("\t*display_clock_mode = 0x%x\n", sec->display_clock_mode);
+			if(sec->rsvd8) printf("\trsvd8 = 0x%x\n", sec->rsvd8);
+			printf("\tdisable_smooth_vision = 0x%x\n", sec->disable_smooth_vision);
+			if(sec->single_dvi) printf("\tsingle_dvi = 0x%x\n", sec->single_dvi);
+			if(sec->rsvd9) printf("\trsvd9 = 0x%x\n", sec->rsvd9);
+			printf("\t*fdi_rx_polarity_inverted = 0x%x\n", sec->fdi_rx_polarity_inverted);
+			if(sec->rsvd10) printf("\trsvd10 = 0x%x\n", sec->rsvd10);
+			if(sec->legacy_monitor_detect) printf("\tlegacy_monitor_detect = 0x%x\n", sec->legacy_monitor_detect);
+			printf("\t*int_crt_support = 0x%x\n", sec->int_crt_support);
+			printf("\t*int_tv_support = 0x%x\n", sec->int_tv_support);
+			if(sec->int_efp_support) printf("\tint_efp_support = 0x%x\n", sec->int_efp_support);
+			if(sec->dp_ssc_enb) printf("\tdp_ssc_enb = 0x%x\n", sec->dp_ssc_enb);
+			if(sec->dp_ssc_freq) printf("\tdp_ssc_freq = 0x%x\n", sec->dp_ssc_freq);
+			if(sec->rsvd11) printf("\trsvd11 = 0x%x\n", sec->rsvd11);
+			break;
+		}
+		case BDB_DRIVER_FEATURES: {
+			const struct bdb_driver_features *sec = (const void *) section;
+			printf("\t*LVDS config: %d\n", sec->lvds_config);
+			printf("\t*Dual frequency: %d\n", sec->dual_frequency);
+
+			break;
+		}
+		case BDB_SDVO_LVDS_OPTIONS: {
+			const struct bdb_sdvo_lvds_options *sec = (const void *) section;
+			printf("\t*Panel type: %d\n", sec->panel_type);
+
+			break;
+		}
+		case BDB_GENERAL_DEFINITIONS: {
+			const struct bdb_general_definitions *sec = (const void *) section;
+			printf("\t*CRT DDC GMBUS pin: %d\n", sec->crt_ddc_gmbus_pin);
+
+			printf("\tDPMS ACPI: %d\n", sec->dpms_acpi);
+			printf("\tSkip boot CRT detect: %d\n",
+			       sec->skip_boot_crt_detect);
+			printf("\tDPMS aim: %d\n",
+			       sec->dpms_aim);
+			if(sec->rsvd1)
+				printf("\trsvd1: 0x%x\n", sec->rsvd1);
+			printf("\tboot_display: { %x, %x }\n",
+			       sec->boot_display[0], sec->boot_display[1]);
+			if (sec->child_dev_size != sizeof(struct common_child_dev_config))
+				printf("\tchild_dev_size: %d\n",
+				       sec->child_dev_size);
+			printf("\t%d devices\n", (secsz - sizeof (*sec)) / sizeof(struct common_child_dev_config));
+			for (i = 0; i < (secsz - sizeof (*sec)) / sizeof(struct common_child_dev_config); i++) {
+				printf ("\t*device type: %x ",
+					sec->devices[i].device_type);
+#define	 DEVICE_TYPE_INT_LFP	0x1022
+#define	 DEVICE_TYPE_INT_TV	0x1009
+#define DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR	0x6052
+				switch (sec->devices[i].device_type) {
+				case DEVICE_TYPE_INT_LFP:
+					printf("(flat panel)\n");
+					break;
+				case DEVICE_TYPE_INT_TV:
+					printf("(TV)\n");
+					break;
+				case DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR:
+					printf("(DVI)\n");
+					break;
+				case 0:
+					printf("(Empty)\n");
+					break;
+				default:
+					printf("(Unknown)\n");
+					break;
+				}
+				if (!sec->devices[i].device_type)
+					continue;
+				printf ("\t *dvo_port: %x\n", sec->devices[i].dvo_port);
+				printf ("\t *i2c_pin: %x\n", sec->devices[i].i2c_pin);
+				printf ("\t *slave_addr: %x\n", sec->devices[i].slave_addr);
+				printf ("\t *ddc_pin: %x\n", sec->devices[i].ddc_pin);
+				printf ("\t *dvo_wiring: %x\n", sec->devices[i].dvo_wiring);
+				printf ("\t edid_ptr: %x\n", sec->devices[i].edid_ptr);
+			}
+
+			break;
+		}
+		case BDB_SKIP: {
+			const struct vbios_data *sec = (const void *) section;
+			if (!is_first_skip)
+				break;
+			is_first_skip = 0;
+			printf("\ttype: %x\n", sec->type);
+			printf("\trelstage: %x\n", sec->relstage);
+			printf("\tchipset: %x\n", sec->chipset);
+			printf(sec->lvds_present ? "\tLVDS\n"
+			       : "\tNo LVDS\n");
+			printf(sec->tv_present ? "\tTV\n"
+			       : "\tNo TV\n");
+			if (sec->rsvd2)
+				printf("\trsvd2: 0x%x\n", sec->rsvd2);
+			for (i = 0; i < 4; i++)
+				if (sec->rsvd3[i])
+					printf("\trsvd3[%d]: 0x%x\n", i,
+					       sec->rsvd3[i]);
+			printf("\tSignon: %.155s\n", sec->signon);
+			printf("\tCopyright: %.155s\n", sec->copyright);
+			printf("\tCode segment: %x\n", sec->code_segment);
+			printf("\tDOS Boot mode: %x\n", sec->dos_boot_mode);
+			printf("\tBandwidth percent: %x\n",
+			       sec->bandwidth_percent);
+			if (sec->rsvd4)
+				printf("\trsvd4: 0x%x\n", sec->rsvd4);
+			printf("\tBandwidth percent: %x\n",
+			       sec->resize_pci_bios);
+			if (sec->rsvd5)
+				printf("\trsvd5: 0x%x\n", sec->rsvd5);
+			break;
+		}
+		}
+	}
+		     
+}
+
+static void parse_vbios(const void *ptr)
+{
+	const optionrom_header_t *oh;
+	oh = ptr;
+	if (oh->signature != 0xaa55) {
+		fprintf(stderr, "bad oprom signature: %x\n", oh->signature);
+		return;
+	}
+	if (!oh->vbt_offset) {
+		fprintf(stderr, "no VBT found\n");
+		return;
+	}
+	parse_vbt((const char *) ptr + oh->vbt_offset);
+}
+
+int
+main (int argc, char **argv)
+{
+	const void *ptr;
+	int fd;
+	if (argc == 2) {
+		fd = open(argv[1], O_RDONLY);
+		ptr = mmap(0, 65536, PROT_READ, MAP_SHARED, fd, 0);
+	} else {
+		fd = open("/dev/mem", O_RDONLY);
+		ptr = mmap(0, 65536, PROT_READ, MAP_SHARED, fd, 0xc0000);
+	}
+	if (ptr == MAP_FAILED) {
+		fprintf (stderr, "mmap failed: %s\n", strerror (errno));
+		return 1;
+	}
+	parse_vbios(ptr);
+	close (fd);
+	return 0;
+}



More information about the coreboot-gerrit mailing list