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 + -
显示快捷键?