?? pci.c
字號:
#include <dos.h>
#include "pci.h"
static PCI_CFG_INFO pci_cfg_info[MAX_PCI_DEVICES];
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);
/*void outl(ULONG uReg, ULONG uValue)
{
outport(uReg, uValue & 0x0000FFFF);
outport(uReg+2, (uValue & 0xFFFF0000) >> 16);
}
ULONG inl(ULONG uReg)
{
ULONG wTmp;
wTmp = inport(uReg);
wTmp |= (inport(uReg+2) << 16); //jason change to <<
return wTmp;
}*/
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() */
BOOLEAN findPCIdev(ULONG classcode, ULONG *puBaseAddress, ULONG *puIntLevel)
{
ULONG uHostTotal; /* Number of host found */
PCI_CFG_INFO *pci_tblp;
ULONG dev_idx;
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;
*puIntLevel = pci_cfg_read(dev_idx, PCI_INTR_LINE, 1UL);
//config PLX PCI bridge local interrupt pin as input (added by wzw)
outpd( (pci_cfg_read(dev_idx, PCI_BASE_ADDR_1, 4UL) & 0xFFFFFFF0) + 0x68, 0x00000900 );
return 1;
} /* if */
dev_idx++;
pci_tblp = pci_tblp->next;
} /* while */
return 0;
} /* findPCIdev() */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -