⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmmprun.c

📁 wince host 和 target PCI驱动程序
💻 C
字号:
/*
 *  COPYRIGHT (c) 1997 by Philips Semiconductors
 *
 *   +-----------------------------------------------------------------+
 *   | THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED |
 *   | AND COPIED IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH  |
 *   | A LICENSE AND WITH THE INCLUSION OF THE THIS COPY RIGHT NOTICE. |
 *   | THIS SOFTWARE OR ANY OTHER COPIES OF THIS SOFTWARE MAY NOT BE   |
 *   | PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. THE   |
 *   | OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED.        |
 *   +-----------------------------------------------------------------+
 *
 *  Revision history         :
 *    10/26/96:  CJP		:	Tested and basically working.
 *								More error checking and reporting added.
 *
 *    970106:  Tilakraj Roy :	Added support for the TMCons in tmDSPRunExecutable.
 *								Commenetd the use of tmDSPRunExecutable
 *    970114:  Tilakraj Roy :	Added command line processing of windows size
 *    970128:  Tilakraj Roy :	Added tmDSPExecutableStop in exit function
 *    970327:  Tilakraj Roy :	Revamped the entire code for proper error handling
 *								Added the ExitEvent for proper cleanup.
 *    970630:  Tilakraj Roy :	Added multiprocessor support.
 *    970631:  Tilakraj Roy :	Added	new cruntime support.
 *    970728:  Tilakraj Roy :	Fixed exit code error bug.
 *
 *
 *  Description              :
 *
 *		This module is driver for the
 *		host part of the PC version of the Level 2
 *		Remote Procedure Call Server. An implementation
 *		of this is needed for each particular host of
 *		a TM-1 board which uses TCS's generic ANSI C library.
 *
 *		In its current form this module is intended to run as
 *		an independent executable that must be
 *		started from a PC command line. Its first argument
 *		must be the name of a TM-1 executable which is to be
 *		downloaded, started, and which is passed all additional
 *		command line arguments. Between starting the executable
 *		and receiving its termination message, this module behaves
 *		as a server for the HostCall interface.
 *
 */

/*---------------------------- Includes --------------------------------------*/

#include "windows.h"
#include "stdio.h"

#include "tmman32.h"
#include "tmtypes.h"
#include "tmcrt.h"
#include "tmif.h"
#include "TMDownLoader.h"


#define  PGM_MAJOR_VERSION (4)
#define  PGM_MINOR_VERSION (0)


DWORD       GlobalExitCode = (~0x0);
BOOL        Interactive = TRUE;

PCHAR       TargetExecutableName = NULL;
DWORD       TargetArgumentOffset;

BOOL WINAPI tmrunControlHandler(DWORD dwCtrlType);

#define		MAXIMUM_NODES		4
#define		MAXIMUM_COMMAND_LINE_ARGS	100

DWORD		DSPCount = 0;

HANDLE		EventArray[MAXIMUM_NODES];

STATUS	tmDSPExecutableLoadEx ( 
	DWORD DSPHandle, 
	PCHAR pszImagePath,
	DWORD NumberOfDSPs,
	TMDwnLdr_SharedSectionTab_Handle SharedSections,
	PDWORD	MMIOPhysicalAddressArray );

/*******************************************************************************/
int 
main(int argc, char *argv[])
{
	STATUS      Status;
	TMSTD_VERSION_INFO Version;

	TMMAN_DSP_CAPS DSPCaps;
	COORD       ConsoleSize;
	DWORD		wIdxArg;
	DWORD		CRTHandle[MAXIMUM_NODES];
	DWORD		DSPHandle[MAXIMUM_NODES];
	DWORD		ArgumentCountArray[MAXIMUM_NODES];
	PVOID		ArgumentVectorArray[MAXIMUM_NODES];
	DWORD		IdxNode;
	DWORD		ArgumentCount;
	DWORD		MMIOPhysicalAddressArray[MAXIMUM_NODES];
	CHAR*		ArgumentVector[MAXIMUM_COMMAND_LINE_ARGS];
	

	TMDwnLdr_SharedSectionTab_Handle SharedSections;

	if (argc == 1) 
	{
		goto mainUsage;
	}

	/* check for compatible driver version */
	Version.dwMajor = TMMAN_DEFAULT_VERSION_MAJ;
	Version.dwMinor = TMMAN_DEFAULT_VERSION_MIN;

	if ((Status = tmNegotiateVersion(TMMAN_DEFAULT, &Version)) != TMOK) 
	{
		fprintf(stderr, "tmmprun:tmNegotiateVersion:FAIL[0x%x](%s)\n", 
			Status,
			tmGetErrorString(Status) );
		goto mainExit1;
	}

	//install a control C handler so that we can perform cleanup before exit.
	if (SetConsoleCtrlHandler(tmrunControlHandler, TRUE) != TRUE) 
	{
		fprintf(stderr, "tmmprun:SetConsoleCtrlHandler:FAIL:[0x%x]\n", GetLastError());
		goto mainExit1;
	}




	// count the number of DSPs we have download into
	for ( wIdxArg = 1 ; wIdxArg < argc; wIdxArg++ ) 
	{
		// images indicates start of target executable names		
		if ( _stricmp ( argv[wIdxArg], "-exec" ) == 0 )
		{
			DSPCount++;
		}
	}

	for ( IdxNode = 0 ; IdxNode < DSPCount ; IdxNode++ )
	{
			Status = tmDSPOpen(IdxNode, &DSPHandle[IdxNode]);

			if (Status != TMOK) 
			{
				fprintf(stderr, "tmmprun:tmDSPOpen:FAIL[0x%x](%s)\n", 
					Status,
					tmGetErrorString(Status) );
				goto mainExit2;
			}

			/* TBD : put error cheking here */
			tmDSPGetCaps ( DSPHandle[IdxNode] , &DSPCaps );

			MMIOPhysicalAddressArray[IdxNode] = DSPCaps.MMIO.dwPhysical;
	}


	//process the generic command line parameters here
	for (wIdxArg = 1; wIdxArg < argc; wIdxArg++) 
	{

		// images indicates start of target executable names		
		if ( _stricmp ( argv[wIdxArg], "-exec" ) == 0 )
		{
			// the next argument should be the name of the 
			// executable , point to it.
			wIdxArg++;
			break;
		}

		switch (toupper(argv[wIdxArg][1])) 
		{
				case 'B':
				Interactive = FALSE;
				break;

			case 'W':
			{
				DWORD       dwWindowLines;
				COORD       ConsoleSize;

				if (sscanf(&argv[wIdxArg][2], "%x", &dwWindowLines) != 1) 
				{
					goto mainUsage;
				}
				ConsoleSize.X = 80;
				ConsoleSize.Y = dwWindowLines;
				SetConsoleScreenBufferSize(
							   GetStdHandle(STD_OUTPUT_HANDLE), ConsoleSize);
			}
			break;

				//add other command line optons here
			case '?':
			default:
				goto mainUsage;
		}
	}

	//////////////////////////////////////////////////////////////////////////


	TMDwnLdr_create_shared_section_table(&SharedSections);

	cruntimeInit();


	for ( IdxNode = 0 ; IdxNode < DSPCount ; IdxNode++ )
	{
		CRunTimeParameterBlock CRTParam;

		DWORD i;

		EventArray[IdxNode] = CreateEvent(
			NULL, //not running on workstation 4.0
			FALSE, //auto reset event
			FALSE, //initial state is not signalled
			NULL);
		
		if (EventArray[IdxNode] == INVALID_HANDLE_VALUE) 
		{
			fprintf(stderr, "tmmprun:CreateEvent:FAIL:[0x%x]", GetLastError());
			goto mainExit4;
		}

		CRTParam.OptionBitmap = 0;
		CRTParam.StdInHandle = (DWORD) GetStdHandle(STD_INPUT_HANDLE);
		CRTParam.StdOutHandle = (DWORD) GetStdHandle(STD_OUTPUT_HANDLE);
		CRTParam.StdErrHandle = (DWORD) GetStdHandle(STD_ERROR_HANDLE);
		

		// process target specific command line arguments here

		// this parameter should be the executable filename

		TargetExecutableName = argv[wIdxArg];
		ArgumentCount = 0;
		ArgumentVector[ArgumentCount++] = argv[wIdxArg];


		for ( wIdxArg++ ; wIdxArg < argc; wIdxArg++) 
		{

			// images indicates start of target executable names		
			if ( _stricmp ( argv[wIdxArg], "-exec" ) == 0 )
			{
				wIdxArg++;
				break;
			}

			ArgumentVector[ArgumentCount++] = argv[wIdxArg];
		}

		ArgumentVector[ArgumentCount] = NULL;

		// we have to allocate persistent storage for these values
		ArgumentCountArray[IdxNode] = ArgumentCount;

		if (  ( ArgumentVectorArray[IdxNode] = 
			malloc ( sizeof ( PVOID ) * ( ArgumentCount + 1 ) ) ) == NULL )
		{
			fprintf(stderr, "tmmprun:malloc:argv:FAIL\n" );
			goto mainExit5;
		}

		memcpy ( ArgumentVectorArray[IdxNode] , 
			ArgumentVector, 
			sizeof ( PVOID ) * ( ArgumentCount + 1 ) );
/*
		for ( i = 0 ; i < ArgumentCountArray[IdxNode] ; i ++ )
		{
			printf ("Argument #%d = %s\n", i , ((PVOID *)ArgumentVectorArray[IdxNode])[i] );
		}
*/
		/////PERFORM RELOCATION HERE /////////////////////////


		Status	= tmDSPExecutableLoadEx ( 
			DSPHandle[IdxNode], 
			TargetExecutableName,
			DSPCount,
			SharedSections,
			MMIOPhysicalAddressArray );


		///////////////////////////////////////////////////////



		if (Status != TMOK) 
		{
			fprintf(stderr, "tmmprun:tmDSPExecutableLoadEx(%s):FAIL[0x%x](%s)\n", 
				TargetExecutableName, 
				Status,
				tmGetErrorString(Status) );
			goto mainExit6;
		}


		CRTParam.OptionBitmap |= constCRunTimeFlagsUseSynchObject;
		CRTParam.SynchronizationObject = (DWORD) EventArray[IdxNode];
		CRTParam.VirtualNodeNumber = IdxNode; /* this is requried by juul's code */

		if (!Interactive) 
		{
			CRTParam.OptionBitmap |= constCRunTimeFlagsNonInteractive;
		}

		if (cruntimeCreate(
			IdxNode,/* the  physical DSP Number */
			ArgumentCountArray[IdxNode],
			ArgumentVectorArray[IdxNode],
			&CRTParam,
			&CRTHandle[IdxNode] ) != True) 
		{
			fprintf(stdout,
				"\ntmmprun:Cannot Initialize C Run Time Server : CRT I/O calls will not work:ERROR\n");
			goto mainExit6;
		}
	
	}
	

	for ( IdxNode = 0 ; IdxNode < DSPCount ; IdxNode++ )
	{
		TMMAN_TMCONS_PARAMS TMConsControl;

		TMConsControl.fRedirectedStdin = FALSE;
		TMConsControl.fRedirectedStdout = FALSE;
		TMConsControl.fRedirectedStderr = FALSE;
		TMConsControl.fUseWindowSize = FALSE;
		TMConsControl.fIgnoreTMCons = TRUE;
		TMConsControl.fUseTMMonWindow = FALSE;

		Status = tmDSPExecutableRun(
			DSPHandle[IdxNode],
			TMMAN_DEFAULT,
			&TMConsControl);

		if (Status != TMOK) 
		{
			fprintf(stderr,
				"tmmprun:tmDSPExecutableRun:FAIL[0x%x](%s)\n", 
				Status,
				tmGetErrorString(Status));
			goto mainExit7;
		}

	}


	WaitForMultipleObjects (DSPCount, EventArray, TRUE, INFINITE );


/*
mainExit7:
*/
	for ( IdxNode = 0 ; IdxNode < DSPCount ; IdxNode++ )
	{
		tmDSPExecutableStop(DSPHandle[IdxNode] );
	}


mainExit7:
	for ( IdxNode = 0 ; IdxNode < DSPCount ; IdxNode++ )
	{
		GlobalExitCode = cruntimeDestroy(CRTHandle[IdxNode]);
	}

mainExit6:
	for ( IdxNode = 0 ; IdxNode < DSPCount ; IdxNode++ )
	{
		if ( ArgumentVectorArray[IdxNode] )
			free ( ArgumentVectorArray[IdxNode] );
	}

mainExit5:
	for ( IdxNode = 0 ; IdxNode < DSPCount ; IdxNode++ )
	{
		CloseHandle(EventArray[IdxNode]);
	}

mainExit4:
	cruntimeExit();
	TMDwnLdr_unload_shared_section_table(SharedSections);

mainExit3:

	for ( IdxNode = 0 ; IdxNode < DSPCount ; IdxNode++ )
	{
		tmDSPClose ( DSPHandle[IdxNode] );
	}


mainExit2:
	SetConsoleCtrlHandler(tmrunControlHandler, FALSE);

mainExit1:
	if (Interactive) 
	{
		fprintf(stdout, "\ntmmprun:Press a key to close server >>");
		getchar();
	}
	return (GlobalExitCode);

mainUsage:
	fprintf(stderr, "usage:tmmprun [-b] [-wWindowSize] -exec ExecutableImageName1 [Arg1] [Arg2] ... -exec ExecutableImageName2 [Arg1] [Arg2] .....\n");
	goto mainExit1;
}

