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

📄 pcicfg_ver1.0.0.c

📁 产生产品信息文件, 写入EEPROM, 读取PCI 设备配置空间信息, 重写PCI 设备配置空间, 根据vendor id 搜索PCI卡
💻 C
字号:
#include "stdio.h"
#include "conio.h"
#include "char_int.c"

#define BYTE unsigned char
#define WORD unsigned int
#define DWORD unsigned long int

//Ver1.0.0
//write a byte to pci configuration space
//portid : pci configruation space index
//pci_addr: pci device address, bus#dev#func#
//val : the byte will be wroten to pci configuration space
void byte_wr_pcicfg(int portid, WORD pci_addr, BYTE val)
{
asm{
	mov ax, 0xb10b;
	mov bx, pci_addr;
	mov di, portid;//pci configuration space index
	mov cl, val;
	int 0x1a;
    }
}

//write a word to pci configuration space
//portid : pci configruation space index
//pci_addr: pci device address, bus#dev#func#
//val : the word will be wroten to pci configuration space
void word_wr_pcicfg(int portid, WORD pci_addr, WORD val)
{
asm{
	mov ax, 0xb10c;
	mov bx, pci_addr;
	mov di, portid;//pci configuration space index
	mov cx, val;
	int 0x1a;
    }
}

//read a byte from pci configuration space
//portid : pci configruation space index
//pci_addr: pci device address, bus#dev#func#
BYTE byte_rd_pcicfg(int portid, WORD pci_addr)
{
	BYTE valret;
	asm mov ax, 0xb108;
	asm mov bx, pci_addr;
	asm mov di, portid;//pci configuration space index
	asm int 0x1a;
	asm mov valret, cl;
	return valret;
}

//read a word from pci configuration space
//portid : pci configruation space index
//pci_addr: pci device address, bus#dev#func#
WORD word_rd_pcicfg(int portid, WORD pci_addr)
{
	WORD valret;
	asm mov ax, 0xb109;
	asm mov bx, pci_addr;
	asm mov di, portid;//pci configuration space index
	asm int 0x1a;
	asm mov valret, cx;
	return valret;
}
/*
DWORD dword_rd_pcicfg(int portid, WORD pci_addr)
{
	DWORD valret;
	asm mov ax, 0xb10a;
	asm mov bx, pci_addr;
	asm mov di, portid;
	asm int 0x1a;
	asm lea bx, valret;
	//asm mov valret, cx;
	__emit__(
		     //mov [bx], ecx;
		);
	return valret;
}*/

//search pci information
void search_pci()
{
	WORD pci_addr, vendorid;
	BYTE bus, dev, func, irq, intpin;
	WORD deviceid, temp;
	DWORD classcode;
	int i=0;
	printf("bus#\tdev#\tfunc#\tVendor\tDevice\tClass\tIRQ\tIntpin\n");
	for(pci_addr=0; pci_addr<0xffff; pci_addr++)
	{
	    vendorid=word_rd_pcicfg(0x0, pci_addr);
	    if(vendorid!=0xffff)
	    {
		bus=(BYTE)(pci_addr>>8);
		dev=(BYTE)((pci_addr>>3)&0x1f);
		func=(BYTE)(pci_addr&0x7);
		deviceid=word_rd_pcicfg(0x2, pci_addr);
		classcode=(DWORD)word_rd_pcicfg(0xa, pci_addr)<<8;
		temp=word_rd_pcicfg(0x8, pci_addr)>>8;
		classcode=classcode | temp;
		irq=byte_rd_pcicfg(0x3c, pci_addr);
		intpin=byte_rd_pcicfg(0x3d, pci_addr);
		printf("\%2.2x\t\%2.2x\t\%2.2x\t", bus, dev, func);
		printf("\%4.4x\t\%4.4x\t\%6.6x\t", vendorid, deviceid, classcode);
		printf("\%2.2x\t\%2.2x\n", irq, intpin);
		i++;
		if(i%20==19)
		{
		    printf("please press any key to continue\n");
		    getch();
		    printf("bus#\tdev#\tfunc#\tVendor\tDevice\tClass\tIRQ\tIntpin\n");
		}
	    }
	}
}

//generate firmware file
int gen_fw(WORD devid)
{
    FILE *fp;
    unsigned char fw[19];

    switch(devid)
    {
	case 0x4056 : {fw[0]=0x9;fw[1]=0x14;fw[2]=0x68;fw[3]=0x71;
			fw[4]=0x2;fw[5]=0x0;fw[6]=0x7;fw[7]=0x9;
			fw[8]=0x14;fw[9]=0x56;fw[10]=0x40;fw[11]=0x0;
			fw[12]=0x0;fw[13]=0x0;fw[14]=0x0;fw[15]=0x0;
			fw[16]=0x0;fw[17]=0x0;fw[18]=0x3; break;}
	default : break;
    }
    fp=fopen("pcicfg.ini", "w");
    fwrite(fw, 19, 1, fp);
    fclose(fp);
    return 0;
}

