diff options
author | Keith Packard <keithp@dulcimer.keithp.com> | 2007-05-16 13:59:36 -0700 |
---|---|---|
committer | Keith Packard <keithp@dulcimer.keithp.com> | 2007-05-16 13:59:36 -0700 |
commit | b28817a87a1608e849e4a9a736dda43533a84b0c (patch) | |
tree | cd81b1f0a3607da52b0643054c3ebe1d07f91780 | |
parent | b31bef1a8effa9acb6de7edd206b9d8c48d88144 (diff) |
Add i830_bios_get_aim_data_block to read AIM data from BIOS
Add-in modules have per-module data in the BIOS which contains configuration
information which cannot be entirely discovered.
-rw-r--r-- | src/bios_reader/bios_reader.c | 9 | ||||
-rw-r--r-- | src/i830_bios.c | 59 | ||||
-rw-r--r-- | src/i830_bios.h | 52 |
3 files changed, 104 insertions, 16 deletions
diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c index a52bcc72..9ec73c13 100644 --- a/src/bios_reader/bios_reader.c +++ b/src/bios_reader/bios_reader.c @@ -30,16 +30,11 @@ #include <string.h> #include <sys/types.h> +#include "../i830_bios.h" + #define _PARSE_EDID_ #include "edid.h" -/* Define some types so we can reuse i830_bios.h */ -typedef void *ScrnInfoPtr; -typedef int Bool; -#define TRUE 1 -#define FALSE 0 -#include "../i830_bios.h" - /* Make a fake pI830 so we can easily pull i830_bios.c code in here. */ struct _fake_i830 { diff --git a/src/i830_bios.c b/src/i830_bios.c index 0d009175..7703c806 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -77,8 +77,8 @@ i830DumpBIOSToFile(ScrnInfoPtr pScrn, unsigned char *bios) * feed an updated VBT back through that, compared to what we'll fetch using * this method of groping around in the BIOS data. */ -static unsigned char * -i830GetBIOS(ScrnInfoPtr pScrn) +unsigned char * +i830_bios_get (ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); struct vbt_header *vbt; @@ -131,7 +131,7 @@ i830GetBIOS(ScrnInfoPtr pScrn) * detecting the panel mode is preferable. */ DisplayModePtr -i830_bios_get_panel_mode(ScrnInfoPtr pScrn) +i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither) { I830Ptr pI830 = I830PTR(pScrn); struct vbt_header *vbt; @@ -140,7 +140,7 @@ i830_bios_get_panel_mode(ScrnInfoPtr pScrn) int panel_type = -1; unsigned char *bios; - bios = i830GetBIOS(pScrn); + bios = i830_bios_get (pScrn); if (bios == NULL) return NULL; @@ -156,6 +156,7 @@ i830_bios_get_panel_mode(ScrnInfoPtr pScrn) return NULL; } + *wants_dither = FALSE; for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size; bdb_block_off += block_size) { @@ -175,7 +176,7 @@ i830_bios_get_panel_mode(ScrnInfoPtr pScrn) lvds1 = (struct lvds_bdb_1 *)(bios + start); panel_type = lvds1->panel_type; if (lvds1->caps & LVDS_CAP_DITHER) - pI830->panel_wants_dither = TRUE; + *wants_dither = TRUE; break; case 41: if (panel_type == -1) @@ -243,3 +244,51 @@ i830_bios_get_panel_mode(ScrnInfoPtr pScrn) xfree(bios); return NULL; } + +unsigned char * +i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block) +{ + unsigned char *bios; + int bdb_off; + int vbt_off; + int aim_off; + struct vbt_header *vbt; + struct aimdb_header *aimdb; + struct aimdb_block *aimdb_block; + + bios = i830_bios_get (pScrn); + if (!bios) + return NULL; + + vbt_off = INTEL_BIOS_16(0x1a); + vbt = (struct vbt_header *)(bios + vbt_off); + + aim_off = vbt->aim_offset[aim]; + if (!aim_off) + { + free (bios); + return NULL; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "aim_off %d\n", aim_off); + aimdb = (struct aimdb_header *) (bios + vbt_off + aim_off); + bdb_off = aimdb->aimdb_header_size; + while (bdb_off < aimdb->aimdb_size) + { + aimdb_block = (struct aimdb_block *) (bios + vbt_off + aim_off + bdb_off); + if (aimdb_block->aimdb_id == data_block) + { + unsigned char *aim = malloc (aimdb_block->aimdb_size + sizeof (struct aimdb_block)); + if (!aim) + { + free (bios); + return NULL; + } + memcpy (aim, aimdb_block, aimdb_block->aimdb_size + sizeof (struct aimdb_block)); + free (bios); + return aim; + } + bdb_off += aimdb_block->aimdb_size + sizeof (struct aimdb_block); + } + free (bios); + return NULL; +} diff --git a/src/i830_bios.h b/src/i830_bios.h index 881d5c86..cb7666e3 100644 --- a/src/i830_bios.h +++ b/src/i830_bios.h @@ -25,6 +25,11 @@ * */ +#ifndef _I830_BIOS_H_ +#define _I830_BIOS_H_ + +#include <xf86str.h> + struct vbt_header { char signature[20]; /**< Always starts with 'VBT$' */ CARD16 version; /**< decimal */ @@ -33,10 +38,7 @@ struct vbt_header { CARD8 vbt_checksum; CARD8 reserved0; CARD32 bdb_offset; /**< from beginning of VBT */ - CARD32 aim1_offset; /**< from beginning of VBT */ - CARD32 aim2_offset; /**< from beginning of VBT */ - CARD32 aim3_offset; /**< from beginning of VBT */ - CARD32 aim4_offset; /**< from beginning of VBT */ + CARD32 aim_offset[4]; /**< from beginning of VBT */ } __attribute__((packed)); struct bdb_header { @@ -114,3 +116,45 @@ struct lvds_bdb_2 { CARD8 table_size; /* not sure on this one */ struct lvds_bdb_2_entry panels[16]; } __attribute__((packed)); + +struct aimdb_header { + char signature[16]; + char oem_device[20]; + CARD16 aimdb_version; + CARD16 aimdb_header_size; + CARD16 aimdb_size; +} __attribute__((packed)); + +struct aimdb_block { + CARD8 aimdb_id; + CARD16 aimdb_size; +} __attribute__((packed)); + +struct vch_bdb_20 { +} __attribute__((packed)); + +struct vch_panel_data { + CARD16 fp_timing_offset; + CARD8 fp_timing_size; + CARD16 dvo_timing_offset; + CARD8 dvo_timing_size; + CARD16 text_fitting_offset; + CARD8 text_fitting_size; + CARD16 graphics_fitting_offset; + CARD8 graphics_fitting_size; +} __attribute__((packed)); + +struct vch_bdb_22 { + struct aimdb_block aimdb_block; + struct vch_panel_data panels[16]; +} __attribute__((packed)); + +unsigned char * +i830_bios_get (ScrnInfoPtr pScrn); + +DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither); + +unsigned char * +i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block); + +#endif /* _I830_BIOS_H_ */ |