cpudp.cpp

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C++ 代码 · 共 366 行

CPP
366
字号
/*

  Copyright(c) 2000 Microsoft.

	Module Name:

		CpuDp.cpp

	Revision History:

 */
#include <windows.h>
#include <types.h>
#include <memory.h>
#include <waveddsi.h>
#include <wavedbg.h>
#include "waveInpdd.h"
#include "platform.h"
#include "sh4.h"
#include "drv_glob.h"
#include "oalintr.h"

#include "cc.h"
#include "macros.h"
#include "wavecpud.h"

extern "C" PBYTE GetVirtualAddressOfUncachedMemory(PBYTE physicalAddress,DWORD size,char* callerID);
DWORD gIntrAudio= SYSINTR_AUDIO;
DWORD dwCCCodecRegBase=CC_CODEC_REGBASE;
DWORD dwCCSysSMCR=CC_SYS_SMSCR;

DmaObject::DmaObject()
{
	pDriverGlobals = VirtualAlloc(
		NULL,
		DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
		MEM_RESERVE,
		PAGE_NOACCESS);

	if (pDriverGlobals) {
		if (!VirtualCopy((PVOID)pDriverGlobals,
			(PVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
			(DWORD)DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
			PAGE_READWRITE | PAGE_NOCACHE))
		{
			VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
			pDriverGlobals=NULL;
		}
	}
	ASSERT(pDriverGlobals);

};
DmaObject::~DmaObject()
{
	if (pDriverGlobals!=NULL) {
		VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
		pDriverGlobals=NULL;
	}

};
DWORD DmaObject::GetGlobalPlayAddress()
{
	ASSERT(pDriverGlobals);
	return ((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.play_address;
};
DWORD DmaObject::SetGlobalPlayAddress(DWORD dwPhysicalAddr)
{
	ASSERT(pDriverGlobals);
	return (((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.play_address=dwPhysicalAddr);
};
USHORT DmaObject::GetGlobalOutInt()
{
	return (((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.outInt);
};
VOID DmaObject::ResetGlobalOutInt(BOOL bDecrement)
{
	if (bDecrement)
		(((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.outInt)--;
	else
		(((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.outInt)=0;
};
DWORD DmaObject::GetGlobalRecAddress()
{
	return ((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.rec_address;
};
DWORD DmaObject::SetGlobalRecAddress(DWORD dwPhysicalAddr)
{
	return (((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.rec_address=dwPhysicalAddr);
};
USHORT DmaObject::GetGlobalInInt()
{
	return ((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.inInt;
};

VOID DmaObject::ResetGlobalInInt(BOOL bDecrement)
{
	if (bDecrement)
		(((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.inInt)--;
	else
		((volatile PDRIVER_GLOBALS)pDriverGlobals)->aud.inInt=0;
};	

class DmaObjectImp: public DmaObject {
public:
	DmaObjectImp()	;
	virtual ~DmaObjectImp() ;

	virtual BOOL EnableDma();
	virtual BOOL DisableDma();
	virtual DWORD GetDmaSourceReg(){ return READ_REGISTER_ULONG((PULONG)pSAR1  );};
	virtual DWORD GetDmaCountReg() { return READ_REGISTER_ULONG((PULONG)pDMATCR1);};
// DMA Channel 1 Registers (audio record channel)
protected:
	PBYTE   pDMAC_RegBase;
	PVULONG pSAR1, pDAR1, pDMATCR1, pCHCR1; //virtual addrs of DMA1 control regs
	PVULONG pCHCR0,pCHCR2,pCHCR3;			//virtual addrs of DMA1 control regs
	PVULONG pDMAOR;						// virtual address of DMA Operation Register
};


DmaObjectImp::DmaObjectImp()
{	
	pDMAC_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
		(PBYTE)DMAC_REGBASE,
		(DWORD)DMAC_REGSIZE,
		"PDD_AudioInitialize, pDMAC_RegBase");

	ASSERT(pDMAC_RegBase);

	pDMAOR   = (PVULONG)(pDMAC_RegBase + DMAC_DMAOR_OFFSET );
	pSAR1    = (PVULONG)(pDMAC_RegBase + DMAC_SAR1_OFFSET   );
	pDAR1    = (PVULONG)(pDMAC_RegBase + DMAC_DAR1_OFFSET   );
	pDMATCR1 = (PVULONG)(pDMAC_RegBase + DMAC_DMATCR1_OFFSET);
	pCHCR1   = (PVULONG)(pDMAC_RegBase + DMAC_CHCR1_OFFSET  );

	pCHCR0   = (PVULONG)(pDMAC_RegBase + DMAC_CHCR0_OFFSET  );
	pCHCR2   = (PVULONG)(pDMAC_RegBase + DMAC_CHCR2_OFFSET  );
	pCHCR3   = (PVULONG)(pDMAC_RegBase + DMAC_CHCR3_OFFSET  );
};
DmaObjectImp::~DmaObjectImp()
{
	if (pDMAC_RegBase)
		VirtualFree((PVOID)pDMAC_RegBase, 0, MEM_RELEASE);
	
};

BOOL DmaObjectImp::EnableDma()
{
	WRITE_REGISTER_ULONG(pDMAOR, DMAC_DMAOR_DME );
	return TRUE;
}

BOOL DmaObjectImp::DisableDma()
{
	WRITE_REGISTER_ULONG(pDMAOR, 0);
	return TRUE;
};
class DmaInObject: public DmaObjectImp {
public:
	DmaInObject();
	~DmaInObject();
	virtual BOOL StartDma(BOOL bGenInterrupt=TRUE);
	virtual BOOL ReStartDma();
	virtual BOOL StopDma();
	virtual BOOL ArmDma(BOOL bFirstBuffer,DWORD dwPhyAddr);
	virtual DWORD GetDmaPhyAddr(BOOL bFirst) { return bFirst?dma_pagePhysicalAddress[0]:dma_pagePhysicalAddress[1];	};
	virtual BOOL SetGlobalAddr(BOOL bFirst) {	
		SetGlobalRecAddress(GetDmaPhyAddr(bFirst));
		return TRUE;
	};
	virtual DWORD GetAudioDmaPageSize() { return AUDIO_DMA_PAGE_REC_SIZE;};
	virtual PVOID  GetDmaVirtualAddr() { return pAudioBufferBase;};

private:
	PVOID pAudioBufferBase;

	static PVBYTE dma_page[2];
	static ULONG dma_pagePhysicalAddress[2];
};

ULONG DmaInObject::dma_pagePhysicalAddress[2] =
{
	AUDIO_BUFFER_REC_BASE,
	(AUDIO_BUFFER_REC_BASE + AUDIO_DMA_PAGE_REC_SIZE )
};

DmaInObject::DmaInObject()
{

	DWORD SizeOfBuffer = (AUDIO_DMA_PAGE_REC_SIZE * 2);

	pAudioBufferBase = VirtualAlloc(
		NULL,
		SizeOfBuffer,
		MEM_RESERVE,
		PAGE_NOACCESS);

	if (pAudioBufferBase) {
		if (!VirtualCopy((PVOID)pAudioBufferBase,
			(PVOID)dma_pagePhysicalAddress[0],
			(DWORD)SizeOfBuffer,
			PAGE_READWRITE | PAGE_NOCACHE))
		{
			VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
			pAudioBufferBase=NULL;
		}
	};
	ASSERT(pAudioBufferBase );
}

DmaInObject::~DmaInObject()
{
	if (pAudioBufferBase)
		VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
}
BOOL DmaInObject::ReStartDma()
{
	WRITE_REGISTER_ULONG((PULONG)pCHCR1, 
		DMAC_CHCR_RL_ACTIVE_HIGH |
		DMAC_CHCR_DM_INCREMENTED |
		DMAC_CHCR_TS_32 |
		DMAC_CHCR_IE_GENERATED |
		DMAC_CHCR_DE_ENABLED );
	return TRUE;
};
BOOL DmaInObject::StartDma(BOOL bGenInterrupt)
{
	READ_REGISTER_ULONG((PULONG)pCHCR1  );
	WRITE_REGISTER_ULONG((PULONG)pCHCR1, 
		DMAC_CHCR_RL_ACTIVE_HIGH |
		DMAC_CHCR_DM_INCREMENTED |
		DMAC_CHCR_TS_32 |
		(bGenInterrupt?DMAC_CHCR_IE_GENERATED:DMAC_CHCR_IE_NOT_GENARATED) |
		DMAC_CHCR_DE_ENABLED );
	return TRUE;
}
BOOL DmaInObject::StopDma()
{
	WRITE_REGISTER_ULONG((PULONG)pCHCR1,
		DMAC_CHCR_RL_ACTIVE_HIGH |
		DMAC_CHCR_DM_INCREMENTED |
		DMAC_CHCR_TS_32 |
		DMAC_CHCR_IE_NOT_GENARATED |
		DMAC_CHCR_DE_DISABLED);
	return TRUE;

}

BOOL DmaInObject::ArmDma(BOOL bFirstBuffer,DWORD dwPhyAddr)
{

	WRITE_REGISTER_ULONG((PULONG)pDAR1,    (ULONG)(bFirstBuffer?dma_pagePhysicalAddress[0]:dma_pagePhysicalAddress[1]));
	WRITE_REGISTER_ULONG((PULONG)pSAR1,    dwPhyAddr );
	WRITE_REGISTER_ULONG((PULONG)pDMATCR1, (ULONG)( AUDIO_DMA_PAGE_REC_SIZE / 4 ));	// set data count
	return TRUE;
};

class DmaOutObject: public DmaObjectImp {
public:
	DmaOutObject();
	~DmaOutObject();
	virtual BOOL StartDma(BOOL bGenInterrupt=TRUE);
	virtual BOOL ReStartDma();
	virtual BOOL StopDma();
	virtual BOOL ArmDma(BOOL bFirstBuffer,DWORD dwPhyAddr);
	virtual DWORD GetDmaPhyAddr(BOOL bFirst) { return bFirst?dma_pagePhysicalAddress[0]:dma_pagePhysicalAddress[1];	};
	virtual BOOL SetGlobalAddr(BOOL bFirst) {	
		SetGlobalPlayAddress(GetDmaPhyAddr(bFirst));
		return TRUE;
	};
	virtual DWORD GetAudioDmaPageSize() { return AUDIO_DMA_PAGE_SIZE;};
	virtual PVOID  GetDmaVirtualAddr() { return pAudioBufferBase;};

private:
	PVOID pAudioBufferBase;

	static PVBYTE dma_page[2];
	static ULONG dma_pagePhysicalAddress[2];
};

ULONG DmaOutObject::dma_pagePhysicalAddress[2] =
{
	AUDIO_BUFFER_BASE,
	(AUDIO_BUFFER_BASE + AUDIO_DMA_PAGE_SIZE)
};
DmaOutObject::DmaOutObject()
{

	DWORD SizeOfBuffer = (AUDIO_DMA_PAGE_SIZE * 2);

	pAudioBufferBase = VirtualAlloc(
		NULL,
		SizeOfBuffer,
		MEM_RESERVE,
		PAGE_NOACCESS);

	if (pAudioBufferBase) {
		if (!VirtualCopy((PVOID)pAudioBufferBase,
			(PVOID)dma_pagePhysicalAddress[0],
			(DWORD)SizeOfBuffer,
			PAGE_READWRITE | PAGE_NOCACHE))
		{
			VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
			pAudioBufferBase=NULL;
		}
	};
	ASSERT(pAudioBufferBase);
}

DmaOutObject::~DmaOutObject()
{
	if (pAudioBufferBase)
		VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
}
BOOL DmaOutObject::ReStartDma()
{
	WRITE_REGISTER_ULONG((PULONG)pCHCR1, 
		DMAC_CHCR_RL_ACTIVE_HIGH |
		DMAC_CHCR_SM_INCREMENTED |
		DMAC_CHCR_TS_32 |
		DMAC_CHCR_IE_GENERATED|
		DMAC_CHCR_DE_ENABLED );
	return TRUE;
};
BOOL DmaOutObject::StartDma(BOOL bGenInterrupt)
{
	READ_REGISTER_ULONG((PULONG)pCHCR1  );
	WRITE_REGISTER_ULONG((PULONG)pCHCR1, 
		DMAC_CHCR_RL_ACTIVE_HIGH |
		DMAC_CHCR_SM_INCREMENTED |
		DMAC_CHCR_TS_32 |
		(bGenInterrupt?DMAC_CHCR_IE_GENERATED:DMAC_CHCR_IE_NOT_GENARATED) |
		DMAC_CHCR_DE_ENABLED );
	return TRUE;
}
BOOL DmaOutObject::StopDma()
{
	WRITE_REGISTER_ULONG((PULONG)pCHCR1, 
		DMAC_CHCR_RL_ACTIVE_HIGH |
		DMAC_CHCR_SM_INCREMENTED |
		DMAC_CHCR_TS_32 |
		DMAC_CHCR_IE_GENERATED |
		DMAC_CHCR_DE_DISABLED );
	return TRUE;

}

BOOL DmaOutObject::ArmDma(BOOL bFirstBuffer,DWORD dwPhyAddr)
{

	WRITE_REGISTER_ULONG((PULONG)pSAR1,    (ULONG)(bFirstBuffer?dma_pagePhysicalAddress[0]:dma_pagePhysicalAddress[1]));
	WRITE_REGISTER_ULONG((PULONG)pDAR1,    dwPhyAddr );
	WRITE_REGISTER_ULONG((PULONG)pDMATCR1, (ULONG)( AUDIO_DMA_PAGE_SIZE / 4 ));	// set data count
	return TRUE;
};



DmaObject * CreateDmaObject(BOOL bRecord) 
{
	if (bRecord)
		return new DmaInObject();
	else 
		return new DmaOutObject();
}

⌨️ 快捷键说明

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