void wr_fw_eeprom(BYTE bus, BYTE dev, BYTE fun)
{
    FILE *fp;
    BYTE i, fw[19];
    WORD pci_addr;
    //GET pci address
    pci_addr = (WORD)bus<<8 | dev<<3 | fun;
    //read the fw, and send to fw[]
    fp=fopen("pcicfg.ini", "r");
    fread(fw, 19, 1, fp);
    fclose(fp);
    //write to EEPROM
    for(i=0;i<19;i++)
    {
	byte_wr_pcicfg(0x8d, pci_addr, i);//address
	byte_wr_pcicfg(0x8e, pci_addr, fw[i]);//data
	byte_wr_pcicfg(0x8c, pci_addr, 0x05);//control-write
	delay(100);
    }
//      val=inpd(0x8c, pci_addr);
//      printf("%x\n", val);

}

void rd_fw_eeprom(BYTE bus, BYTE dev, BYTE fun)
{
	int i=0, j=0;
	BYTE val;
	WORD pci_addr;
	//get pci address
	pci_addr =(WORD)bus<<8 | dev<<3 | fun;
	//print
	for(j=0;j<16;j++)
	{
	    printf("%2.2x ", j);
	}
	printf("\n");
	for(j=0;j<48;j++)
	    printf("-");
	printf("\n");
	//read from EEPROM
	byte_wr_pcicfg(0x8d, pci_addr, 0x00);//set the base address for current read
	byte_wr_pcicfg(0x8c, pci_addr, 0x07);//control-random_read
	val=byte_rd_pcicfg(0x8e, pci_addr);
	delay(200);
//	printf("%2.2x ",val);
	for(i=0;i<32;i++)
	{
	    byte_wr_pcicfg(0x8c, pci_addr, 0x03);//control-current_read
	    val=byte_rd_pcicfg(0x8e, pci_addr);
	    delay(100);
	    printf("%2.2x ", val);
	    if(i%16==15) printf("\n");
	}
	printf("\n");
}

void show_pcicfg(BYTE bus, BYTE dev, BYTE func)
{
	unsigned char i=0;
	BYTE valret;
	WORD pci_addr;
	pci_addr= (((WORD)bus)<<8) | (dev<<3) | func;
	for(i=0;i<16;i++)
	    printf("%2.2x ", i);
	printf("\n");
	for(i=0;i<48;i++)
	    printf("-");
	printf("\n");
	for(i=0;i<128;i++)
	{
	    valret=byte_rd_pcicfg(i,pci_addr);
	    printf("%2.2x ", valret);
	    if(i%16==15) printf("\n");
	}
}

void help()
{
	printf("pcicfg g xxxx:\tgenerate the firmware file in pcicfg.ini.\n");
	printf("       w bus dev func:\tdownload the firmware to eeprom from pcicfg.ini.\n");
	printf("       r bus dev func:\tread from eeprom, and display.\n");
	printf("       d bus dev func:\tdisplay pci configuration space.\n");
	printf("       s :\tsearch the pci device, and display\n");
	printf("         xxxx:\t product model name.\n");
	printf("	 bus:\t pci bus number.\n");
	printf("	 dev:\t pci dev number.\n");
	printf("	 func:\t pci func number. \n");
	printf("\t\t\t\t\tFisher Pan\n");
	printf("\t\t\t\t\t2007-09-11\n");
	printf("\t\t\t\t\tmail:fishing_cat@sohu.com\n");
}

void main(int argc, char *argv[])
{
	char fw[19];
	FILE *fp;
	BYTE val, num, bus, dev, func;
	WORD cmd;

	if(argc==3) cmd=(WORD)Hex_Dec(argv[2]);//for product number
	else if(argc==5)//for pci bus#/dev#/func#
	{
		bus=(BYTE)Hex_Dec(argv[2]);
		dev=(BYTE)Hex_Dec(argv[3]);
		func=(BYTE)Hex_Dec(argv[4]);
	}
	switch(argv[1][0])//for command para
	{
	    case 'g' :
	    {
		if(argc==3)
		switch(cmd)
		{
		    case 0x4056: gen_fw(0x4056);break;
		    case 0x4037: gen_fw(0x4037);break;
		    default: help(); break;
		}
		else help();
	    }
	    case 'w' :
	    {
		if (argc==5)
		    wr_fw_eeprom(bus, dev, func);
		else help();
		break;
	    }
	    case 'r' :
	    {
		if(argc==5)
		    rd_fw_eeprom(bus, dev, func);
		else help();
		break;
	    }
	    case 'd' :
	    {
		if(argc==5)
		    show_pcicfg(bus, dev, func);
		else help();
		break;
	    }
	    case 's' :
	    {
		if(argc==2)
		    search_pci();
		else help();
		break;
	    }
	    default : help();break;
	}
}

⌨️ 快捷键说明

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