📄 oemioctl.c
字号:
pITM->dwSPC = dwSPC;
pITM->dwFrequency = PerfCountFreq();
wNumInterrupts = 0;
//RETAILMSG(1, (TEXT("ILTiming GetTime @ 0x%08X:%08X\r\n"),
// pITM->dwParam1, pITM->dwParam2));
break;
case ILTIMING_MSG_GET_PFN:
pITM->pfnPerfCountSinceTick = (PVOID)PerfCountSinceTick;
RETAILMSG (1, (TEXT("ILTiming GetPFN\r\n")));
break;
default:
RETAILMSG(1, (TEXT("IOCTL_HAL_ILTIMING: BAD MESSAGE!\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
break;
#if IMGSHAREETH
////////////////////////////////////////////////////////////////////////
// The support for VMini..
//
case IOCTL_VBRIDGE_GET_TX_PACKET:
if (lpOutBuf)
return VBridgeUGetOneTxPacket((PUCHAR *)lpOutBuf, nInBufSize);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
case IOCTL_VBRIDGE_GET_TX_PACKET_COMPLETE:
VBridgeUGetOneTxPacketComplete((PUCHAR)lpInBuf, nInBufSize);
return TRUE;
case IOCTL_VBRIDGE_GET_RX_PACKET:
if (lpOutBuf)
{
return VBridgeUGetOneRxPacket((PUCHAR *)lpOutBuf, lpBytesReturned);
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
case IOCTL_VBRIDGE_GET_RX_PACKET_COMPLETE:
VBridgeUGetOneRxPacketComplete((PUCHAR)lpInBuf);
return TRUE;
case IOCTL_VBRIDGE_GET_ETHERNET_MAC:
VBridgeUGetEDBGMac((PBYTE)lpOutBuf);
return TRUE;
case IOCTL_VBRIDGE_CURRENT_PACKET_FILTER:
////////////////////////////////////////////////////////////////////////
// First, see if filter setting is implemented, then inform vbridge
// on the new filtering.
//
if (OEMEthCurrentPacketFilter((PDWORD)lpInBuf))
{
VBridgeUCurrentPacketFilter((PDWORD)lpInBuf);
return TRUE;
}
return FALSE;
case IOCTL_VBRIDGE_802_3_MULTICAST_LIST:
if (OEMEthMulticastList((PUCHAR)lpInBuf, nInBufSize))
return TRUE;
return FALSE;
case IOCTL_VBRIDGE_WILD_CARD:
return VBridgeUWildCard(lpInBuf, nInBufSize, lpOutBuf, nOutBufSize,
lpBytesReturned);
case IOCTL_VBRIDGE_SHARED_ETHERNET:
////////////////////////////////////////////////////////////////////////
// Yes, this kernel supports shared ethernet port.
//
return TRUE;
#endif // IMGSHAREETH
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Translate interrupt into SYSINTR
//
// Translate IRQSYSINTR (or request new SYSINTR)
case IOCTL_HAL_TRANSLATE_IRQ:
case IOCTL_HAL_REQUEST_SYSINTR:
if (nInBufSize >= sizeof(DWORD) && nOutBufSize >= sizeof(DWORD) &&
lpOutBuf && lpInBuf)
{
*(PDWORD)lpOutBuf = OEMRequestSysIntr(*(PDWORD)lpInBuf);
if (lpBytesReturned)
{
*lpBytesReturned = sizeof(DWORD);
}
return TRUE;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
// Release previously requested SYSINTR
case IOCTL_HAL_RELEASE_SYSINTR:
if (nInBufSize >= sizeof(DWORD) && lpInBuf)
{
DWORD Success = OEMReleaseSysIntr(*(PDWORD)lpInBuf);
if (lpBytesReturned)
{
*lpBytesReturned = 0;
}
if (Success == ERROR_SUCCESS)
{
return TRUE;
}
else
{
SetLastError(Success);
return FALSE;
}
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
// Provide interrupt number based on device location
case IOCTL_HAL_REQUEST_IRQ:
if (nInBufSize >= sizeof(DEVICE_LOCATION) &&
nOutBufSize >= sizeof(DWORD) && lpOutBuf && lpInBuf)
{
if(!OEMGetInterrupt((PDEVICE_LOCATION)lpInBuf, (PDWORD)lpOutBuf))
return(FALSE);
if (lpBytesReturned)
{
*lpBytesReturned = sizeof(DWORD);
}
break;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
case IOCTL_HAL_ALLOCATE_DMA_CHANNEL:
EnterCriticalSection(&csDMAChannelAllocation);
if( !AllocateDMAChannel((PALLOCATE_DMA_PARAMS)lpInBuf,
(PALLOCATE_DMA_RESULT)lpOutBuf) )
{
LeaveCriticalSection(&csDMAChannelAllocation);
return FALSE;
}
{
int InitAudioDmaTransfer( PALLOCATE_DMA_PARAMS param , PALLOCATE_DMA_RESULT result);
InitAudioDmaTransfer( (PALLOCATE_DMA_PARAMS)lpInBuf, (PALLOCATE_DMA_RESULT)lpOutBuf) ;
}
LeaveCriticalSection(&csDMAChannelAllocation);
break;
case IOCTL_HAL_INITIALIZE_DMA_CHANNEL:
if( !InitializeDMAChannel((PINITIALIZE_DMA_PARAMS)lpInBuf,
(PINITIALIZE_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_FREE_DMA_CHANNEL:
EnterCriticalSection(&csDMAChannelAllocation);
if( !FreeDMAChannel((PFREE_DMA_PARAMS)lpInBuf,
(PFREE_DMA_RESULT)lpOutBuf) )
{
LeaveCriticalSection(&csDMAChannelAllocation);
return FALSE;
}
LeaveCriticalSection(&csDMAChannelAllocation);
break;
case IOCTL_HAL_START_DMA_TRANSFER:
if( !StartDMATransfer((PSTART_DMA_PARAMS)lpInBuf,
(PSTART_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_HALT_DMA_TRANSFER:
if( !HaltDMATransfer((PHALT_DMA_PARAMS)lpInBuf,
(PHALT_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_RESTART_DMA_TRANSFER:
if( !RestartDMATransfer((PRESTART_DMA_PARAMS)lpInBuf,
(PRESTART_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_STOP_DMA_TRANSFER:
if( !StopDMATransfer((PSTOP_DMA_PARAMS)lpInBuf,
(PSTOP_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_GET_ERROR_STATUS:
if( !GetErrorStatus((PGET_ERROR_PARAMS)lpInBuf,
(PGET_ERROR_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_CLEAR_ERROR_STATUS:
if( !ClearErrorStatus((PCLEAR_ERROR_PARAMS)lpInBuf,
(PCLEAR_ERROR_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_FREE_DMA_SYSINTR:
if( !FreeDmaSysIntr((PFREE_DMA_SYSINTR_PARAMS)lpInBuf,
(PFREE_DMA_SYSINTR_RESULT)lpOutBuf) )
return FALSE;
break;
case HAL_IOCTL_GPIO :
{
if( lpInBuf )
{
OEM_IOCTL_GPIO* gpio = (OEM_IOCTL_GPIO*)lpInBuf;
return SharedGPIOControl( gpio->num , gpio->pin , gpio->code , gpio->value ) ;
}
return FALSE;
}
break;
case HAL_IOCTL_AACI_DMA:
{
int StartAudioDmaTransfer( PSTART_DMA_PARAMS params , int*buffered );
if( StartAudioDmaTransfer( (PSTART_DMA_PARAMS)lpInBuf , (int*)lpOutBuf ) == 0 )
{
return TRUE;
}
else
{
return FALSE;
}
}
break;
case HAL_IOCTL_AACI_GETBUFFER:
{
int GetAudioDmaStatus( int*, int* );
GetAudioDmaStatus( (int*)lpInBuf , (int*)lpOutBuf );
return TRUE;
}
break;
case HAL_IOCTL_AACI_CLEARSTATUS:
{
int ClearAudioDmaStatus( int , int );
ClearAudioDmaStatus( *(int*)lpInBuf , *(int*)lpOutBuf );
return TRUE;
}
default:
#ifdef INTERNAL_HAL_TESTING
if (!InternalHalTesting(dwIoControlCode, lpInBuf,
nInBufSize, lpOutBuf,
nOutBufSize, lpBytesReturned))
{
return(FALSE);
}
break;
#endif
SetLastError(ERROR_NOT_SUPPORTED);
return(FALSE);
// Post kernel-init initialization, good place to initialize critical sections
case IOCTL_HAL_POSTINIT:
// Initialize critical sections
InitializeCriticalSection(&csWakeIntMask);
InitializeCriticalSection(&csRequestSysIntr);
InitializeCriticalSection(&csDMAChannelAllocation);
return TRUE;
}
return(TRUE);
}
static int PlayAudioStart = 0;
static int RecordAudioStart = 0;
static struct AudioDmaData
{
int buffered;
DWORD interrupt;
int channel;
START_DMA_PARAMS param;
DWORD pagelist[0x1000];
DWORD fifo;
}PlayConfig , RecordConfig;
int InitAudioDmaTransfer( PALLOCATE_DMA_PARAMS param , PALLOCATE_DMA_RESULT result)
{
if( param->ucDestDevice == 14 && param->ucSourceDevice == 0 )
{
PlayConfig.buffered = 0;
PlayConfig.interrupt = result->dwInterruptID;
PlayConfig.channel = result->ucChannelNumber;
PlayAudioStart = 1;
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("kernel : play init %d %d\r\n" ) , PlayConfig.interrupt ,PlayConfig.channel ));
}
else if( param->ucDestDevice == 0 && param->ucSourceDevice == 13 )
{
RecordConfig.buffered = 0;
RecordConfig.interrupt = result->dwInterruptID;
RecordConfig.channel = result->ucChannelNumber;
RecordAudioStart = 1;
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("kernel : record init %d %d\r\n" ) , RecordConfig.interrupt ,RecordConfig.channel ));
}
return 0;
}
int ClearAudioDmaStatus( int play , int record)
{
struct AudioDmaData* config;
if( play )
{
STOP_DMA_PARAMS param;
config = &PlayConfig;
param.ucChannelNumber = config->channel;
OEMInterruptDisable( config->interrupt );
StopDMATransfer( ¶m , 0 );
OEMInterruptEnable( config->interrupt , 0 , 0 );
config->buffered = 0;
}
if( record )
{
STOP_DMA_PARAMS param;
config = &RecordConfig;
param.ucChannelNumber = config->channel;
OEMInterruptDisable( config->interrupt );
StopDMATransfer( ¶m , 0 );
OEMInterruptEnable( config->interrupt , 0 , 0 );
config->buffered = 0;
}
return 0;
}
int GetAudioDmaStatus( int*play , int*record )
{
if( play )
*play = PlayConfig.buffered;
if( record )
*record = RecordConfig.buffered;
return 0;
}
int maxback = 0;
int StartAudioDmaTransfer( PSTART_DMA_PARAMS params , int*buffered )
{
int error = 0;
if( params->ucChannelNumber == PlayConfig.channel )
{
if( PlayConfig.buffered < 2 )
{
PlayConfig.buffered ++;
if( PlayConfig.buffered == 1 )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("kernel : do dma transfer\r\n" ) ));
OEMInterruptEnable( PlayConfig.interrupt , NULL , 0 );
if( !StartDMATransfer( params, 0 ) )
{
error = 2;
RETAILMSG( (DebugMsgMask&DebugMsg_Important) , (TEXT("kernel : dma error \r\n" ) ));
}
else
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("kernel : start dma ok\r\n" ) ));
}
else
{
int pagecnt = ( params->dwTransferSize + (params->pdwSourceBuffer[0]&0xfff) + 0xfff ) / 0x1000;
PlayConfig.param = *params;
memcpy( PlayConfig.pagelist , params->pdwSourceBuffer , pagecnt*sizeof(DWORD) );
PlayConfig.fifo = params->pdwDestBuffer[0];
PlayConfig.param.pdwSourceBuffer = PlayConfig.pagelist;
PlayConfig.param.pdwDestBuffer = &PlayConfig.fifo;
}
*buffered = PlayConfig.buffered;
}
else
{
RETAILMSG( (DebugMsgMask&DebugMsg_Important) , (TEXT("kernel : too many buffers\r\n" ) ));
error = 1;
}
}
else if( params->ucChannelNumber == RecordConfig.channel )
{
if( RecordConfig.buffered < 2 )
{
RecordConfig.buffered ++;
if( RecordConfig.buffered == 1 )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("kernel : do record dma\r\n" ) ));
maxback = 0;
OEMInterruptEnable( RecordConfig.interrupt , NULL , 0 );
if( !StartDMATransfer( params, 0 ) )
error = 3;
}
else
{
int pagecnt = ( params->dwTransferSize + (params->pdwSourceBuffer[0]&0xfff) + 0xfff ) / 0x1000;
RecordConfig.param = *params;
memcpy( RecordConfig.pagelist , params->pdwDestBuffer , pagecnt*sizeof(DWORD) );
RecordConfig.fifo = params->pdwSourceBuffer[0];
RecordConfig.param.pdwSourceBuffer = &RecordConfig.fifo;
RecordConfig.param.pdwDestBuffer = RecordConfig.pagelist;
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("backup record dma\r\n")));
}
*buffered = RecordConfig.buffered;
}
else
{
RETAILMSG( (DebugMsgMask&DebugMsg_Important) , (TEXT("kernel : too many record buffers %d\r\n" ) , RecordConfig.buffered));
error = 2;
}
}
else
error = -1;
return error;
}
int CompleteAudioDmaTransfer( DWORD interrupt )
{
int error = 0;
struct AudioDmaData* config;
if( interrupt == PlayConfig.interrupt && PlayAudioStart == 1 )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("kernel : complete play interrupt\r\n" ) ));
config = &PlayConfig;
}
else if( interrupt == RecordConfig.interrupt && RecordAudioStart == 1 )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("kernel : complete record interrupt\r\n" ) ));
config = &RecordConfig;
}
else
error = -1;
if( !error )
{
if( config->buffered > 0 )
{
config->buffered --;
if( config->buffered > 0 )
{
OEMInterruptEnable( interrupt , NULL , 0 );
StartDMATransfer( &config->param , 0 );
maxback ++;
}
else
{
static volatile PDMAC_REGS pDMACRegs = (PDMAC_REGS)DMAC_BASE;
OEMInterruptEnable( interrupt , NULL , 0 );
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("kernel : no more buffer %d \r\n" ) , maxback));
}
}
else
{
static volatile PDMAC_REGS pDMACRegs = (PDMAC_REGS)DMAC_BASE;
RETAILMSG( (DebugMsgMask&DebugMsg_Important) , (TEXT("kernel : audio continue error %x %x\r\n" ) ,
pDMACRegs->DMACIntStatus , pDMACRegs->DMACC1Configuration ));
return 0;
}
return config->interrupt;
}
return error;
}
/* EOF oemioctl.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -