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

📄 tmman.c

📁 wince host 和 target PCI驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
	tmMsgCreate
*/
STATUS  tmMsgCreate ( 
	PTMMAN_MESSAGE_DESC pMsgCreate, /* message channel attributes */
	PVOID *ppMsg )					/* address of mem to store msg obj ptr */
{
	DWORD	Interrupt;
	STATUS	Status;

	Status = msgmCreateMsg ( GetMsgMgrObject(), pMsgCreate, ppMsg );

	return Status;


}
/*
	tmMsgDestroy
	this function closes the message channel opened with the host

*/
STATUS    tmMsgDestroy ( 
	PVOID pMsg )	/* ptr to msg obj to destroy */
{
	DWORD	Interrupt;
	STATUS	Status;

	Status = msgDestroy ( pMsg );

	return Status;
}

/*
	tmMsgSend
*/
STATUS  tmMsgSend ( 
	PVOID pMsg,			/* ptr to the msg obj */
	PVOID pPacket )	/* packet ptr to send to host */
{
	DWORD	Interrupt;
	STATUS	Status;
/*
	DWORD	Start, End;
	Start = cycles();
*/

	Status = msgSend ( pMsg, pPacket );

/*
	End = cycles();
	if ( End > Start )
		tmDBGPrintf("M[%x]", End - Start );
	else
		tmDBGPrintf("M[W:%x:%x]", End , Start );
*/

	return Status;

}

/* 
	tmParameterDWORDSet
	set parameters for counterparts running on DSP 
*/
STATUS	tmParameterDWORDSet ( DWORD ID, DWORD Value )
{
	if ( ID > Global.ParameterCount )
	{
		return TM_STATUS(TMMAN_ERR_IDOUTOFRANGE);
	}
	Global.pParameterDWORD[ID] = Value;
	return TMOK;
}

/* 
	tmParameterDWORDGet
	get parameters for counterparts running on DSP 
*/
STATUS	tmParameterDWORDGet ( DWORD ID, PDWORD pValue )
{
	if ( ID > Global.ParameterCount )
	{
		return TM_STATUS(TMMAN_ERR_IDOUTOFRANGE);
	}
	*pValue = Global.pParameterDWORD[ID];
	return TMOK;
}

/*
	tmSGMemCopy ()
	This function copies data to/from a page locked buffer on the host
	from/to a buffer in the target local memory.
	It requires a handle to the host buffer returned by a call to
	tmBufferPrepare on the host.
	This function fails under the following circumstances
	If the dwBufferHandle passed is invalid.
	If the Host address passed is invalid.
	If the size of copy is greater than the size of the locked memory.
	USAGE 
	Note that this function can only copy data across the PCI bus.
	It will behave unpredictably if both the host and the target address
	denote the same side of the bus. i.e both host addresses or both
	target addresses.

	It uses the standard memcpy to do the actual copying 

	NOTE :
	Normally on a x86 CPU, PTE list - except the first and the last PTE
	all otehr PTE have size = PAGESIZE ( ntddk.h = 4K ), but due to 
	Pentium's capability of having 4MB pages we don't take a chance. We
	go through every PTE without making any assumptions about page sizes
	 
*/

STATUS	tmSGMemCopy ( PVOID pObject, DWORD dwHostAddress,
	DWORD dwTargetAddress, DWORD dwSize, BOOL fHostToTarget )
{
	DWORD	dwDWORDCount;
	DWORD	dwIdxPTE, dwBlockSize;
	DWORD	dwLinearAddress;
	DWORD	dwBytesCopied;

	/* remote object - this object exists on the host */
	PTMHD_BUFFER_PTEHEADER	this = (PTMHD_BUFFER_PTEHEADER)pObject;

	/* validate the object */
	if ( this->dwSize != sizeof ( TMHD_BUFFER_PTEHEADER ) )
	{
		return TM_STATUS(TMMAN_ERR_INVALIDOBJECT);
	}

	/* validate the PTE */
	
	if ( this->dwEntryCount > 0 );
	else
	{
		return TM_STATUS(TMMAN_ERR_INVALIDPTEHEADER);
	}

	/* validate the host address */
	if ( ( dwHostAddress >= this->dwLinearAddress ) &&
		( dwHostAddress <= ( this->dwLinearAddress + this->dwBufferSize ) ) );
	else
	{
		return TM_STATUS(TMMAN_ERR_INVALIDHOSTADDR);
	}

	/* validate the size requested */
	if ( ( dwHostAddress + dwSize ) <= 
		( this->dwLinearAddress + this->dwBufferSize ) );
	else
	{
		return TM_STATUS(TMMAN_ERR_INVALIDCOPYSIZE);
	}

	/* base linear address of the buffer */
	dwLinearAddress = this->dwLinearAddress;
	dwBytesCopied = 0;

	/* find the appropriate entry in the PTE corresponding to host address */
	for ( dwIdxPTE = 0 ; dwIdxPTE < this->dwEntryCount ; dwIdxPTE ++)
	{
		if ( ( dwHostAddress >= dwLinearAddress ) && 
			( dwHostAddress <= ( dwLinearAddress + this->Entries[dwIdxPTE].dwSize ) ) )
		{
			/* we found the first PTE encompassing the required range */
			dwBlockSize = 
				this->Entries[dwIdxPTE].dwSize - (dwHostAddress - dwLinearAddress);
			dwLinearAddress += this->Entries[dwIdxPTE].dwSize;

			DT(11, ("tmSGMemCopy:memcpy:Target[%x]:Host[%x]:Size[%x]\n",
				( dwTargetAddress + dwBytesCopied ),
				this->Entries[dwIdxPTE].dwPhysicalAddress + 
				( this->Entries[dwIdxPTE].dwSize -  dwBlockSize ),
				dwBlockSize ));

			if ( fHostToTarget )
			{

				memcpy ( (PVOID)( dwTargetAddress + dwBytesCopied ), 
					(PBYTE) this->Entries[dwIdxPTE].dwPhysicalAddress + 
					( this->Entries[dwIdxPTE].dwSize -  dwBlockSize ),
					dwBlockSize );

			}
			else
			{
				memcpy ( 
					( this->Entries[dwIdxPTE].dwSize -  dwBlockSize ),
					(PVOID)( dwTargetAddress + dwBytesCopied ), 
					(PBYTE) this->Entries[dwIdxPTE].dwPhysicalAddress + 					
					dwBlockSize );

			}

			dwBytesCopied = dwBlockSize;
			break;
		}
		dwLinearAddress += this->Entries[dwIdxPTE].dwSize;
	}


	for ( dwIdxPTE++ ; dwIdxPTE < this->dwEntryCount ; dwIdxPTE ++)
	{
		if ( ( ( dwHostAddress + dwSize ) >= dwLinearAddress ) && 
			( ( dwHostAddress + dwSize ) <= ( dwLinearAddress + this->Entries[dwIdxPTE].dwSize ) ) )
		{
			/* we found the last PTE encompassing the required range */
			dwBlockSize = ( dwHostAddress + dwSize ) - dwLinearAddress;

			DT(11, ("tmSGMemCopy:memcpy:Target[%x]:Host[%x]:Size[%x]\n",
				( dwTargetAddress + dwBytesCopied ),
				this->Entries[dwIdxPTE].dwPhysicalAddress,
				dwBlockSize ));

			if ( fHostToTarget )
			{
					
				memcpy ( (PVOID)( dwTargetAddress + dwBytesCopied ), 
					(PVOID)this->Entries[dwIdxPTE].dwPhysicalAddress,
					dwBlockSize );
			}
			else
			{
				memcpy ( 
					(PVOID)this->Entries[dwIdxPTE].dwPhysicalAddress,
					(PVOID)( dwTargetAddress + dwBytesCopied ), 
					dwBlockSize );

			}
			dwBytesCopied += dwBlockSize;

			break;
		}
		else
		{
			DT(11, ("tmSGMemCopy:memcpy:Target[%x]:Host[%x]:Size[%x]\n",
				( dwTargetAddress + dwBytesCopied ),
				this->Entries[dwIdxPTE].dwPhysicalAddress,
				this->Entries[dwIdxPTE].dwSize ));

			/* copy this block entirely */
			if ( fHostToTarget )
			{

				memcpy ( (PVOID)( dwTargetAddress + dwBytesCopied ), 
					(PVOID)this->Entries[dwIdxPTE].dwPhysicalAddress,
					this->Entries[dwIdxPTE].dwSize );

			}
			else
			{
				memcpy (
					(PVOID)this->Entries[dwIdxPTE].dwPhysicalAddress,
					(PVOID)( dwTargetAddress + dwBytesCopied ), 
					this->Entries[dwIdxPTE].dwSize );
			}
			dwBytesCopied += this->Entries[dwIdxPTE].dwSize;
		}
		dwLinearAddress += this->Entries[dwIdxPTE].dwSize;
	}

	return TMOK;
}
/*
	tmSGGetNextBlock ()
*/
STATUS	tmSGGetNextBlock ( PVOID pObject, PDWORD pdwLinearAddress, 
	PDWORD pdwPhysicalAddress, PDWORD pdwSize)
{
	/* remote object - this object exists on the host */
	PTMHD_BUFFER_PTEHEADER	this = (PTMHD_BUFFER_PTEHEADER)pObject;

	if ( this->dwSize != sizeof ( TMHD_BUFFER_PTEHEADER ) )
	{
		return TM_STATUS(TMMAN_ERR_INVALIDOBJECT);
	}

	if ( this->dwEntryCount > 0 );
	else
	{
		return TM_STATUS(TMMAN_ERR_INVALIDPTEHEADER);
	}

	if ( this->dwCurrentEntry >= this->dwEntryCount )
	{
		return TM_STATUS ( TMMAN_ERR_ENDOFPTELIST );
	}

	*pdwLinearAddress = this->dwCurrentLinearAddress;
	*pdwPhysicalAddress = 
		this->Entries[this->dwCurrentEntry].dwPhysicalAddress;
	*pdwSize = this->Entries[this->dwCurrentEntry].dwSize;

	/* prepare for the next call to tmGetNextBlock */
	this->dwCurrentLinearAddress += 
		this->Entries[this->dwCurrentEntry].dwSize;
	this->dwCurrentEntry++;

	return TMOK;	
}

/*
	tmSGGetFirstBlock ()
*/
STATUS	tmSGGetFirstBlock ( PVOID pObject, PDWORD pdwLinearAddress, 
	PDWORD pdwPhysicalAddress, PDWORD pdwSize)
{
	/* remote object - this object exists on the host */
	PTMHD_BUFFER_PTEHEADER	this = (PTMHD_BUFFER_PTEHEADER)pObject;

	if ( this->dwSize != sizeof ( TMHD_BUFFER_PTEHEADER ) )
	{
		return TM_STATUS(TMMAN_ERR_INVALIDOBJECT);
	}

	if ( this->dwEntryCount > 0 );
	else
	{
		return TM_STATUS(TMMAN_ERR_INVALIDPTEHEADER);
	}
	
	this->dwCurrentEntry = 0;
	this->dwCurrentLinearAddress = this->dwLinearAddress;

	*pdwLinearAddress = this->dwCurrentLinearAddress;
	*pdwPhysicalAddress = this->Entries[this->dwCurrentEntry].dwPhysicalAddress;
	*pdwSize = this->Entries[this->dwCurrentEntry].dwSize;
	
	/* prepare for the call to tmGetNextBlock */
	this->dwCurrentLinearAddress += 
		this->Entries[this->dwCurrentEntry].dwSize;
	this->dwCurrentEntry++;

	return TMOK;
}

DWORD	tmDBGPrintf(char * pFormat, ...)
{
	return 0;
}

⌨️ 快捷键说明

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