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

📄 fruid.c

📁 Write Fruid in DOS system
💻 C
📖 第 1 页 / 共 2 页
字号:
//********************************************************************
//*  Munich Update Motherboard FRUID Tool                            *
//********************************************************************
//*
//* Chipset:  NVDIA MCP55
//* EEPROM:   ATMEL AT24C64
//* Author:   Yuanjie Xu, ESBU/SW MiTAC Shanghai
//* Modifier: Jessie.Jing, SW2, ESBU, MiTAC Shanghai
//* 
//********************************************************************
//* Rev. Date        Description                                     *
//********************************************************************
//* 0.1  2006-06-19  Initial version
//* 1.0  2007-04-29  Check whether burning time is earlier than 2005

#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <mem.h>
#include <conio.h>
#pragma inline

extern unsigned _floatconvert;
#pragma extref _floatconvert

#define inb_p(p)		inportb(p)
#define outb_p(v, p)	outportb(p, v)

typedef unsigned char		BYTE;
typedef unsigned short		WORD;
typedef unsigned long		u32;
typedef unsigned long long 	u64;

typedef long uint32_t;
typedef unsigned bool;

#define	FALSE 0
#define	TRUE  1

static u32 smbus_base_addr = 0;
static u32 smbus_base_offset = 0;
static u32 smbus_value_bit = 0;

struct smbus_controller
{
	u32 pci_id;
	u32 base_offset;
	u32 value_bit;
};


static struct smbus_controller smbus_controller_list[] = 
{
	{ 0x25a48086, 0x20, 0xffe0}, //Hance Rapids ICH SMBus Controller
	{ 0x24838086, 0x20, 0xffe0}, //ICH3 SMBus Controller
	{ 0x005210de, 0x24, 0xffff}, //CK804 SMBus Controller, NVDIA
	{ 0x036810de, 0x24, 0xffff}, //MCP55 SMBus Controller, NVDIA
	{ 0, 0, 0},
};

/*SMBus address offsets */
#define PRTCL  (smbus_base_addr + 0)
#define STS    (smbus_base_addr + 1)
#define ADDR   (smbus_base_addr + 2)
#define CMD    (smbus_base_addr + 3)
#define DATA0  (smbus_base_addr + 4)
#define DATA1  (smbus_base_addr + 5)

#define FruSize 0x2000

struct Fru_table
{
   char            *Field_descript;
   WORD            Location;
   unsigned        Length;
};

/*Fru Table for Motherboard or FPB*/
struct Fru_table FruTable_MFS[] = {
	{"UNIX_Timestamp32"     , 0x1F37 , 4 },
	{"FRUID_Info"           , 0x1F3B , 29},
	{"Manufacture_Loc"      , 0x1F8B , 64},
	{"Sun_Part_No"          , 0x1FCB , 7 },
	{"Sun_Serial_No"        , 0x1FD2 , 6 },
	{"Vendor_Name"          , 0x1FD8 , 2 },
	{"Initial_HW_Rev_Level" , 0x1FDC , 2 },
	{"FRUID_Source_BIN_Info", 0x1FF0 , 11},
	{"CRC"                  , 0x1F33 , 200},
	{"CRC32"                , 0x1FFC , 4 },
	{NULL,0,0}
};

/*Fru Table for SAS SBP, chicago*/
struct Fru_table FruTable_CS[] = {
	{"UNIX_Timestamp32"     , 0x1F34 , 4 },
	{"FRUID_Info"           , 0x1F38 , 29},
	{"Manufacture_Loc"      , 0x1F88 , 64},
	{"Sun_Part_No"          , 0x1FC8 , 7 },
	{"Sun_Serial_No"        , 0x1FCF , 6 },
	{"Vendor_Name"          , 0x1FD5 , 2 },
	{"Initial_HW_Rev_Level" , 0x1FD9 , 2 },
	{"FRUID_Source_BIN_Info", 0x1FED , 11},
	{"CRC"                  , 0x1F30 , 203},
	{"CRC32"                , 0x1FFC , 4 },
	{NULL,0,0}
};

struct Fru_table *fru=NULL;

WORD CRClength;
BYTE FruBuffer[FruSize];

/* CRC Model Abstract Type */
/* ----------------------- */
/* The following type stores the context of an executing instance of the */
/* model algorithm. Most of the fields are model parameters which must be */
/* set before the first initializing call to cm_ini. */
typedef struct
{
        int cm_width; /* Parameter: Width in bits [8,32]. */
        uint32_t cm_poly; /* Parameter: The algorithm's polynomial. */
        uint32_t cm_init; /* Parameter: Initial register value. */
        bool cm_refin; /* Parameter: Reflect input bytes? */
        bool cm_refot; /* Parameter: Reflect output CRC? */
        uint32_t cm_xorot; /* Parameter: XOR this to output CRC. */

        uint32_t cm_reg; /* Context: Context during execution. */
} cm_t;
typedef cm_t *p_cm_t;


/* The following definitions make the code more readable. */

#define BITMASK(X) (1L << (X))

static uint32_t reflect(uint32_t v, int b)
/* Returns the value v with the bottom b [0,32] bits reflected. */
/* Example: reflect(0x3e23L,3) == 0x3e26 */
{
        int i;
        uint32_t t = v;
        for (i = 0; i < b; i++) {
                if (t & 1L)
                        v |=  BITMASK((b-1)-i);
                else
                        v &= ~BITMASK((b-1)-i);
                t >>= 1;
        }
        return (v);
}

static uint32_t widmask(p_cm_t p_cm)
/* Returns a longword whose value is (2^p_cm->cm_width)-1. */
/* The trick is to do this portably (e.g. without doing <<32). */
{
        return ((((1L<<(p_cm->cm_width-1))-1L)<<1)|1L);
}

//void outb_p(int value, int addr);
//unsigned int inb_p(int addr);

u32 pcibios_read_config_dword(u32 busnum, u32 devnum, u32 funnum, u32 regnum);
int probe_smbus (u32 pci_id);
int get_smbus_addr (void);
BYTE i2c_read_word(WORD offset1);
void  i2c_write_word(WORD offset, BYTE data);

void cm_ini(p_cm_t p_cm);
void cm_nxt(p_cm_t p_cm, int ch);
uint32_t cm_crc(p_cm_t p_cm);
uint32_t compute_crc32(BYTE *bytes, int length);

void Display_All_Context(void);
void Update_Binfile(void);
int Update_time(void);
void Update_Serial_NO(void);
void Update_CRC32(void);
void DoubleCheck_CRC32(void);

void Check_Info(void);
void Check_time(void);
void Check_ManuLoc(void);
void Check_PN(void);
void Check_SN(void);
void Check_VendorName(void);
void Check_HW_Rev_Lev(void);
void Check_bin_info(void);
int Check_CRC32(void);

void usage(void);


void cm_ini(p_cm_t p_cm)
{
	p_cm->cm_reg = p_cm->cm_init;
}

void cm_nxt(p_cm_t p_cm, int ch)
{
	int i;
	uint32_t uch = (uint32_t)ch;
	uint32_t topbit = BITMASK(p_cm->cm_width-1);

	if (p_cm->cm_refin)
		uch = reflect(uch, 8);

	p_cm->cm_reg ^= (uch << (p_cm->cm_width-8));
	for (i = 0; i < 8; i++) {
		if (p_cm->cm_reg & topbit)
			p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
		else
			p_cm->cm_reg <<= 1;

		p_cm->cm_reg &= widmask(p_cm);
	}
}

uint32_t cm_crc(p_cm_t p_cm)
{
	if (p_cm->cm_refot)
		return (p_cm->cm_xorot ^ reflect(p_cm->cm_reg, p_cm->cm_width));
	else
		return (p_cm->cm_xorot ^ p_cm->cm_reg);
}

uint32_t compute_crc32(BYTE *bytes, int length)
{
	cm_t crc_mdl;
	p_cm_t p_crc;
	int i;
	uint32_t aCRC;

	p_crc = &crc_mdl;

	p_crc->cm_width = 32;
	p_crc->cm_poly = 0x04c11db7;
	p_crc->cm_init = 0xffffffff;
	p_crc->cm_refin = TRUE;
	p_crc->cm_refot = TRUE;
	p_crc->cm_xorot = 0xffffffff;

	cm_ini(p_crc);

	for (i = 0; i < length; i++)
	{
		cm_nxt(p_crc, bytes[i]);
	}

	aCRC = (uint32_t)cm_crc(p_crc);

	return (aCRC);
}

static BYTE slave_addr;
BYTE Low128_Bufer[128],Hi128_Bufer[128],buffer[265];
char SFileName[20];  //source file
char TSFileName[20]; //target file
char SN_number[7];
char compare_time[5];
char compare_info[30];
char compare_ManuLoc[65];
char compare_pn[8];
char compare_sn[7];
char compare_vn[3];
char compare_hw[3];
char compare_bin_info[12];

void Display_All_Context(void)
{
	int i, j = 0;

	printf("\n\t");
	for(i = 0;i<= 0xF;i++)
		printf("%2x  ",i);
	printf("\n");
	for(i = 0;i<= 0x1FFF;i++)
	{
		j = i % 16;
		if (j == 0)
		{
			printf("\n");
			printf("0x%2x\t", i);
		}
		FruBuffer[i] = i2c_read_word(i);
		printf("%2.2x  ",i2c_read_word(i));
	}
	printf("\n");
}

void Update_Binfile()
{
    int length = 0,i,count = 0;
    BYTE buffer[80];
    FILE *file = NULL;
    file = fopen(SFileName,"rb");

    memset (buffer, 0, 80);
    do
    {
		length = fread((void *)buffer,1,80,file);
		for(i = 0;i < length;i++)
		{
			i2c_write_word(count*80+i,buffer[i]);
//			printf("%x\t",buffer[i]);
		}
		count++;
		memset(buffer,0,80);
	}while(length == 80);
    fclose(file);
//  printf("\n");
}

