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 + -
显示快捷键?