📄 pci_diag.c
字号:
/* Open a handle to a PCI device */
static WDC_DEVICE_HANDLE DeviceOpen(const WD_PCI_SLOT *pSlot)
{
WDC_DEVICE_HANDLE hDev;
DWORD dwStatus;
WD_PCI_CARD_INFO deviceInfo;
/* Retrieve the device's resources information */
BZERO(deviceInfo);
deviceInfo.pciSlot = *pSlot;
dwStatus = WDC_PciGetDeviceInfo(&deviceInfo);
if (WD_STATUS_SUCCESS != dwStatus)
{
PCI_ERR("DeviceOpen: Failed retrieving the device's resources information.\n"
"Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
return NULL;
}
/* NOTE: You can modify the device's resources information here, if
necessary (mainly the deviceInfo.Card.Items array or the items number -
deviceInfo.Card.dwItems) in order to register only some of the resources
or register only a portion of a specific address space, for example. */
/* Open a handle to the device */
hDev = PCI_DeviceOpen(&deviceInfo);
if (!hDev)
{
PCI_ERR("DeviceOpen: Failed opening a handle to the device: %s",
PCI_GetLastErr());
return NULL;
}
return hDev;
}
/* Close handle to a PCI device */
static void DeviceClose(WDC_DEVICE_HANDLE hDev)
{
if (!hDev)
return;
if (!PCI_DeviceClose(hDev))
{
PCI_ERR("DeviceClose: Failed closing PCI device: %s",
PCI_GetLastErr());
}
}
/* -----------------------------------------------
Read/write memory and I/O addresses
----------------------------------------------- */
/* Read/write address menu options */
enum {
MENU_RW_ADDR_SET_ADDR_SPACE = 1,
MENU_RW_ADDR_SET_MODE,
MENU_RW_ADDR_SET_TRANS_TYPE,
MENU_RW_ADDR_READ,
MENU_RW_ADDR_WRITE,
MENU_RW_ADDR_TEST,
MENU_RW_ADDR_EXIT = DIAG_EXIT_MENU,
};
#define ACTIVE_ADDR_SPACE_NEEDS_INIT 0xFF
/* Read/write memory or I/O space address menu */
static void MenuReadWriteAddr(WDC_DEVICE_HANDLE hDev)
{
DWORD option;
static DWORD dwAddrSpace = ACTIVE_ADDR_SPACE_NEEDS_INIT;
static WDC_ADDR_MODE mode = WDC_MODE_8;
static BOOL fBlock = FALSE;
/* Initialize active address space */
if (ACTIVE_ADDR_SPACE_NEEDS_INIT == dwAddrSpace)
{
DWORD dwNumAddrSpaces = PCI_GetNumAddrSpaces(hDev);
/* Find the first active address space */
for (dwAddrSpace = 0; dwAddrSpace < dwNumAddrSpaces; dwAddrSpace++)
{
if (WDC_AddrSpaceIsActive(hDev, dwAddrSpace))
break;
}
/* Sanity check */
if (dwAddrSpace == dwNumAddrSpaces)
{
PCI_ERR("MenuReadWriteAddr: Error - no active address spaces found\n");
dwAddrSpace = ACTIVE_ADDR_SPACE_NEEDS_INIT;
return;
}
}
do
{
printf("\n");
printf("Read/write the device's memory and IO ranges\n");
printf("---------------------------------------------\n");
printf("%d. Change active address space for read/write "
"(currently: BAR %ld)\n", MENU_RW_ADDR_SET_ADDR_SPACE, dwAddrSpace);
printf("%d. Change active read/write mode (currently: %s)\n",
MENU_RW_ADDR_SET_MODE,
(WDC_MODE_8 == mode) ? "8 bit" : (WDC_MODE_16 == mode) ? "16 bit" :
(WDC_MODE_32 == mode) ? "32 bit" : "64 bit");
printf("%d. Toggle active transfer type (currently: %s)\n",
MENU_RW_ADDR_SET_TRANS_TYPE,
(fBlock ? "block transfers" : "non-block transfers"));
printf("%d. Read from active address space\n", MENU_RW_ADDR_READ);
printf("%d. Write to active address space\n", MENU_RW_ADDR_WRITE);
printf("%d. Test the pci card\n",MENU_RW_ADDR_TEST);
printf("%d. Exit menu\n", MENU_RW_ADDR_EXIT);
printf("\n");
if (DIAG_INPUT_FAIL == DIAG_GetMenuOption(&option,
MENU_RW_ADDR_TEST))
{
continue;
}
switch (option)
{
case MENU_RW_ADDR_EXIT: /* Exit menu */
break;
case MENU_RW_ADDR_SET_ADDR_SPACE: /* Set active address space for read/write address requests */
{
SetAddrSpace(hDev, &dwAddrSpace);
break;
}
case MENU_RW_ADDR_SET_MODE: /* Set active mode for read/write address requests */
WDC_DIAG_SetMode(&mode);
break;
case MENU_RW_ADDR_SET_TRANS_TYPE: /* Toggle active transfer type */
fBlock = !fBlock;
break;
case MENU_RW_ADDR_READ: /* Read from a memory or I/O address */
case MENU_RW_ADDR_WRITE: /* Write to a memory or I/O address */
{
WDC_DIRECTION direction =
(MENU_RW_ADDR_READ == option) ? WDC_READ : WDC_WRITE;
if (fBlock)
WDC_DIAG_ReadWriteBlock(hDev, direction, dwAddrSpace);
else
WDC_DIAG_ReadWriteAddr(hDev, direction, dwAddrSpace, mode);
break;
}
case MENU_RW_ADDR_TEST:
TestSequence(hDev);
break;
}
} while (MENU_RW_ADDR_EXIT != option);
}
static void SetAddrSpace(WDC_DEVICE_HANDLE hDev, PDWORD pdwAddrSpace)
{
DWORD dwAddrSpace;
DWORD dwNumAddrSpaces = PCI_GetNumAddrSpaces(hDev);
PCI_ADDR_SPACE_INFO addrSpaceInfo;
printf("\n");
printf("Select an active address space:\n");
printf("-------------------------------\n");
for (dwAddrSpace = 0; dwAddrSpace < dwNumAddrSpaces; dwAddrSpace++)
{
BZERO(addrSpaceInfo);
addrSpaceInfo.dwAddrSpace = dwAddrSpace;
if (!PCI_GetAddrSpaceInfo(hDev, &addrSpaceInfo))
{
PCI_ERR("SetAddrSpace: Error - Failed to get address space information: %s",
PCI_GetLastErr());
return;
}
printf("%ld. %-*s %-*s %s\n",
dwAddrSpace + 1,
MAX_NAME_DISPLAY, addrSpaceInfo.sName,
MAX_TYPE - 1, addrSpaceInfo.sType,
addrSpaceInfo.sDesc);
}
printf("\n");
if (DIAG_INPUT_SUCCESS != DIAG_InputDWORD((PVOID)&dwAddrSpace,
"Enter option", FALSE, 1, dwNumAddrSpaces))
{
return;
}
dwAddrSpace--;
if (!WDC_AddrSpaceIsActive(hDev, dwAddrSpace))
{
printf("You have selected an inactive address space\n");
return;
}
*pdwAddrSpace = dwAddrSpace;
}
/*-------------------------------------------------*/
static void TestSequence(WDC_DEVICE_HANDLE hDev)
{
PWDC_DEVICE pDev=(PWDC_DEVICE)hDev;// 硬件地址
WDC_ADDR_DESC *pAddrDesc;
BOOL fIsMemory;
WD_ITEMS *pItem;
DWORD dwAddr;
DWORD dwStatus;
DWORD dwAddrSpace=2;
UCHAR Keyd,i;
BYTE bData=0,bDataTemp;
UINT32 u32Data=0;
static int ErrTimes=0;
pAddrDesc = &pDev->pAddrDesc[0];
fIsMemory = WDC_ADDR_IS_MEM(pAddrDesc);
pItem = &pDev->cardReg.Card.Item[pAddrDesc->dwItemIndex];
dwAddr = fIsMemory ? pItem->I.Mem.dwPhysicalAddr : (DWORD)pItem->I.IO.dwAddr;
printf("\n");
printf("Write and read random :\n");
printf("-------------------------------\n");
printf("Write to 0x%0*lX - 0x%0*lX (4 bytes)\n",
(int)WDC_SIZE_32 * 2, dwAddr+4,
(int)WDC_SIZE_32 * 2, dwAddr+8);
printf("Read from 0x%0*lX - 0x%0*lX (4 bytes)\n\n",
(int)WDC_SIZE_32 * 2, dwAddr,
(int)WDC_SIZE_32 * 2, dwAddr+3);
printf("Yes/No?('Y'continue the test else exit )");
fgets(gsInput, sizeof(gsInput), stdin);
sscanf(gsInput, "%c", &Keyd);
if(Keyd!='Y')
{
return;
}
WDC_WriteAddr32(hDev, 0, 0x28, 0x20);// 修改命令字
WDC_WriteAddr32(hDev, 0, 0x4c, 0x0103);
dwStatus=WDC_WriteAddr32(hDev, 0, 0x50, 0x17609000);
if (WD_STATUS_SUCCESS == dwStatus)
{
printf("Initialize succeed.\n");
}
else
return;
dwStatus=WDC_ReadAddr8(hDev, dwAddrSpace, 0, &bData);//打开通道?
/*---------------------------------------------------------------
while(WDC_ReadAddr32(hDev, 0, 0x4c, &u32Data)==0) //监听中断
{
if(u32Data&0x04)
{
for(i=0;i<4;i++)
{
dwStatus=WDC_ReadAddr8(hDev, dwAddrSpace, i, &bData);
if (WD_STATUS_SUCCESS == dwStatus)
{
printf("%s 0x%0*lX %s offset 0x%0*lX in BAR %ld\n",
(WDC_READ == 1) ? "Read" : "Write", 2,(UINT32)bData,
(WDC_READ == 1) ? "from" : " to ",2,i, dwAddrSpace);
}
else
{
printf("Error1! (Read Error)\n");
return;
}
}
if(WDC_WriteAddr32(hDev, 0, 0x4c, (u32Data|0x400)))
{
printf("Error2! (Write Error)\n");
return;
}
}
}
return;
----------------------------------------------*/
while(1) //连续测试
{
for(i=0;i<4;i++)
{
bData=rand()%0x100;
if (WDC_WriteAddr8(hDev, dwAddrSpace, 4+i, bData))
{
printf("\nError1!(Write Error)");
return;
}
if (WDC_ReadAddr8(hDev, dwAddrSpace, i, &bDataTemp)) //读
{
printf("\nError2!(Read Error)");
return;
}
if (bDataTemp!=bData)
{
printf("%s 0x%0*lX %s offset 0x%0*lX in BAR %ld ",
(WDC_READ == 0) ? "Read" : "Write", 2,(UINT32)bData,
(WDC_READ == 0) ? "from" : " to ",2,4+i, dwAddrSpace);
printf("%s 0x%0*lX %s offset 0x%0*lX in BAR %ld\n",
(WDC_READ == 1) ? "Read" : "Write", 2,(UINT32)bDataTemp,
(WDC_READ == 1) ? "from" : " to ",2,i, dwAddrSpace);
if(++ErrTimes%8==0)
{
printf("Error3! (Verify Error)\n");
printf("The totale error times=%d\n\n",ErrTimes);
return;
}
}
}
}
return;
/*---------------------------------------------------*/
fgets(gsInput, sizeof(gsInput), stdin);
while(Keyd!=0)
{
for(i=0;i<4;i++)
{
bData=rand()%0x100;
dwStatus=WDC_WriteAddr8(hDev, dwAddrSpace, 4+i, bData);//连续写
if (WD_STATUS_SUCCESS == dwStatus)
{
printf("%s 0x%0*lX %s offset 0x%0*lX in BAR %ld ",
(WDC_READ == 0) ? "Read" : "Write", 2,(UINT32)bData,
(WDC_READ == 0) ? "from" : " to ",2,4+i, dwAddrSpace);
}
dwStatus=WDC_ReadAddr8(hDev, dwAddrSpace, i, &bData); //连续读
if (WD_STATUS_SUCCESS == dwStatus)
{
printf("%s 0x%0*lX %s offset 0x%0*lX in BAR %ld\n",
(WDC_READ == 1) ? "Read" : "Write", 2,(UINT32)bData,
(WDC_READ == 1) ? "from" : " to ",2,i, dwAddrSpace);
}
}
fgets(gsInput, sizeof(gsInput), stdin);
sscanf(gsInput, "%d", &Keyd);
}
};
/* -----------------------------------------------
Read/write the configuration space
----------------------------------------------- */
/* Read/write the configuration space menu options */
enum {
MENU_RW_CFG_SPACE_READ_OFFSET = 1,
MENU_RW_CFG_SPACE_WRITE_OFFSET,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -