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

📄 pci.c

📁 此為philip 1362 USB DOS下的驅動程式包, 已經共測試並內含有說明文件
💻 C
字号:
#include <dos.h>
#include "pci.h"

#define I_VENDOR_ID          0x00
#define PCI_DEVICE_ID        0x02
#define PCI_CMD_REG          0x04
#define PCI_STATUS_REG       0x06
#define PCI_REV_ID           0x08     /* including the class code */
#define PCI_CACHE_LINE_SIZE  0x0C
#define PCI_LATENCY_TIMER    0x0D
#define PCI_HEAD_TYPE        0x0E
#define PCI_BIST             0x0F
#define PCI_BASE_ADDR_0      0x10
#define PCI_BASE_ADDR_1      0x14
#define PCI_BASE_ADDR_2      0x18
#define PCI_BASE_ADDR_3      0x1C
#define PCI_BASE_ADDR_4      0x20
#define PCI_BASE_ADDR_5      0x24
#define PCI_CIS_POINTER      0x28
#define PCI_SUB_VENDOR_ID    0x2C
#define PCI_SUB_SYSTEM_ID    0x2E
#define PCI_EXP_ROM_BASE     0x30
#define PCI_INTR_LINE        0x3C
#define PCI_INTR_PIN         0x3D
#define PCI_MIN_GNT          0x3E
#define PCI_MAX_LAT          0x3F

#define OFFSET_TO_DW_INDEX(x)     ((x) & ~0x3)
#define OFFSET_TO_BYTE_INDEX(x)   ((x) & 0x3)

/*---------------------------------------------------------------------*/
/* Ports and the bit patterns used by the Configuration Mechanism One  */
/*---------------------------------------------------------------------*/
#define CFG_ADDR_REG    0x0CF8
#define CFG_DATA_REG    0x0CFC
#define CFG_SPACE_ENA   0x80000000

/*---------------------------------------------------------------------*/
/* Ports and the bit patterns used by the Configuration Mechanism Two  */
/*---------------------------------------------------------------------*/
#define CFG_ENABLE_REG   0x0CF8
#define CFG_FORWARD_REG  0x0CFA
#define CFG_BASE_REG     0xC000
#define CFG_SPACE_KEY    0xF0
#define SPE_CYC_ENA      0x01

#define MULTI_FUNC_BIT   0x80


#define MAX_PCI_DEVICES   16
#define MAX_BUS_NUM   16         /* the maximum value is 256           */
#define MAX_DEV_NUM   32
#define MAX_FUNC_NUM   8

#define PCI_CFG_MECHANISM_1   1
#define PCI_CFG_MECHANISM_2   2

#define PCI_NO_DEVICE_ID      0xffffffff

#define USHORT      unsigned short
#define ULONG       unsigned long
#define UCHAR       unsigned char

typedef  struct pci_cfg_info
	{
	struct  pci_cfg_info *next;
	USHORT  vendor_id;
	USHORT  dev_id;
	USHORT  pci_bus_num;
	USHORT  pci_dev_num;
	USHORT  pci_func_num;
	USHORT  rev_id;
	USHORT  base_class;
	USHORT  sub_class;
	ULONG   class_code;

	USHORT  subsys_vendor_id;
	USHORT  subsys_id;
	ULONG   cfg_addr;
} PCI_CFG_INFO;


static PCI_CFG_INFO pci_cfg_info[MAX_PCI_DEVICES];

unsigned long		g_bridge_setting_IO;


USHORT pci_cfg_rd_w(ULONG addr, ULONG offset);
UCHAR  pci_cfg_rd_b(ULONG addr, ULONG offset);
ULONG  pci_cfg_rd_l(ULONG addr, ULONG offset);

static ULONG inpd(int portnum)
{
   static ULONG value ;
   asm mov dx,portnum ;
   asm lea bx,value ;
__emit__(0x66,0x50,			// push EAX
		0x66,0xED,			// in EAX,DX
		0x66,0x89,0x07,		// mov [BX],EAX
		0x66,0x58) ;		// pop EAX
		return value ;
}

static void outpd(int portnum, ULONG val)
{
   static ULONG value = 0 ;

   value = val ;
   asm mov dx,portnum ;
   asm lea bx,value ;
   __emit__(0x66,0x50,			// push EAX
		0x66,0x8B,0x07,		// mov EAX,[BX]
		0x66,0xEF,			// out DX,EAX
		0x66,0x58) ;		// pop EAX
   return ;
}

PCI_CFG_INFO * get_pci_cfg_info_tbl()
{
	PCI_CFG_INFO  *pinfo;
	ULONG dnum, fnum, bus_num;
	ULONG addr, addr_f;
	ULONG tmpl;
	ULONG tmps;
	ULONG pci_found;


	pinfo = &pci_cfg_info[0];
	pci_found = 0;

	for(bus_num=0; bus_num < MAX_BUS_NUM; bus_num++)
		{
		for(dnum=0; dnum < MAX_DEV_NUM; dnum++)
			{
			addr = (bus_num << 16) | (dnum << 11);
		for(fnum=0; fnum < MAX_FUNC_NUM; fnum++)
				{
				/*---------------------------------------------------------*/
				/* read vendor and device IDs and check them               */
				/*---------------------------------------------------------*/
				addr_f = addr | (fnum << 8);
				tmpl = pci_cfg_rd_l(addr_f, 0);
				if(tmpl == PCI_NO_DEVICE_ID)
					 break;

				pinfo->vendor_id = tmpl & 0xFFFF;
				pinfo->dev_id = (tmpl >> 16) & 0xFFFF;
				pinfo->pci_bus_num = bus_num;
				pinfo->pci_dev_num = dnum;
				pinfo->pci_func_num = fnum;

				pinfo->subsys_id = pci_cfg_rd_w(addr_f,
												  PCI_SUB_VENDOR_ID);

				pinfo->subsys_vendor_id = pci_cfg_rd_w(addr_f,
												  PCI_SUB_SYSTEM_ID);

				tmpl = pci_cfg_rd_l(addr_f, PCI_REV_ID);
				pinfo->rev_id = tmpl & 0xf;
				pinfo->class_code  = (tmpl >> 8) & 0xffffff;
				pinfo->base_class  = (tmpl >> 24) & 0xff;
				pinfo->sub_class  = (tmpl >> 16) & 0xff;

				pinfo->cfg_addr = addr_f;

				pci_found++;

				if(pci_found >= MAX_PCI_DEVICES)
					 break;

		pinfo->next = &pci_cfg_info[pci_found];
				pinfo = pinfo->next;

				tmpl = pci_cfg_rd_b(addr| (fnum  << 8), PCI_HEAD_TYPE);
				if(!(tmpl & MULTI_FUNC_BIT))
					break;
				}
			}
		}
	pinfo->next = 0;
	return &pci_cfg_info[0];
} /* get_pci_cfg_info_tbl() */


ULONG pci_cfg_read(ULONG dev_idx, ULONG offset, ULONG bytes)
{
	ULONG addr;

	addr = pci_cfg_info[dev_idx].cfg_addr;

	if(bytes == 1)
	return pci_cfg_rd_b(addr, offset);
	else if(bytes == 2)
	return pci_cfg_rd_w(addr, offset);
	else
	return pci_cfg_rd_l(addr, offset);

}


USHORT pci_cfg_rd_w(ULONG addr, ULONG offset)
{
	USHORT wtmp;

	addr |= CFG_SPACE_ENA;
	outpd(CFG_ADDR_REG, addr | OFFSET_TO_DW_INDEX(offset));
	wtmp = inport(CFG_DATA_REG | OFFSET_TO_BYTE_INDEX(offset));
	outpd(CFG_ADDR_REG, 0);

	return wtmp;
} /* pci_cfg_rd_w() */

UCHAR  pci_cfg_rd_b(ULONG addr, ULONG offset)
{
	UCHAR btmp;

	addr |= CFG_SPACE_ENA;
	outpd(CFG_ADDR_REG, addr | OFFSET_TO_DW_INDEX(offset));
	btmp = inportb(CFG_DATA_REG | OFFSET_TO_BYTE_INDEX(offset));
	outpd(CFG_ADDR_REG, 0);

	return btmp;

} /* pci_cfg_rd_b() */


ULONG  pci_cfg_rd_l(ULONG addr, ULONG offset)
{
	ULONG ltmp;

	addr |= CFG_SPACE_ENA;
	outpd(CFG_ADDR_REG, addr | OFFSET_TO_DW_INDEX(offset));
	ltmp =  inpd(CFG_DATA_REG);
	outpd(CFG_ADDR_REG, 0);

	return ltmp;

} /* pci_cfg_rd_l() */



ULONG findPCIdev(ULONG classcode, ULONG *puBaseAddress, ULONG *puIntLevel)
{
	PCI_CFG_INFO 				        *pci_tblp;
	ULONG 						dev_idx;
	ULONG 						uHostType;
	ULONG						uRetVal;
	ULONG						uData;
	dev_idx = 0;
	pci_tblp = get_pci_cfg_info_tbl();

	/*************************************/
	/* No PCI device found in the system */
	/*************************************/
	if(pci_tblp->vendor_id == 0xffff && pci_tblp->dev_id == 0xffff) {
		return 0;
	}

	/*************************************/
	/* Search for USB host controllers   */
	/*************************************/
	while (pci_tblp) {
		/* Is it the end of pSOS PCI device table? */
		if (pci_tblp->vendor_id == 0xffff && pci_tblp->dev_id == 0xffff)
			break;

		/* Is it a USB host controller? */
		if (pci_tblp->class_code == classcode) {
			*puBaseAddress = pci_cfg_read(dev_idx, PCI_BASE_ADDR_2, 4UL) & 0xFFFFFFF0;
			g_bridge_setting_IO		= pci_cfg_read(dev_idx, PCI_BASE_ADDR_1, 4UL) & 0xFFFFFFF0;
			*puIntLevel = pci_cfg_read(dev_idx, PCI_INTR_LINE, 1UL);
			return 1;
		} /* if */

		dev_idx++;
		pci_tblp = pci_tblp->next;

	} /* while */

	return 0;

} /* findPCIdev() */

void set_pci_bridge( void )
{
	unsigned long wait_cycle=3L;
	unsigned long tmp;

	tmp = inpd (g_bridge_setting_IO + 0x18);
	tmp &= ~0x0000003C;							// mask register[5..2]
	tmp |= wait_cycle << 2;

	outpd(g_bridge_setting_IO + 0x18, tmp);
	outpd( g_bridge_setting_IO + 0x68, 0x00000900 );
}


⌨️ 快捷键说明

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