BOOL WINAPI 
tmrunControlHandler(DWORD dwCtrlType)
{
	DWORD	IdxNode;

	fprintf(stderr, "\ntmmprun:Control C Detected : Performing Cleanup\n");

	for ( IdxNode = 0 ; IdxNode < DSPCount ; IdxNode++ )
	{
		SetEvent(EventArray[IdxNode]);
	}

	return TRUE;
}



STATUS	tmDSPExecutableLoadEx ( 
	DWORD DSPHandle, 
	PCHAR pszImagePath,
	DWORD NumberOfDSPs,
	TMDwnLdr_SharedSectionTab_Handle SharedSections,
	PDWORD	MMIOPhysicalAddressArray )
{
	PTMSTD_MEMORY_BLOCK	pSDRAM;
	TMMAN_DSP_CAPS DSPCaps;
	TMMAN_DSP_INFO DSPInfo;
	TMDwnLdr_Status LoaderStatus;

	STATUS	Status  = TMOK;
	DWORD	ImageSize;
	DWORD	Alignment;
	DWORD	ClockSpeed = 0x5f5e100;	
	DWORD	CacheOption = TMDwnLdr_LeaveCachingToDownloader;
	DWORD	AlignedDownloadAddress;
	TMDwnLdr_Object_Handle	ObjectHandle;
	Endian					endian;
	CHAR	szDeviceName[0x10];

	/* TBD : put error cheking here */
	tmDSPGetCaps ( DSPHandle , &DSPCaps );

	/* TBD : put error checking here */
	tmDSPGetMiscInfo ( DSPHandle , &DSPInfo );

	pSDRAM = &DSPCaps.SDRAM;
	
	if ( ( LoaderStatus = TMDwnLdr_load_object_from_file ( 
		pszImagePath, 
		SharedSections, 
		&ObjectHandle ) ) != TMDwnLdr_OK )
	{
		//Status = TM_STATUS ( TMERRTMMAN32_ERR_OPENIMAGEFILEFAIL );
		OutputDebugString ( TMDwnLdr_get_last_error (LoaderStatus) );
		Status = TM_STATUS ( TMERR(TM_STATUS_HCOMP_TMLD, LoaderStatus) );
		goto tmDSPExecutableLoadExit1;
	}

	if ( ( LoaderStatus = TMDwnLdr_get_endian ( 
		ObjectHandle, 
		&endian ) ) != TMDwnLdr_OK )
	{
		OutputDebugString ( TMDwnLdr_get_last_error (LoaderStatus) );
		Status = TM_STATUS ( TMERR(TM_STATUS_HCOMP_TMLD, LoaderStatus) );
		goto tmDSPExecutableLoadExit2;
	}

	if ( endian != LittleEndian )
	{
		Status = TM_STATUS ( TMMAN32_ERR_IMAGENOTLITTLEENDIAN );
		goto tmDSPExecutableLoadExit2;	
	}

	if ( ( LoaderStatus = TMDwnLdr_resolve_symbol( 
		ObjectHandle, 
		"_TMMANSharedPatch", 
		DSPInfo.TMMANSharedPhys ) ) != TMDwnLdr_OK )
	{
		// for future reference store that this target image for this
		// board doesn't have libtmman.a linked with it.
		DSPInfo.Flags |= TMIF_DSPMISCINFO_SYMBOLNOTPATCHED;
		tmDSPSetMiscInfo ( DSPHandle, &DSPInfo );

		OutputDebugString( "tmman32:tmDSPExecutableLoad:WARNING:_TMMANSharedPatch:UNDEFINED\n" );	
		
	}
	else
	{
		DSPInfo.Flags &= (~TMIF_DSPMISCINFO_SYMBOLNOTPATCHED);
		tmDSPSetMiscInfo ( DSPHandle, &DSPInfo );
	}


  	if ( ( LoaderStatus = TMDwnLdr_get_image_size ( ObjectHandle, 
		&ImageSize, &Alignment 	) ) != TMDwnLdr_OK )
	{
		Status = TM_STATUS ( TMERR(TM_STATUS_HCOMP_TMLD, LoaderStatus) );
		OutputDebugString ( TMDwnLdr_get_last_error (LoaderStatus) );
		goto tmDSPExecutableLoadExit2; 
	}

	AlignedDownloadAddress = 
		( (DSPCaps.SDRAM.dwPhysical + Alignment -1 ) & ( ~( Alignment - 1 ) ) );

	// read in clock speed here
	sprintf ( szDeviceName, "Device.%x", DSPCaps.DSPNumber );
	ClockSpeed = GetPrivateProfileInt (
		szDeviceName, "ClockSpeed", ClockSpeed, "tmman.ini" );

	// read in Cache Option goes here
	// the cache options are the same as the values defined in
	// TMDownLoader.h this is kind of fucked up because
	// TMDownloader enumerate TMDwnLdr_CacheingSupport changes
	// the ini file values and hence documentatino will have to 
	// be update.
	sprintf ( szDeviceName, "Device.%x", DSPCaps.DSPNumber );
	CacheOption = GetPrivateProfileInt (
		szDeviceName, "CacheOption", CacheOption, "tmman.ini" );

	if ( ( LoaderStatus = TMDwnLdr_multiproc_relocate ( 
		ObjectHandle, 
		tmWin95Host,
		(Address*)MMIOPhysicalAddressArray,
		DSPCaps.DSPNumber, // NodeNumber
		NumberOfDSPs,// NumberOfNodes
		ClockSpeed,
		(Address)AlignedDownloadAddress,
		DSPCaps.SDRAM.dwSize,
		CacheOption ) ) != TMDwnLdr_OK )
	{
		OutputDebugString ( TMDwnLdr_get_last_error (LoaderStatus) );
		Status = TM_STATUS ( TMERR(TM_STATUS_HCOMP_TMLD, LoaderStatus) );
		goto tmDSPExecutableLoadExit2; 
	}

	if ( ( LoaderStatus = TMDwnLdr_get_memory_image ( 
		ObjectHandle, 
		(Address)tmPhysToLin ( AlignedDownloadAddress, &DSPCaps.SDRAM ) ) ) != TMDwnLdr_OK )
	{
		OutputDebugString ( TMDwnLdr_get_last_error (LoaderStatus) );
		Status = TM_STATUS ( TMERR(TM_STATUS_HCOMP_TMLD, LoaderStatus ) );
		goto tmDSPExecutableLoadExit2; 
	}


tmDSPExecutableLoadExit2 :
	TMDwnLdr_unload_object ( ObjectHandle );

tmDSPExecutableLoadExit1 :
	return Status;

}

⌨️ 快捷键说明

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