int Update_time()
{
	time_t Timestamp, Timestamp1;
	time_t Timestamp_comp = 0;
	int i;

	putenv("TZ=EST-8");
	tzset();

	Timestamp = time(NULL);
	Timestamp1 = Timestamp;
	printf("Current Time  : %s", ctime(&Timestamp));

	// Unix_Timestamp32
	for (i=(fru[0].Length-1);i>=0;i--)
	{
		i2c_write_word(fru[0].Location + i, Timestamp & 0xFF);
		Timestamp>>=8;
	}
	printf("Write Time    : %s", ctime(&Timestamp1));
	
	for (i=0;i<=3;i++)
	{
		Timestamp_comp += i2c_read_word(fru[0].Location + i);
		if (i != 3)
		    Timestamp_comp <<=8;
	}
	printf("Compare Time  : %s", ctime(&Timestamp_comp));

	if(Timestamp_comp == Timestamp1)
	{
		printf("Update UNIX_Timestamp32 Pass\n");
		return 0;
	}
	else
	{
		printf("Update UNIX_Timestamp32 Fail\n");
		return 1;
	}
}

void Update_Serial_NO(void)
{
//  WORD offset = 0x1FD2;
    WORD index;

    for(index = 0;index < fru[4].Length;index++)
    {
		i2c_write_word(fru[4].Location+index,SN_number[index]);
//		FruBuffer[offset+index] = SN_number[index];
    }
}

void Update_CRC32()
{
    u32 CRC32 = 0;
    int i,j;
    BYTE crc1;
    BYTE crc2;
    BYTE crc3;
    BYTE crc4;

    CRClength = fru[8].Length;
    for(j=0;j<CRClength;j++)
       FruBuffer[fru[8].Location+j] = i2c_read_word(fru[8].Location+j);
    CRC32=compute_crc32(&FruBuffer[fru[8].Location],CRClength);
    for (i=3;i>=0;i--)
    {
       FruBuffer[fru[9].Location + i] = CRC32 & 0xFF;
       i2c_write_word(fru[9].Location + i, CRC32 & 0xFF);
       CRC32>>=8;
    }
    crc1 =  i2c_read_word(fru[9].Location);
    crc2 =  i2c_read_word(fru[9].Location+1);
    crc3 =  i2c_read_word(fru[9].Location+2);
    crc4 =  i2c_read_word(fru[9].Location+3);
    printf("CRC32: 0x%2.2X%2.2X%2.2X%2.2X\n", crc1, crc2, crc3, crc4);
}

void DoubleCheck_CRC32()
{
    u32 CRC32 = 0, CRC32_1 = 0;
    char buff[100];
    int i;
    CRClength = fru[8].Length;

    for (i=0;i<=3;i++)
    {
        CRC32_1+=FruBuffer[fru[9].Location+i];
        if (i<=2)
           CRC32_1*=256;
    }
    sprintf(buff,"%08lX",CRC32_1);
//    printf("%20s : 0x%s\n","CRC32_1",buff);

    CRC32 = compute_crc32(&FruBuffer[fru[8].Location],CRClength);
    sprintf(buff,"%08lX",CRC32);
//    printf("%20s : 0x%s\n","Re-Caculate CRC32",buff);
 
	if (CRC32 == CRC32_1)
    {
        printf("Double check EEPROM Checksum32 Pass\n");
        exit(0);
    }
    else
    {
        printf("Double check EEPROM Checksum32 Error\n");
        exit(1);
    }
}

void Check_time()
{
	time_t Timestamp = 0;
	char tmpbuf[10];
	int year = 0;
	int i;
	BYTE time1;
	BYTE time2;
	BYTE time3;
	BYTE time4;

	printf("0x%4X Field:  %s\n", fru[0].Location, fru[0].Field_descript);
	putenv("TZ=EST-8");
	tzset();
	for (i = 0; i <= 3; i++)
	{
		Timestamp += i2c_read_word(fru[0].Location + i);;
		if (i != 3)
			Timestamp <<= 8;
	}
	time1 =  i2c_read_word(fru[0].Location);
	time2 =  i2c_read_word(fru[0].Location+1);
	time3 =  i2c_read_word(fru[0].Location+2);
	time4 =  i2c_read_word(fru[0].Location+3);
	printf("Burning UNIX_Timestamp32 in fruid:  %s", ctime(&Timestamp));
	printf("                                    (0x%2.2X%2.2X%2.2X%2.2X)\n", time1, time2, time3, time4);

	strftime(tmpbuf, 10, "%Y", localtime(&Timestamp));
	year = atoi(tmpbuf);
	if(year < 2005)
	{
		printf( "Burning year: %4i is earlier than 2005! Error!", year);
		exit(1);
	}
}

void Check_Info()
{
	WORD index;
	WORD offset = fru[1].Location;
	printf("0x%4X Field:  %s\n", offset, fru[1].Field_descript);

	memset(compare_info, 0, 30);

⌨️ 快捷键说明

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