📄 dmawince.c
字号:
/******************************************************************************
**
** COPYRIGHT (C) 2001, 2002 Intel Corporation.
**
** This software as well as the software described in it is furnished under
** license and may only be used or copied in accordance with the terms of the
** license. The information in this file is furnished for informational use
** only, is subject to change without notice, and should not be construed as
** a commitment by Intel Corporation. Intel Corporation assumes no
** responsibility or liability for any errors or inaccuracies that may appear
** in this document or any software that may be provided in association with
** this document.
** Except as permitted by such license, no part of this document may be
** reproduced, stored in a retrieval system, or transmitted in any form or by
** any means without the express written consent of Intel Corporation.
**
** FILENAME: dmawince.c
**
** PURPOSE: Contains all WinCE OS specific functions for DMA Controller Engine
** access and control
**
******************************************************************************/
#include <windows.h>
#include <drv_glob.h>
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <ceddk.h>
#include <nkintr.h>
#include <oalintr.h>
#include <dmacbits.h>
#include "xllp_dmac.h"
#include "dmawince.h"
//
// DMA IST routine
//
INT WINAPI DmacIntrThread(void);
//
// Externs
//
extern void XllpDmacHwInit();
extern void XllpDmacInterruptHandler();
extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
volatile DMA_GLOBALS *pDMAGlobals = NULL;
volatile P_XLLP_DMAC_T pDmacHandle = NULL;
#define DMA_CHANNEL_0 _T("DMA_CHANNEL_0")
#define DMA_CHANNEL_1 _T("DMA_CHANNEL_1")
#define DMA_CHANNEL_2 _T("DMA_CHANNEL_2")
#define DMA_CHANNEL_3 _T("DMA_CHANNEL_3")
#define DMA_CHANNEL_4 _T("DMA_CHANNEL_4")
#define DMA_CHANNEL_5 _T("DMA_CHANNEL_5")
#define DMA_CHANNEL_6 _T("DMA_CHANNEL_6")
#define DMA_CHANNEL_7 _T("DMA_CHANNEL_7")
#define DMA_CHANNEL_8 _T("DMA_CHANNEL_8")
#define DMA_CHANNEL_9 _T("DMA_CHANNEL_9")
#define DMA_CHANNEL_10 _T("DMA_CHANNEL_10")
#define DMA_CHANNEL_11 _T("DMA_CHANNEL_11")
#define DMA_CHANNEL_12 _T("DMA_CHANNEL_12")
#define DMA_CHANNEL_13 _T("DMA_CHANNEL_13")
#define DMA_CHANNEL_14 _T("DMA_CHANNEL_14")
#define DMA_CHANNEL_15 _T("DMA_CHANNEL_15")
#define DMA_CHANNEL_16 _T("DMA_CHANNEL_16")
#define DMA_CHANNEL_17 _T("DMA_CHANNEL_17")
#define DMA_CHANNEL_18 _T("DMA_CHANNEL_18")
#define DMA_CHANNEL_19 _T("DMA_CHANNEL_19")
#define DMA_CHANNEL_20 _T("DMA_CHANNEL_20")
#define DMA_CHANNEL_21 _T("DMA_CHANNEL_21")
#define DMA_CHANNEL_22 _T("DMA_CHANNEL_22")
#define DMA_CHANNEL_23 _T("DMA_CHANNEL_23")
#define DMA_CHANNEL_24 _T("DMA_CHANNEL_24")
#define DMA_CHANNEL_25 _T("DMA_CHANNEL_25")
#define DMA_CHANNEL_26 _T("DMA_CHANNEL_26")
#define DMA_CHANNEL_27 _T("DMA_CHANNEL_27")
#define DMA_CHANNEL_28 _T("DMA_CHANNEL_28")
#define DMA_CHANNEL_29 _T("DMA_CHANNEL_29")
#define DMA_CHANNEL_30 _T("DMA_CHANNEL_30")
#define DMA_CHANNEL_31 _T("DMA_CHANNEL_31")
//******************************************************************************
//
// Function Name: DmaDllEntry
//
// Description: Function called at dll load time and whenever a process/thread
// attaches to the dll.
//
//
// Input Arguments:
// hInstDLL: Instance handle..specifies base address of dll
// Op: Operation code
// lpvReserved: Reserved
//
// Output Arguments:
//
//
// Return Value:
// TRUE: if Ok to load the dll
// FALSE: otherwise
//
// Notes:
//
//*******************************************************************************
BOOL __stdcall DmaDllEntry
(
HANDLE hinstDLL,
DWORD Op,
LPVOID lpvReserved
)
{
//
// Ref count of processes attaching to DMA library
//
static unsigned long processCount=0;
switch (Op)
{
case DLL_PROCESS_ATTACH :
++processCount;
//RETAILMSG(1,(TEXT("DmaDllEntry Proc Attach: 0x%x\r\n"),processCount));
//NKDbgPrintfW(TEXT("\r\nDMA Engine Loaded -- Process...\r\n"));
//XllpDmacInit();
break;
case DLL_PROCESS_DETACH :
--processCount;
//RETAILMSG(1,(TEXT("DmaDllEntry Proc Detach: 0x%x\r\n"),processCount));
break;
case DLL_THREAD_DETACH :
//--z;
//RETAILMSG(1,(TEXT("DmaDllEntry Thrd Detach: 0x%x\r\n"),z));
break;
case DLL_THREAD_ATTACH :
//++z;
//RETAILMSG(1,(TEXT("DmaDllEntry Thread Attach: 0x%x\r\n"),processCount));
//NKDbgPrintfW(TEXT("DMA Engine, Thread Attach, XllpDmacInit...\r\n"));
//XllpDmacInit();
//NKDbgPrintfW(TEXT("DMA Engine, Thread Attach...\r\n"));
break;
default :
break;
}
return TRUE;
}
//******************************************************************************
//
// Function Name: GDE_Init()
//
// Other STream Interface functions stubbed.
//
//
//******************************************************************************
DWORD GDE_Init(DWORD p1, DWORD p2)
{
// Initialize the DMA system.
NKDbgPrintfW(TEXT("GDE_Init In = %x, %x...\r\n"), p1, p2);
XllpDmacInit();
// Exit
NKDbgPrintfW(TEXT("GDE_Init Done...\r\n"));
return 1; // Use non-zero to indicate success.
}
//*******************************************
//
// Stubs
//
//*******************************************
XLLP_BOOL_T GDE_Deinit(DWORD p1)
{
//NKDbgPrintfW(TEXT("GDE_Deinit..."));
return XLLP_TRUE;
}
//*******************************************
DWORD GDE_Open(DWORD P1, DWORD P2, DWORD P3 )
{
//NKDbgPrintfW(TEXT("GDE_Open..."));
return 1;
}
//*******************************************
BOOL GDE_Close( DWORD p1)
{
//NKDbgPrintfW(TEXT("GDE_Close..."));
return 1;
}
//*******************************************
BOOL GDE_IOControl(
DWORD hOpenContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
)
{
//NKDbgPrintfW(TEXT("GDE_IOControl..."));
return 1;
}
//*******************************************
DWORD GDE_Read(
DWORD hOpenContext,
LPVOID pBuffer,
DWORD Count
)
{
//NKDbgPrintfW(TEXT("GDE_Read..."));
return 1;
}
//*******************************************
DWORD GDE_Write(
DWORD hOpenContext,
LPCVOID pBuffer,
DWORD Count
)
{
//NKDbgPrintfW(TEXT("GDE_Write..."));
return 1;
}
//*******************************************
DWORD GDE_Seek(
DWORD hOpenContext,
long Amount,
WORD Type
)
{
//NKDbgPrintfW(TEXT("GDE_Seek..."));
return 1;
}
//*******************************************
void GDE_PowerUp(
DWORD hDeviceContext
)
{
//NKDbgPrintfW(TEXT("GDE_PowerUp..."));
return;
}
//*******************************************
void GDE_PowerDown(
DWORD hDeviceContext
)
{
//NKDbgPrintfW(TEXT("GDE_PowerDown..."));
return;
}
//*******************************************
//******************************************************************************
//
// Function Name: XllpDmacInit
//
// Description: Function called to initialize this dll
// Creates DMA register mapping, sets up DMA IST and initializes hardware
//
//
// Input Arguments:
//
//
// Output Arguments:
//
//
// Return Value:
// TRUE: when successful
// FALSE: otherwise
//
// Notes:
//
//*******************************************************************************
XLLP_STATUS_T XllpDmacInit
(
)
{
XLLP_UINT32_T i;
if (pDMAGlobals == NULL)
{
//
// Initialize the DMA Register map
//
pDMAGlobals = (volatile DMA_GLOBALS *)VirtualAllocCopy(sizeof(DMA_GLOBALS),"pDMAGlobals",(PVOID)(GDE_BUFFER_VIRTUAL));
if (pDMAGlobals == NULL)
return FALSE;
}
if (pDmacHandle == NULL)
{
pDmacHandle = (volatile P_XLLP_DMAC_T)VirtualAllocCopy(sizeof(XLLP_DMAC_T),"pDmacHandle",(PVOID)(DMAC_BASE_U_VIRTUAL));
if (pDmacHandle == NULL)
return FALSE;
}
//
// Check for first time initialization flag
//
if( pDMAGlobals->notFirstTime )
return TRUE;
pDMAGlobals->notFirstTime=1;
//
// Do all the only one time initialization
// Create the DMAC interrupt event
//
for(i=0;i<32;++i)
pDMAGlobals->pArrayChannel[i] = 0;
//
// These are taken by wave (audio) driver and Camera.
//
pDMAGlobals->pArrayChannel[DMA_CH_OUT] = 1;
pDMAGlobals->pArrayChannel[DMA_CH_RCV] = 1;
pDMAGlobals->pArrayChannel[DMA_CH_MIC] = 1;
pDMAGlobals->gDmacIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//
// Create DMA IST
// This thread will handle all DMA interrupts and be responsible for calling appropriate
// second level handlers.
//
if (!(InterruptInitialize(SYSINTR_DMA, pDMAGlobals->gDmacIntrEvent, NULL, 0)))
{
RETAILMSG(1,(TEXT("DMAC: Interrupt initialization failed .....\r\n")));
return FALSE;
}
pDMAGlobals->gDmacThreadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
pDMAGlobals->gDmacIntrThread =
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) DmacIntrThread, NULL, 0, NULL);
if ( pDMAGlobals->gDmacIntrThread == NULL )
{
return (FALSE);
}
WaitForSingleObject(pDMAGlobals->gDmacThreadReadyEvent, INFINITE);
//
// Initialize DMAC hardware
// This will also stop any ongoing DMA activity
//
pDMAGlobals->hDMAEvent[0] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_0);
pDMAGlobals->hDMAEvent[1] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_1);
pDMAGlobals->hDMAEvent[2] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_2);
pDMAGlobals->hDMAEvent[3] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_3);
pDMAGlobals->hDMAEvent[4] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_4);
pDMAGlobals->hDMAEvent[5] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_5);
pDMAGlobals->hDMAEvent[6] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_6);
pDMAGlobals->hDMAEvent[7] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_7);
pDMAGlobals->hDMAEvent[8] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_8);
pDMAGlobals->hDMAEvent[9] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_9);
pDMAGlobals->hDMAEvent[10] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_10);
pDMAGlobals->hDMAEvent[11] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_11);
pDMAGlobals->hDMAEvent[12] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_12);
pDMAGlobals->hDMAEvent[13] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_13);
pDMAGlobals->hDMAEvent[14] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_14);
pDMAGlobals->hDMAEvent[15] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_15);
pDMAGlobals->hDMAEvent[16] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_16);
pDMAGlobals->hDMAEvent[17] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_17);
pDMAGlobals->hDMAEvent[18] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_18);
pDMAGlobals->hDMAEvent[19] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_19);
pDMAGlobals->hDMAEvent[20] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_20);
pDMAGlobals->hDMAEvent[21] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_21);
pDMAGlobals->hDMAEvent[22] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_22);
pDMAGlobals->hDMAEvent[23] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_23);
pDMAGlobals->hDMAEvent[24] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_24);
pDMAGlobals->hDMAEvent[25] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_25);
pDMAGlobals->hDMAEvent[26] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_26);
pDMAGlobals->hDMAEvent[27] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_27);
pDMAGlobals->hDMAEvent[28] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_28);
pDMAGlobals->hDMAEvent[29] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_29);
pDMAGlobals->hDMAEvent[30] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_30);
pDMAGlobals->hDMAEvent[31] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_31);
XllpDmacHwInit();
XllpDmacEnableInterrupt();
Sleep(10);
RETAILMSG(1,(TEXT("XllpDmacInit success.\r\n")));
return TRUE;
}
//******************************************************************************
//
// Function Name: DmacIntrThread
//
// Description: The IST for DMA Controller interrupt.
//
//
// Input Arguments:
//
//
// Output Arguments:
//
//
// Return Value:
// None
//
// Notes: Calls the XllpDmacIntHandler which does the guts of the work
//
//*******************************************************************************
INT WINAPI DmacIntrThread
(
void
)
{
DWORD tmpDINT;
int i;
SetEvent(pDMAGlobals->gDmacThreadReadyEvent);
while (TRUE)
{
WaitForSingleObject(pDMAGlobals->gDmacIntrEvent, INFINITE);
// DMA interrupts are currently masked. This routine will not be interrupted by another DMA interrupt.
tmpDINT = pDmacHandle->DINT;
for ( i=0; i<XLLP_DMAC_CHANNEL_NUM; i++ )
{
if (tmpDINT & (1u << i))
{
// Acknowledge the given interrupt channel
pDmacHandle->DCSR[i] |= (0x1 << 2);
RETAILMSG(1,(TEXT("DMA %d\r\n"), i)); //hzh
// signal the waiting thread
SetEvent(pDMAGlobals->hDMAEvent[i]); // should search this list in priority order instead of linearly.
}
// Stop searching if there are no more threads to signal
if ((unsigned)i >= tmpDINT)
break;
}
// Now that we have SetEvent on all known interrupt source, we can re-enable DMA interrupts.
InterruptDone(SYSINTR_DMA);
}
return XLLP_STATUS_SUCCESS;
}
BOOL XllpDmacAcquireMutex
(
HANDLE *hDmacMutex,
DWORD timeout
)
{
//
// Create the mutex for protecting access to shared data structures (channel array map)
// Need to be acquired before calling XllpAllocate/FreeChannel
//
if ((*hDmacMutex = CreateMutex(NULL, FALSE, DMAC_MUTEX_NAME)) == NULL)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -