📄 tmman.c
字号:
/*
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 + -