sdbtest.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,249 行 · 第 1/4 页

C
1,249
字号
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995, 1996, 1997, 1998  Microsoft Corporation

Module Name:  
    sdbtest.c

Abstract:  
    Main file for the tests.  Contains all high level testing
	routines.

Functions:


Notes: 

--*/
#include "platform.h"
#include "common.h"
#include "stdio.h"

// PUT_PCI_DELAY is defined in shx\platform.h if required.

#define TRIGGER				/* Nothing */ /* { *(volatile unsigned long *)0xb8000000 = 73; } */

#ifdef PUT_PCI_DELAY
/* This would put in a delay every my_buffer_size accesses. */
#define MY_DELAY 		{ if( !(num_access ++ % my_buffer_size) ) { 	\
							for(glbl_wait = 0; glbl_wait < my_wait; glbl_wait ++);	\
						  }	\
						}
#else
#define MY_DELAY		/* Nothing. */ /* My Delay was used for PCI debugging to put delays between every two accesses */
#endif
							

int my_wait = 0, glbl_wait = 1000, num_access = 0, my_buffer_size = 0;
int StopNext = 1;

int SDBTEST_main( void ) {

	PCIHostBridgeWindowInfoRec PCIHostBridgeWindowInfo;

	/* First turn on the debug output mechanism.  This is where the DbgPrintf()	*/
	/*	output goes and for the most part this will be a serial port running at	*/
	/*	38400,N,8,1.															*/
	OEM_DbgOutputInit();

	/* Now initialize the host bridge so that PCI configuration accesses can	*/
	/*	be performed and so that the PCI memory and I/O windows function.		*/
	/*	Note that this may have already been done in OEM_InitDebugOutput() if	*/
	/*	the output device is attached via the PCI interface.					*/
	/* This function should set the bus number of the PCI segment connected to	*/
	/*	the CPU to 0.															*/
	if (OEM_InitPCIHostBridge()) {
		DbgPrintf( "main() - ERROR: PCI Host Bridge Initialization Failed\n" );
	}

	/* Get the specifications for the PCI memory windows we have to work in.	*/
	OEM_GetPCIHostBridgeWindowInfo( &PCIHostBridgeWindowInfo );
	if (PCIHostBridgeWindowInfo.dwMemWinSize < 16*1024*1024) { // NKCH. Microsoft stated 64 Mb here.
		DbgPrintf( "VIOLATION: PCI Memory Window Size Is 0x%08lX\n", PCIHostBridgeWindowInfo.dwMemWinSize );
	}
	if (PCIHostBridgeWindowInfo.dwIOWinSize < 256*1024) {
		DbgPrintf( "VIOLATION: PCI I/O Window Size Is 0x%08lX\n", PCIHostBridgeWindowInfo.dwIOWinSize );
	}

	return RunTests();

} /* main() */



/* This is the main routine that is responsible for running the tests.  It will	*/
/*	configure the PCI bus by enumerating the segments and then it will find the	*/
/*	RIO device.  After that it will run the memory and I/O tests.				*/
int RunTests( void ) {

	PCIDevIDRec RIODevID;
	PCIDevAddrRec RIO;
	WORD wRevision;
	BYTE bLastBusNo;

	DbgPrintf("+RunTests()\n");

	/* Now I'll find the bus number and device number for the RIO board and the	*/
	/*	VMETRO board.  This may involve initializing several PCI-PCI bridges	*/
	/*	before I find the PCI segment for the backplane.  One that segment I	*/
	/*	should be able to find the RIO board and the VMETRO board.				*/

	/* First, I must enumerate all the busses.  This involved searching for		*/
	/*	PCI-PCI bridges and assigning primary, secondary and subordinate bus	*/
	/*	numbers to them.														*/
	/* The recursive routine needs a seed variable to get started.  I'll just	*/
	/*	use the RIO structure.													*/
	bLastBusNo = 0;
	RIO.bParentDevNo = RIO.bDevNo = 0xFF;
	if (EnumeratePCIBuses( &RIO, &bLastBusNo )) {
		DbgPrintf( "RunTests() - ERROR: EnumeratePCIBuses() Failed\n" );
		return 1;
	}

	DbgPrintf( "PCI Buses Enumerated, Last Bus Number is %d\n", bLastBusNo );

	// Instead of doing tests on the RIO card, i'm doing tests on the
	// IGS display card.
#if 1
	/* Find the RIO card.  Note that the lower 4 bits of the Subsystem ID are	*/
	/*	used as revision numbers, so we must look for all of those combinations.*/
	RIODevID.wVendorID = 0x8086;
	RIODevID.wDeviceID = 0x0960;
	RIODevID.wSubsystemVendorID = 0x1414;
	RIODevID.wSubsystemID = 0x0030;
	for( wRevision = 0; wRevision < 16; wRevision++ ) {
		RIO.bParentDevNo = RIO.bDevNo = 0xFF;
		if (FindNextPCIDevice( &RIODevID, &RIO )) {
			DbgPrintf( "RunTests() - ERROR: Call To FindNextPCIDevice() Failed\n" );
			return 1;
		}
		if (RIO.bDevNo != 0xFF)
			break;
		RIODevID.wSubsystemID++;
	}
	if (RIO.bDevNo == 0xFF) {
		DbgPrintf( "RunTests() - ERROR: RIO Not Found\n" );
		return 1;
	}
	DbgPrintf( "RIO Found at Bus %d, Device %d\n", RIO.bBusNo, RIO.bDevNo );

#if 1
	if (TestMemory( &RIO ))
		DbgPrintf( "TestMemory() Failed!\n" );
#endif

	// skip test_io.
	// ProcessCommands();
	if (TestIO( &RIO )) {
		DbgPrintf( "TestIO() Failed!\n" );
		return;
	}

	return 0;

	// No need to do rest of the stuff. That was done only to try out.
#endif
	{
		PCIDevIDRec IGSDevID;
		PCIDevAddrRec IGS;
		unsigned long BaseReg0;
		unsigned long tmp;

#if (SH_PLATFORM==PLATFORM_ASPEN)
		// Look up the PCI bus, idsel 3 and get device ID and vendor ID
		OEM_ReadConfigDword( 0, 0, 0, 0x0, &BaseReg0);
		DbgPrintf("Device ID = 0x%x, Vendor ID = 0x%x\n", BaseReg0 >> 16, BaseReg0 & 0xFFFF);
#elif (SH_PLATFORM==PLATFORM_BIGSUR)
		// Look up the PCI bus, idsel 3 and get device ID and vendor ID
		OEM_ReadConfigDword( 0, 0, 0, 0x0, &BaseReg0);
		DbgPrintf("Device ID = 0x%x, Vendor ID = 0x%x\n", BaseReg0 >> 16, BaseReg0 & 0xFFFF);
#endif (SH_PLATFORM==PLATFORM_ASPEN)
		
	// 0: S3, 1: IGS
#if 1
		IGSDevID.wVendorID =  0x10ea; // , S3: 0x5333
		IGSDevID.wDeviceID = 0; // 0x5000
#else
		IGSDevID.wVendorID = 0x5333; // IGS: 0x10ea, S3: 0x5333
		IGSDevID.wDeviceID = 0; // 0x5000
#endif
		IGSDevID.wSubsystemVendorID = 0x0;
		IGSDevID.wSubsystemID = 0x0;

		IGS.bParentDevNo = IGS.bDevNo = 0xFF;

		if (FindNextPCIDevice( &IGSDevID, &IGS )) {
			DbgPrintf( "RunTests() - ERROR: Call To FindNextPCIDevice(IGS) Failed\n" );
			return 1;
		}
		if (IGS.bDevNo == 0xFF) {
			DbgPrintf( "RunTests() - ERROR: IGS Device Not Found\n" );
			return 1;
		}
		DbgPrintf( "IGS Found at Bus %d, Device %d\n", IGS.bBusNo, IGS.bDevNo );
		// Set the IGS Base Address and enable IO and Memory Read Writes.
		//void OEM_ReadConfigWord( DWORD dwBusNo, DWORD dwDevNo, DWORD dwFuncNo, DWORD dwOffset, WORD *pwData ) {
		OEM_ReadConfigDword( IGS.bBusNo, IGS.bDevNo, 0, 0x10, &BaseReg0);
		DbgPrintf( "BaseReg0 reads as 0x%x \n", BaseReg0);

		// Write 0 to the base register. 
		BaseReg0 = 0;
		OEM_WriteConfigDword( IGS.bBusNo, IGS.bDevNo, 0, 0x10, BaseReg0);
		OEM_ReadConfigDword( IGS.bBusNo, IGS.bDevNo, 0, 0x10, &BaseReg0);
		DbgPrintf( "BaseReg0 Now reads as 0x%x \n", BaseReg0);

		// Enable IO and Memory areas on the card.
		// Read the Command/Status register
		OEM_ReadConfigDword( IGS.bBusNo, IGS.bDevNo, 0, 0x4, &tmp);
		DbgPrintf( "Command Status register reads as 0x%x \n", tmp);
		// Write 3 to enable.
		tmp = 3;
		OEM_WriteConfigDword( IGS.bBusNo, IGS.bDevNo, 0, 0x4, tmp);
		OEM_ReadConfigDword( IGS.bBusNo, IGS.bDevNo, 0, 0x4, &tmp);
		DbgPrintf( "Command Status register Now reads as 0x%x \n", tmp);

		// Now your card is enabled. You should be able to run your device
		// driver now.
	{
		unsigned char ctmp;
		/* Check out a few things for the IGS card. */

#if (SH_PLATFORM==PLATFORM_ASPEN)
		unsigned base = 0xA4300000;  // Base address for PCI Io space
#elif (SH_PLATFORM==PLATFORM_BIGSUR)
		unsigned base = 0xA4300000;  // Base address for PCI Io space
#else (SH_PLATFORM==PLATFORM_ASPEN)
		unsigned base = 0xA5000000;
#endif (SH_PLATFORM==PLATFORM_ASPEN)

		*(volatile unsigned char *) (base + 0x46e8) = 0x18;
		*(volatile unsigned char *) (base + 0x0102) = 0x01;
		*(volatile unsigned char *) (base + 0x46e8) = 0x08;

#if 0
		base = 0xA4800000; 
		*(volatile unsigned short *) 0xA6000004 = 0xFBFF;
#endif
		
		*(volatile unsigned char *) (base + 0x03ce) = 0x92;
		ctmp = *(volatile unsigned char *) (base + 0x03cf);
		DbgPrintf( "0x92 reads as 0x%x \n", ctmp);
	}
		
	}

	return 0;

} /* RunTests() */



/* This function runs the memory tests.  These use the shared RAM on the	*/
/*	RIO as the memory to test against.  First the amount of contiguous RAM	*/
/*	on the RIO is determined, and then the routine will run a series of		*/
/*	tests on the memory addressing and data transfer capabilities.  It will	*/
/*	move the host memory window and the RIO base address so that all of the	*/
/*	address combinations are exercised.										*/
int TestMemory( PCIDevAddrRec *pRIO ) {

	PCIHostBridgeWindowInfoRec PCIHostBridgeWindowInfo;
	DWORD dwRIORAMWindowSize, dwRIOContigRAMSize;
	DWORD dwTemp, dwPCISharedRAMBase1, dwPCISharedRAMBase2;
	DWORD dwNumPasses;
	BYTE bRAMTestPhase, bRAMAccessWidth;

	/* Get the size and starting address for the Host Bridge PCI memory window we have to work in.	*/
	OEM_GetPCIHostBridgeWindowInfo( &PCIHostBridgeWindowInfo );
	DbgPrintf( "Host Bridge Memory Windows Size is 0x%08lX\n",
		PCIHostBridgeWindowInfo.dwMemWinSize );

	/* Find the biggest contiguous piece of RAM on RIO */
	if (DetectRIORAM( pRIO, &dwRIORAMWindowSize, &dwRIOContigRAMSize )) {
		DbgPrintf( "TestMemory() - ERROR: Call To DetectRIORAM() Failed\n" );
		return 1;
	}

	DbgPrintf( "Detected RAM Window is 0x%08lX, Detected Contiguous RAM is 0x%08lX\n",
		dwRIORAMWindowSize, dwRIOContigRAMSize );

	/* First I'll do two passes through the memory testing that		*/
	/*	test the limits of addressing the PCI address range.  This	*/
	/*	will force the use of the PCI memory paging registers in	*/
	/*	the host bridge by switching between high and low address	*/
	/*	ranges at each phase of RAM testing.						*/
	/* Create a base address to use for the shared RAM	*/
	DbgPrintf( "TestMemory() - Testing PCI Paging Register Limits\n" );
	dwPCISharedRAMBase1 = 0;

	for( dwTemp = PCIHostBridgeWindowInfo.dwMemWinSize; dwTemp; dwTemp <<= 2 )
		dwPCISharedRAMBase1 |= dwTemp;
	dwPCISharedRAMBase2 = (~dwPCISharedRAMBase1 & ~(PCIHostBridgeWindowInfo.dwMemWinSize-1));
	bRAMAccessWidth = 32;

#if 0
	DbgPrintf("TM: dwMemWinSize = 0x%x, dwPCISharedRAMBase1 = 0x%x, 2 = 0x%x\n", 
		PCIHostBridgeWindowInfo.dwMemWinSize, dwPCISharedRAMBase1, dwPCISharedRAMBase2);
	// Hardcoding just to see why it does not work.
	dwPCISharedRAMBase1 = 0;
	dwPCISharedRAMBase2 = 0xF0000000;
#endif 1

#if 0
	{
		extern int my_RAW, my_TP, my_Single;
		if(my_Single) {
			bRAMAccessWidth = my_RAW;
			bRAMTestPhase = my_TP;
			if (TestRAMRegion( pRIO, bRAMTestPhase, bRAMAccessWidth,
				dwPCISharedRAMBase1, 4096, dwRIOContigRAMSize/2 - 4096 )) {
				DbgPrintf( "TestMemory() - ERROR: Bank 1 Call To TestRAMRegion() Failed\n" );
				return 1;
			}
		return 0;
		}
	}
#endif 1
	for( dwNumPasses = 0; dwNumPasses < 2; dwNumPasses++ ) {
		for( bRAMTestPhase = 1; bRAMTestPhase < 4; bRAMTestPhase++ ) {
			/* Do this phase on the first half of the shared RAM	*/
			/*	using the first base address.						*/
			/* Remember to stay out of the lower 4K of RAM because	*/

⌨️ 快捷键说明

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