sdbtest.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,249 行 · 第 1/4 页
C
1,249 行
OEM_WriteConfigDword( pRIO->bBusNo, pRIO->bDevNo, 1, 0x48, dwSharedRAMBase );
if ((wPCIStatus = GetPCIBridgeStatus( pRIO )) != 0) {
ClearPCIBridgeStatus( pRIO );
DbgPrintf( "InitI960() - ERROR: Can't Write Secondary Inbound ATU Base Address Register\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* Set the ATU's command register to allow I/O and Memory transactions as well */
/* as DMA and other operations. */
OEM_WriteConfigWord( pRIO->bBusNo, pRIO->bDevNo, 1, 0x04, 0x0156 );
if ((wPCIStatus = GetPCIBridgeStatus( pRIO )) != 0) {
ClearPCIBridgeStatus( pRIO );
DbgPrintf( "InitI960() - ERROR: Can't Write Primary ATU Command Register\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/************************************************************************************/
/* Set the bridge's command register to allow I/O and Memory transactions as */
/* well as DMA and other operations. */
OEM_WriteConfigWord( pRIO->bBusNo, pRIO->bDevNo, 0, 0x04, 0x0147 );
if ((wPCIStatus = GetPCIBridgeStatus( pRIO )) != 0) {
ClearPCIBridgeStatus( pRIO );
DbgPrintf( "InitI960() - ERROR: Can't Write Primary Bridge Command Register\n" );
PrintPCIError( wPCIStatus );
return 1;
}
return 0;
} /* InitI960() */
/* This routine will exercise the I/O functionality of the SDB. It does this */
/* by running against I/O registers that are found in the RIO ethernet chip. */
/* The base address of the ethernet chip is moved so that accesses are */
/* performed across the entire lower 64K range of the I/O space that the RIO */
/* PCI-PCI bridge allows. */
int TestIO( PCIDevAddrRec *pRIO ) {
PCIHostBridgeWindowInfoRec PCIHostBridgeWindowInfo;
PCIDevAddrRec Ethernet, PC87560, PCIStartDev;
PCIMapInfoRec PCIMapInfo;
PCIDevIDRec PCIDevID;
DWORD dwIOBaseAddr;
WORD wPCIStatus;
BYTE bAccessWidth;
int iReg;
volatile BYTE *pvbRegister;
volatile WORD *pvwRegister;
volatile DWORD *pvdwRegister;
BYTE bReadData;
WORD wReadData;
DWORD dwReadData, dwWriteData, dwVerificationData;
#ifdef NKCH
{
// Clear PCI Bridge Status
ClearPCIBridgeStatus( pRIO );
DbgPrintf( "\n\n+TestIO\n" );
StopNext = 1;
}
#endif 1
/* First I must disable all the devices on the PC87560 that come up enabled by */
/* default. These violate the PCI spec. in that they are not disabled after */
/* reset and they cannot be disabled by writing the PCI command register. */
/* Note that we start searching from the RIO i960 bridge itself. That we we */
/* will be sure to find the DEC21143 on the RIO and not some other chip in the */
/* system. */
PCIDevID.wVendorID = 0x100B;
PCIDevID.wDeviceID = 0x0002;
PCIDevID.wSubsystemVendorID = 0;
PCIDevID.wSubsystemID = 0;
PC87560 = *pRIO;
if (FindNextPCIDevice( &PCIDevID, &PC87560 )) {
DbgPrintf( "TestIO() - ERROR: Call To FindNextPCIDevice() Failed\n" );
return 1;
}
if (PC87560.bDevNo == 0xFF) {
DbgPrintf( "TestIO() - ERROR: PC87560 Not Found\n" );
return 1;
}
DbgPrintf( "PC87560 Found at Bus %d, Device %d\n", PC87560.bBusNo, PC87560.bDevNo );
OEM_WriteConfigWord( PC87560.bBusNo, PC87560.bDevNo, 1, 0x5A, 0 );
if ((wPCIStatus = GetPCIBridgeStatus( &PC87560 )) != 0) {
ClearPCIBridgeStatus( &PC87560 );
DbgPrintf( "TestIO() - ERROR: Can't Disable PC87560 Devices\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* Find the DEC21143 ethernet MAC chip. Note that we start searching from the */
/* RIO i960 bridge itself. That we we will be sure to find the DEC21143 on */
/* the RIO and not some other chip in the system. */
PCIDevID.wVendorID = 0x1011;
PCIDevID.wDeviceID = 0x0019;
PCIDevID.wSubsystemVendorID = 0;
PCIDevID.wSubsystemID = 0;
Ethernet = *pRIO;
if (FindNextPCIDevice( &PCIDevID, &Ethernet )) {
DbgPrintf( "TestIO() - ERROR: Call To FindNextPCIDevice() Failed\n" );
return 1;
}
if (Ethernet.bDevNo == 0xFF) {
DbgPrintf( "TestIO() - ERROR: Ethernet Not Found\n" );
return 1;
}
DbgPrintf( "Ethernet Found at Bus %d, Device %d\n", Ethernet.bBusNo, Ethernet.bDevNo );
/* Get the size and starting address for the Host Bridge PCI memory window we */
/* have to work in. */
OEM_GetPCIHostBridgeWindowInfo( &PCIHostBridgeWindowInfo );
/* There are four 32-bit registers that I can use on the chip. I need to test */
/* the address lines of the host bridge by moving these around in PCI I/O */
/* address space. Since the RIO PCI-PCI bridge only allows the registers to */
/* be mapped into the lower 64K PCI address range, my options are somewhat */
/* limited. Also, the base address for the ethernet I/O regsters must be */
/* 7-bit aligned. */
/* I'll rotate through the four registers, moving the base address used to */
/* access them each time. The value written to each register will be the */
/* address used to write to it. */
bAccessWidth = 32;
dwWriteData = 0x80000000;
#ifdef PUT_PCI_DELAY
{
if(StopNext) {
DbgPrintf("\nTestIO, AccessWidth = %d\n", bAccessWidth);
DbgPrintf("Enter wait loops at 0x8c000004\n");
ProcessCommands();
my_wait = *(volatile unsigned *)0x8c000004;
StopNext = *(volatile unsigned *)0x8c00000C;
DbgPrintf("my_wait = 0x%x, StopNext = %d\n", my_wait, StopNext);
}
}
#endif PUT_PCI_DELAY
for( dwIOBaseAddr = 0; dwIOBaseAddr < 64*1024; dwIOBaseAddr += 0x0080 ) {
if (InitEthernet( &Ethernet, dwIOBaseAddr )) {
DbgPrintf( "TestIO() - ERROR: Call To InitEthernet() Failed\n" );
return 1;
}
/* Open the I/O windows for all bridges, including the host bridge and the */
/* bridge on the RIO. */
PCIMapInfo.dwPCIMemBase = 0xFFFFFFFF;
PCIMapInfo.dwPCIMemLimit = 0;
PCIMapInfo.dwPCIIOBase = PCIMapInfo.dwPCIIOLimit = dwIOBaseAddr;
PCIStartDev.bParentDevNo = PCIStartDev.bDevNo = 0xFF;
if (MapPCIWindows( &PCIMapInfo, &PCIStartDev, &Ethernet )) {
DbgPrintf( "TestIO() - ERROR: MapPCIWindows() Failed\n" );
return 1;
}
/* Read the four registers using the new base address and checking */
/* for the value that was written to them. */
pvdwRegister = (volatile DWORD *)pvwRegister = (volatile WORD *)pvbRegister =
(volatile BYTE *)(PCIHostBridgeWindowInfo.dwIOWinBase + dwIOBaseAddr + 24);
for( iReg = 3; iReg <= 4; iReg++ ) {
dwVerificationData = (dwWriteData & 0x80000000) ? 0x00000004 : (dwWriteData << 1);
dwWriteData = (dwWriteData & 0xFFFFFFF8) ? (dwWriteData >> 1) : 0x80000000;
switch( bAccessWidth ) {
case 8:
bReadData = *pvbRegister;
// DbgPrintf("B:dwIOBaseAddr = 0x%x, pvdwRegister=0x%x, dwReadData=0x%x, dwVerificationData=0x%x\n", dwIOBaseAddr, pvdwRegister, dwReadData, dwVerificationData);
DbgPrintf("B:dwIOBaseAddr = 0x%x, pvdwRegister=0x%x, dwReadData=0x%x, dwVerificationData=0x%x\n", dwIOBaseAddr, pvdwRegister, dwReadData, dwVerificationData);
if (dwIOBaseAddr && bReadData != (BYTE)dwVerificationData) {
DbgPrintf( "TestIO() - ERROR: PCI Addr 0x%08lX, Wrote 0x%02X, Read 0x%02X\n",
(DWORD)pvbRegister - PCIHostBridgeWindowInfo.dwIOWinBase,
(BYTE)dwVerificationData, bReadData );
return 1;
}
*pvbRegister++ = (BYTE)dwWriteData;
bReadData = *pvbRegister;
if (dwIOBaseAddr && bReadData != (BYTE)(dwVerificationData >> 8)) {
DbgPrintf( "TestIO() - ERROR: PCI Addr 0x%08lX, Wrote 0x%02X, Read 0x%02X\n",
(DWORD)pvbRegister - PCIHostBridgeWindowInfo.dwIOWinBase,
(BYTE)(dwVerificationData >> 8), bReadData );
return 1;
}
*pvbRegister++ = (BYTE)(dwWriteData >> 8);
bReadData = *pvbRegister;
if (dwIOBaseAddr && bReadData != (BYTE)(dwVerificationData >> 16)) {
DbgPrintf( "TestIO() - ERROR: PCI Addr 0x%08lX, Wrote 0x%02X, Read 0x%02X\n",
(DWORD)pvbRegister - PCIHostBridgeWindowInfo.dwIOWinBase,
(BYTE)(dwVerificationData >> 16), bReadData );
return 1;
}
*pvbRegister++ = (BYTE)(dwWriteData >> 16);
bReadData = *pvbRegister;
if (dwIOBaseAddr && bReadData != (BYTE)(dwVerificationData >> 24)) {
DbgPrintf( "TestIO() - ERROR: PCI Addr 0x%08lX, Wrote 0x%02X, Read 0x%02X\n",
(DWORD)pvbRegister - PCIHostBridgeWindowInfo.dwIOWinBase,
(BYTE)(dwVerificationData >> 24), bReadData );
return 1;
}
*pvbRegister = (BYTE)(dwWriteData >> 24);
pvbRegister += 5;
break;
case 16:
wReadData = *pvwRegister;
// DbgPrintf("S:dwIOBaseAddr = 0x%x, pvdwRegister=0x%x, dwReadData=0x%x, dwVerificationData=0x%x\n", dwIOBaseAddr, pvdwRegister, dwReadData, dwVerificationData);
DbgPrintf("S:dwIOBaseAddr = 0x%x, pvdwRegister=0x%x, dwReadData=0x%x, dwVerificationData=0x%x\n", dwIOBaseAddr, pvdwRegister, dwReadData, dwVerificationData);
if (dwIOBaseAddr && wReadData != (WORD)dwVerificationData) {
DbgPrintf( "TestIO() - ERROR: PCI Addr 0x%08lX, Wrote 0x%04X, Read 0x%04X\n",
(DWORD)pvdwRegister - PCIHostBridgeWindowInfo.dwIOWinBase,
(WORD)dwVerificationData, wReadData );
return 1;
}
*pvwRegister++ = (WORD)dwWriteData;
wReadData = *pvwRegister;
if (dwIOBaseAddr && wReadData != (WORD)(dwVerificationData >> 16)) {
DbgPrintf( "TestIO() - ERROR: PCI Addr 0x%08lX, Wrote 0x%04X, Read 0x%04X\n",
(DWORD)pvwRegister - PCIHostBridgeWindowInfo.dwIOWinBase,
(WORD)(dwVerificationData >> 16), wReadData );
return 1;
}
*pvwRegister = (WORD)(dwWriteData >> 16);
pvdwRegister += 3;
break;
case 32:
dwReadData = *pvdwRegister;
// DbgPrintf("L:dwIOBaseAddr = 0x%x, pvdwRegister=0x%x, dwReadData=0x%x, dwVerificationData=0x%x\n", dwIOBaseAddr, pvdwRegister, dwReadData, dwVerificationData);
DbgPrintf("L:dwIOBaseAddr = 0x%x, pvdwRegister=0x%x, dwReadData=0x%x, dwVerificationData=0x%x\n", dwIOBaseAddr, pvdwRegister, dwReadData, dwVerificationData);
if (dwIOBaseAddr && dwReadData != dwVerificationData) {
DbgPrintf( "TestIO() - ERROR: PCI Addr 0x%08lX, Wrote 0x%08lX, Read 0x%08lX\n",
(DWORD)pvdwRegister - PCIHostBridgeWindowInfo.dwIOWinBase,
dwVerificationData, dwReadData );
return 1;
}
/* Write the access address into the register, note that the registers */
/* are 32-bits wide, but they are on 64-bit boundaries, hence the *8. */
*pvdwRegister = dwWriteData;
pvdwRegister += 2;
break;
}
}
#if 1
for(glbl_wait = 0; glbl_wait < my_wait; glbl_wait ++);
#endif 1
/* After every register pass, check for PCI errors */
if ((wPCIStatus = GetPCIBridgeStatus( &Ethernet )) != 0) {
ClearPCIBridgeStatus( &Ethernet );
DbgPrintf( "TestIO() - ERROR: PCI Error Detected On I/O Access Near 0x%08lX\n", dwIOBaseAddr );
PrintPCIError( wPCIStatus );
return 1;
}
/* Rotate through the 8, 16 and 32-bit access widths */
/*
bAccessWidth <<= 1;
bAccessWidth = (bAccessWidth & 0x38) ? bAccessWidth : 8;
*/
}
DbgPrintf( "TestIO() - Successful\n" );
return 0;
} /* TestIO() */
/* This routine is used to initialize the PCI configuration space registers on the */
/* DEC21143 enough so that some of the registers can be used to test I/O space */
/* capabilities. */
int InitEthernet( PCIDevAddrRec *pEthernet, DWORD dwIOBaseAddr ) {
WORD wPCIStatus;
DbgPrintf("+InitEthernet(pEthernet=%x, dwIOBaseAddr = %x)\n", pEthernet, dwIOBaseAddr);
DbgPrintf("bBusNoe=%x, bDevNo=%x\n", pEthernet->bBusNo, pEthernet->bDevNo);
/* Write the I/O Base Address Register */
OEM_WriteConfigDword( pEthernet->bBusNo, pEthernet->bDevNo, 0, 0x10, dwIOBaseAddr );
if ((wPCIStatus = GetPCIBridgeStatus( pEthernet )) != 0) {
ClearPCIBridgeStatus( pEthernet );
DbgPrintf( "InitEthernet() - ERROR: Can't Write I/O Base Address\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* Set PCI command register to respond to I/O accesses, generate MWI cycles, */
/* allow bus mastering, generation parity and system errors */
/* Note that memory accesses are NOT enabled, though they are possible */
OEM_WriteConfigWord( pEthernet->bBusNo, pEthernet->bDevNo, 0, 0x04, 0x015D );
if ((wPCIStatus = GetPCIBridgeStatus( pEthernet )) != 0) {
ClearPCIBridgeStatus( pEthernet );
DbgPrintf( "InitEthernet() - ERROR: Can't Write PCI Command Register\n" );
PrintPCIError( wPCIStatus );
return 1;
}
/* Clear Sleep and Snooze mode bits in the CFDD to wake the part up */
OEM_WriteConfigDword( pEthernet->bBusNo, pEthernet->bDevNo, 0, 0x40, 0 );
if ((wPCIStatus = GetPCIBridgeStatus( pEthernet )) != 0) {
ClearPCIBridgeStatus( pEthernet );
DbgPrintf( "InitEthernet() - ERROR: Can't Write CFDD Register\n" );
PrintPCIError( wPCIStatus );
return 1;
}
DbgPrintf("-InitEthernet(pEthernet=%x, dwIOBaseAddr = %x)\n", pEthernet, dwIOBaseAddr);
return 0;
} /* InitEthernet */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?