All pastes #1801249 Raw Edit

C

public c v1 · immutable
#1801249 ·published 2010-02-18 07:42 UTC
rendered paste body
#define _GNU_SOURCE#include <stdio.h>#include <string.h>#include <stdlib.h>/* 128Kb */#define BIOS_SIZE	131072char BIOS[BIOS_SIZE];enum ELEMENT_TYPES{	STRING=0,	CLOCK_INFO,	VENDOR_ID,};/* Clock Info Table start marker */#define CLOCK_TABLE_START "\xE8\x03\xE8\x03\x28\x00\x98\x00\x00\x00\x08"/* Clock Info Table end marker */#define CLOCK_TABLE_END "\x08\x00\x00\x00\x7A\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00"/************ Clock Info Table structure ********************************* * [CLOCK_TABLE_START]  * [18 bytes ???] * [0x01 0x01 0x02 0x03 0x02 0x040506 0x03 0x070809 etc... depending on how many rows] * <ROW0> [3byte GPU (100x MHz)] [3byte RAM (100x MHz)] [3byte Vcore (mV)] * [7 bytes ???] </ROW0> * <ROW1> ... * [7 bytes ???] </ROW1> * etc..  So each row is 16 bytes. I've seen up to 12 rows  * [CLOCK_TABLE_END] */typedef struct {	int type;	void *data;	char *desc;	unsigned int offset;	unsigned int length;}Element;typedef struct {	unsigned int vcore;	unsigned int ram;	unsigned int gpu;}ClockInfo;typedef struct {	char *name;	unsigned short id;}VendorID;VendorID KNOWN_VENDORS[] = {{ "Asus"	,0x1043 },{ "Diamond"	,0x1092 },{ "GigaByte"	,0x1458 },{ "VisionTek"	,0x1545 },{ "Sapphire"	,0x174B },{ "Powercolor"	,0x1787 },{ NULL }};Element *HD48xx_vbios[] = {&(Element){ STRING	,NULL,"Bios Date/Time"			,0x0050, 16},&(Element){ VENDOR_ID	,NULL,"Sub Vendor ID"			,0x007C,  2},&(Element){ STRING	,NULL,"Bios Version String"		,0x0094, 14},&(Element){ STRING	,NULL,"Reported Chip Type"		,0x00A3,  5},&(Element){ STRING	,NULL,"Interface"			,0x00A9, 12},&(Element){ STRING	,NULL,"RAM Type"			,0x00B5,  6},&(Element){ STRING	,NULL,"Hardware Spec"			,0x00BD, 76},&(Element){ STRING	,NULL,"Power Cable Error Message"	,0x010E,164},&(Element){ STRING	,NULL,"Copyright"			,0x01B2, 38},&(Element){ STRING	,NULL,"ATOMBios Version"		,0x01D8, 41},&(Element){ CLOCK_INFO	,NULL,"Clock Info Table"		,0,0},NULL};void print_hex(char *ptr, size_t size){        int i;        for(i=0;i<size;i++){                printf("%02hhX ",ptr[i]);        }        puts("\n");}void byte_swap(char *bytes, int length){	char copy;	int i; 	for(i=0;(length-- -i)>1;i++){		copy = bytes[i];		bytes[i] = bytes[length];		bytes[length] = copy;	}}void parse_vbios(Element **vbios){	int i,j;	char *cptr;	char *start,*end;	ClockInfo **clk;	int number,temp,length;	for(i=0;vbios[i];i++){		switch(vbios[i]->type){		case STRING:			cptr = malloc(vbios[i]->length);			memcpy(cptr,				BIOS+vbios[i]->offset,				vbios[i]->length);			vbios[i]->data = cptr;			break;		case VENDOR_ID:			number = 0;			memcpy(&number,BIOS+vbios[i]->offset,				vbios[i]->length);			for(j=0;KNOWN_VENDORS[j].name ;j++){				if(number == KNOWN_VENDORS[j].id ){					vbios[i]->data = &KNOWN_VENDORS[j];					break;				}			}					break;		case CLOCK_INFO:			start = NULL;			start = memmem(BIOS,BIOS_SIZE,CLOCK_TABLE_START,9);			if(start == NULL){				printf("ERROR: Clock info table start\n");				break;			}			start+=10+19;						end = NULL;			end = memmem(BIOS,BIOS_SIZE,CLOCK_TABLE_END,16);			if(end == NULL){				printf("ERROR: Clock info table end\n");				break;			}			length = (int) (end-start);			number = length/16;			if( (length%16) == 0 ){				start+=16;				number--;			}else {				start += length%16; 			}						clk = malloc(sizeof(ClockInfo*)*(number+1));			for(j=0;j<number;j++){				clk[j]=malloc(sizeof(ClockInfo));				temp =0;				memcpy(&temp,start,3);				clk[j]->gpu = temp/100;				temp =0;				memcpy(&temp,start+3,3);				clk[j]->ram = temp/100;				temp =0;				memcpy(&temp,start+6,3);				clk[j]->vcore = temp;				start+=16;			}			clk[j]=NULL;			vbios[i]->data = clk;		}	};}void dump_vbios(Element **vbios){	int i,j;	ClockInfo **clk;	for(i=0;vbios[i];i++){		printf("[%04x:%04x] %s\n",			vbios[i]->offset,			vbios[i]->length,			vbios[i]->desc);		switch(vbios[i]->type){		case STRING:			printf("%s\n",(char*)vbios[i]->data);			break;		case CLOCK_INFO:			if(vbios[i]->data == NULL)break;			clk = (ClockInfo**) vbios[i]->data;			for(j=0;clk[j];j++){				printf(" Profile %02i: %s %04u %s %04u %s %04u mV\n",					j,					"GPU =",clk[j]->gpu,					"MHz | MEM =",	clk[j]->ram,					"MHz | Vcore =",clk[j]->vcore);			}			break;		case VENDOR_ID:			printf("0x%hX - %s\n",				((VendorID*)vbios[i]->data)->id,				((VendorID*)vbios[i]->data)->name);			break;		}	}}int main(int argc, char **argv){	FILE *fptr;	if(argc != 2 ){		printf("Specify file\n");		return 1;	}	fptr = fopen(argv[1],"r");	fread(BIOS,BIOS_SIZE,1,fptr);	fclose(fptr);	parse_vbios(HD48xx_vbios);	dump_vbios(HD48xx_vbios);	return 0;}