⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bios.c

📁 ati driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	Copyright (c) 2002, Thomas Kurschel	Part of Radeon kernel driver			BIOS detection and retrieval of vital data		Most of this data should be gathered directly,	especially monitor detection should be done on	demand so not all monitors need to be connected	during boot*/#include "radeon_driver.h"#include "../shared/mmio.h"#include "../regs/bios_regs.h"#include "../regs/config_regs.h"#include "../regs/memcntrl_regs.h"#include "../regs/fp_regs.h"#include "../regs/crtc_regs.h"#include "../shared/radeon_bios.h"#include "../common/utils.h"#include <stdio.h>#include <string.h>static const char ati_rom_sig[] = "761295520";static const char *radeon_sig[] = {	"RADEON",		// r100	"RV100",		// rv100	"U1",			// rs100 (IGP320M)	"M6",			// mobile version of r100	// probably an M6P; 	// anyway - this is the card I wrote this driver for!	// (perhaps ATI tries to make the card incompatible to standard drivers)	"P6",	"RV200",		// rv200	"M7",			// m7	"RG6",			// r200 (according to spec)	"RS200",		// rs200	"R200",			// r200 (8500 LE)	"R200AGP",		// Fire GL E1	"M9"			// guess: m9	"RV250",		// rv250 R9100	"V280",			// RV280 R9200	"R300",			// R300 R9500 / R9700	"R350",			// R350 R9800	"R360",			// R360 R9800 XT	"V350",			// RV350 R9600	"V360",			// RV350 R9600 XT :guess};// find address of ROM;// this code is really nasty as maintaining the radeon signatures// is almost impossible (the signatures provided by ATI are always out-dated);// further, if there is more then one card built into the computer, we// may detect the wrong BIOS! // we have two possible solutions:// 1. use the PCI location as stored in BIOS// 2. verify the IO-base address as stored in BIOS// I have no clue how these values are _written_ into the BIOS, and// unfortunately, every BIOS does the detection in a different way,// so I'm not sure which is the _right_ way of doing itstatic char *Radeon_FindRom( rom_info *ri ){       	uint32 segstart;	uint8 *rom_base;	char *rom;	int i,j;		for( segstart = 0x000c0000; segstart < 0x000f0000; segstart += 0x00001000 ) {		bool found = false;				// find ROM				rom_base = ri->bios_ptr + segstart - 0xc0000;				if( rom_base[0] != 0x55 || rom_base[1] != 0xaa )			continue;			// find signature of ATI                              		rom = rom_base;		found = false;						for( i = 0; i < 128 - strlen( ati_rom_sig ); i++ ) {			if( ati_rom_sig[0] == rom_base[i] ) {				if( strncmp(ati_rom_sig, rom_base + i, strlen( ati_rom_sig )) == 0 ) {					found = true;					break;				}			}		}				if( !found )			continue;		// find signature of card		found = false;				for( i = 0; i < 512; i++ ) {			for( j = 0; j < sizeof( radeon_sig ) / sizeof( radeon_sig[0] ); j++ ) {				if( radeon_sig[j][0] == rom_base[i] ) {					if( strncmp( radeon_sig[j], rom_base + i, strlen( radeon_sig[j] )) == 0 ) {						SHOW_INFO( 2, "Signature: %s", radeon_sig[j] );						found = true;						break;					}				}			}		}				if( !found )			continue;				SHOW_INFO( 2, "found ROM @0x%lx", segstart );		return rom_base;	}		SHOW_INFO0( 2, "no ROM found" );	return NULL;}// PLL info is stored in ROM, probably it's too easy to replace it// and thus they produce cards with different timingsstatic void Radeon_GetPLLInfo( device_info *di ){	uint8 *bios_header;	PLL_BLOCK pll, *pll_info;		bios_header = di->rom.rom_ptr + *(uint16 *)(di->rom.rom_ptr + 0x48);	pll_info = (PLL_BLOCK *)(di->rom.rom_ptr + *(uint16 *)(bios_header + 0x30));	memcpy( &pll, pll_info, sizeof( pll ));		di->pll.xclk = (uint32)pll.XCLK;	di->pll.ref_freq = (uint32)pll.PCLK_ref_freq;	di->pll.ref_div = (uint32)pll.PCLK_ref_divider;	di->pll.min_pll_freq = pll.PCLK_min_freq;	di->pll.max_pll_freq = pll.PCLK_max_freq;		SHOW_INFO( 2, "ref_clk=%ld, ref_div=%ld, xclk=%ld, min_freq=%ld, max_freq=%ld from BIOS",		di->pll.ref_freq, di->pll.ref_div, di->pll.xclk, 		di->pll.min_pll_freq, di->pll.max_pll_freq );}/*const char *Mon2Str[] = {	"N/C",	"CRT",	"CRT",	"Laptop flatpanel",	"DVI (flatpanel)",	"secondary DVI (flatpanel) - unsupported",	"Composite TV",	"S-Video out"};*//*// ask BIOS what kind of monitor is connected to each portstatic void Radeon_GetMonType( device_info *di ){	unsigned int tmp;		SHOW_FLOW0( 3, "" );		di->disp_type[0] = di->disp_type[1] = dt_none;	if (di->has_crtc2) {		tmp = INREG( di->regs, RADEON_BIOS_4_SCRATCH );				// ordering of "if"s is important as multiple		// devices can be concurrently connected to one port		// (like both a CRT and a TV)				// primary port		// having flat-panel support is most important		if (tmp & 0x08)			di->disp_type[0] = dt_dvi;		else if (tmp & 0x4)			di->disp_type[0] = dt_lvds;		else if (tmp & 0x200)			di->disp_type[0] = dt_tv_crt;		else if (tmp & 0x10)			di->disp_type[0] = dt_ctv;		else if (tmp & 0x20)			di->disp_type[0] = dt_stv;		// secondary port		// having TV-Out support is more important then CRT support		// (CRT gets signal anyway)		if (tmp & 0x1000)			di->disp_type[1] = dt_ctv;		else if (tmp & 0x2000)			di->disp_type[1] = dt_stv;		else if (tmp & 0x2)			di->disp_type[1] = dt_crt;		else if (tmp & 0x800)			di->disp_type[1] = dt_dvi_ext;		else if (tmp & 0x400)			// this is unlikely - I only know about one LVDS unit			di->disp_type[1] = dt_lvds;	} else {		// regular Radeon		// TBD: no TV-Out detection		di->disp_type[0] = dt_none;		tmp = INREG( di->regs, RADEON_FP_GEN_CNTL);		if( tmp & RADEON_FP_EN_TMDS )			di->disp_type[0] = dt_dvi;		else			di->disp_type[0] = dt_crt;	}		SHOW_INFO( 1, "BIOS reports %s on primary and %s on secondary port", 		Mon2Str[di->disp_type[0]], Mon2Str[di->disp_type[1]]);			// remove unsupported devices	if( di->disp_type[0] >= dt_dvi_ext )		di->disp_type[0] = dt_none;	if( di->disp_type[1] >= dt_dvi_ext )		di->disp_type[1] = dt_none;	// HACK: overlays can only be shown on first CRTC;	// if there's nothing on first port, connect	// second port to first CRTC (proper signal routing	// is hopefully done by BIOS)	if( di->has_crtc2 ) {		if( di->disp_type[0] == dt_none && di->disp_type[1] == dt_crt ) {			di->disp_type[0] = dt_crt;			di->disp_type[1] = dt_none;		}	}		SHOW_INFO( 1, "Effective routing: %s on primary and %s on secondary port", 		Mon2Str[di->disp_type[0]], Mon2Str[di->disp_type[1]]);}*/// get flat panel info (does only make sense for Laptops// with integrated display, but looking for it doesn't hurt,// who knows which strange kind of combination is out there?)static bool Radeon_GetBIOSDFPInfo( device_info *di ){	uint8 *bios_header;	uint16 fpi_offset;	FPI_BLOCK fpi;	char panel_name[30];	int i;		bios_header = di->rom.rom_ptr + *(uint16 *)(di->rom.rom_ptr + 0x48);		fpi_offset = *(uint16 *)(bios_header + 0x40);		if( !fpi_offset ) {		di->fp_info.panel_pwr_delay = 200;		SHOW_ERROR0( 2, "No Panel Info Table found in BIOS" );		return false;	} 			memcpy( &fpi, di->rom.rom_ptr + fpi_offset, sizeof( fpi ));		memcpy( panel_name, &fpi.name, sizeof( fpi.name ) );	panel_name[sizeof( fpi.name )] = 0;		SHOW_INFO( 2, "Panel ID string: %s", panel_name );				di->fp_info.panel_xres = fpi.panel_xres;	di->fp_info.panel_yres = fpi.panel_yres;		SHOW_INFO( 2, "Panel Size from BIOS: %dx%d", 		di->fp_info.panel_xres, di->fp_info.panel_yres);			di->fp_info.panel_pwr_delay = fpi.panel_pwr_delay;		if( di->fp_info.panel_pwr_delay > 2000 || di->fp_info.panel_pwr_delay < 0 )		di->fp_info.panel_pwr_delay = 2000;	// there might be multiple supported resolutions stored;	// we are looking for native resolution	for( i = 0; i < 20; ++i ) {		uint16 fpi_timing_ofs;		FPI_TIMING_BLOCK fpi_timing;				fpi_timing_ofs = fpi.fpi_timing_ofs[i];				if( fpi_timing_ofs == 0 )			break;					memcpy( &fpi_timing, di->rom.rom_ptr + fpi_timing_ofs, sizeof( fpi_timing ));		if( fpi_timing.panel_xres != di->fp_info.panel_xres ||			fpi_timing.panel_yres != di->fp_info.panel_yres )			continue;				di->fp_info.h_blank = (fpi_timing.h_total - fpi_timing.h_display) * 8;		// TBD: seems like upper four bits of hsync_start contain garbage

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -