coreboot-kgpe-d16/util/intelvbttool/intelvbttool.c
Patrick Georgi a73b93157f tree: drop last paragraph of GPL copyright header
It encourages users from writing to the FSF without giving an address.
Linux also prefers to drop that and their checkpatch.pl (that we
imported) looks out for that.

This is the result of util/scripts/no-fsf-addresses.sh with no further
editing.

Change-Id: Ie96faea295fe001911d77dbc51e9a6789558fbd6
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/11888
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2015-10-31 21:37:39 +01:00

532 lines
14 KiB
C

/*
* Copyright (C) 2014 Vladimir Serbinenko
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#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;
int ndev;
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);
ndev = (secsz - sizeof(*sec)) /
sizeof(struct common_child_dev_config);
printf("\t%d devices\n", ndev);
for (i = 0; i < ndev; 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;
}