📄 test.cpp
字号:
//-----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//-----------------------------------------------------------------------------
//
// File: test.cpp
//
// This file contains test code for the DMA driver.
//
//-----------------------------------------------------------------------------
#include "main.h"
#include "globals.h"
#include "bsp.h"
typedef __int64 timer_type;
//-----------------------------------------------------------------------------
// External Functions
//-----------------------------------------------------------------------------
// External Variables
//-----------------------------------------------------------------------------
// Defines
#define DMA_TEST_CHANNEL1 15
#define DMA_TEST_CHANNEL2 14
#define IRQ_TEST1 IRQ_DMACH15
#define IRQ_TEST2 IRQ_DMACH14
#ifdef DMAC_CHANNEL_INVALID
#undef DMAC_CHANNEL_INVALID
#endif
#define DMAC_CHANNEL_INVALID 0xff
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// Local Functions
//-----------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
//
// Function: OpenCloseChanTest
//
// This function tests open and close operation of the DMA virtual channels.
// The test will attempt to open all available channels and verify that the
// correct virtual channel ID is returned. All successfully opened channels
// are then closed.
//
// Parameters:
// uiMsg
// [in] Message code.
//
// tpParam
// [in] Additional message-dependent data.
//
// lpFTE
// [in] Function table entry that generated this call.
//
// Returns:
// TPR_PASS if the test passed, TPR_FAIL if the test fails, or possibly other
// special conditions.
//
//------------------------------------------------------------------------------
TESTPROCAPI OpenCloseChanTest(UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE)
{
INT i, rc = TPR_PASS;
UINT8 chan[DMAC_NUM_CHANNELS];
// The shell doesn't necessarily want us to execute the test. Make sure
// first.
if(uMsg != TPM_EXECUTE)
{
return TPR_NOT_HANDLED;
}
g_pKato->Log(LOG_COMMENT, TEXT("Starting OpenCloseChanTest..."));
// Clear out the channel array
memset(chan, 0, sizeof(chan));
// For each available channel
for (i = 0; i < DMAC_NUM_CHANNELS; i++)
{
// Get a channel handle
chan[i] = DDKDmacRequestChan(i);
RETAILMSG(1, (TEXT("DDKDmacRequestChan(%d) return 0x%x\r\n"), i, chan[i]));
}
// Determine number of channels successfully opened
for (i = 0; i < DMAC_NUM_CHANNELS; i++)
{
// Stop once we hit open request failure
if (chan[i] == DMAC_CHANNEL_INVALID) break;
}
// If we did not open any channels successfully
if (i == 0)
{
g_pKato->Log(LOG_FAIL, TEXT("FAILURE: OpenCloseChanTest could not open any channels"));
rc = TPR_FAIL;
}
else
{
g_pKato->Log(LOG_COMMENT, TEXT("Successfully opened %d channels"), i);
}
// Make sure remaining open requests returned open failure
for ( ; i < DMAC_NUM_CHANNELS; i++)
{
// Stop if we hit any open request successes
if (chan[i] != DMAC_CHANNEL_INVALID) break;
}
// If we hit more open request successes
if (i != DMAC_NUM_CHANNELS)
{
g_pKato->Log(LOG_FAIL, TEXT("FAILURE: OpenCloseChanTest opened suceeded beyond available channels"));
rc = TPR_FAIL;
}
// Close all channels successfully opened
for (i = 0; i < DMAC_NUM_CHANNELS; i++)
{
// If open was successful
if (chan[i] != DMAC_CHANNEL_INVALID)
{
if (! DDKDmacReleaseChan(chan[i]))
{
g_pKato->Log(LOG_FAIL, TEXT("DDKDmacReleaseChan failed: chan[%d] = %d"), i, chan[i]);
rc = TPR_FAIL;
}
else
g_pKato->Log(LOG_COMMENT, TEXT("DDKDmacReleaseChan success: chan[%d] = %d"), i, chan[i]);
}
}
g_pKato->Log(LOG_COMMENT, TEXT("Ending OpenCloseChanTest..."));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: Mem2MemTest
//
// This function tests the DMA's ability to perform a memory-to-memory
// transfer. Two virtual channels are requested and then two buffers are used
// to define a memory transfer. The transfer is done in both directions and
// the results are verified. This transfer is interrupt-driven and uses
// the standard OAL interrupt registration procedures normally used by
// device drivers.
//
// Parameters:
// uiMsg
// [in] Message code.
//
// tpParam
// [in] Additional message-dependent data.
//
// lpFTE
// [in] Function table entry that generated this call.
//
// Returns:
// TPR_PASS if the test passed, TPR_FAIL if the test fails, or possibly other
// special conditions.
//
//------------------------------------------------------------------------------
TESTPROCAPI Mem2MemTest(UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE)
{
INT rc = TPR_FAIL;
DMA_ADAPTER_OBJECT dmaAdapter = { sizeof(DMA_ADAPTER_OBJECT), Internal, 0 };
PHYSICAL_ADDRESS phyAddr[4];
PUINT8 pBuf[4];
UINT8 chan1, chan2;
HANDLE hEvent1 = NULL;
HANDLE hEvent2 = NULL;
UINT32 irq;
UINT32 sysintr1 = SYSINTR_UNDEFINED;
UINT32 sysintr2 = SYSINTR_UNDEFINED;
//UINT32 status[2];
UINT32 bufSize = 32*1024;
DMAC_CHANNEL_CFG dmaCfg1, dmaCfg2;
timer_type finish_count_1, start_count_1;
timer_type finish_count_2, start_count_2;
timer_type resolution;
QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>(&resolution) );
// The shell doesn't necessarily want us to execute the test. Make sure
// first.
if(uMsg != TPM_EXECUTE)
{
return TPR_NOT_HANDLED;
}
g_pKato->Log(LOG_COMMENT, TEXT("Starting Mem2MemTest..."));
// Request the first memory-to-memory channel
chan1 = DDKDmacRequestChan(DMA_TEST_CHANNEL1);
if (chan1 == DMAC_CHANNEL_INVALID)
{
g_pKato->Log(LOG_FAIL, TEXT("DDKDmacRequestChan failed!"));
goto cleanUp;
}
// Request the second memory-to-memory channel
chan2 = DDKDmacRequestChan(DMA_TEST_CHANNEL2);
if (chan2 == DMAC_CHANNEL_INVALID)
{
g_pKato->Log(LOG_FAIL, TEXT("DDKDmacRequestChan failed!"));
goto cleanUp;
}
g_pKato->Log(LOG_COMMENT, TEXT("CHAN1 = %d"), chan1);
g_pKato->Log(LOG_COMMENT, TEXT("CHAN2 = %d"), chan2);
// Allocate buffers for memory-to-memory transfer testing
pBuf[0] = (PUINT8) HalAllocateCommonBuffer(&dmaAdapter, 4*bufSize, &phyAddr[0], FALSE);
if (pBuf[0] == NULL)
{
g_pKato->Log(LOG_FAIL, TEXT("HalAllocateCommonBuffer failed!"));
goto cleanUp;
}
pBuf[1] = pBuf[0] + bufSize;
pBuf[2] = pBuf[1] + bufSize;
pBuf[3] = pBuf[2] + bufSize;
phyAddr[1].LowPart = phyAddr[0].LowPart + bufSize;
phyAddr[2].LowPart = phyAddr[1].LowPart + bufSize;
phyAddr[3].LowPart = phyAddr[2].LowPart + bufSize;
g_pKato->Log(LOG_COMMENT, TEXT("DMA common buffer[0] UA = 0x%x, PA = 0x%x "),
pBuf[0], phyAddr[0].LowPart);
g_pKato->Log(LOG_COMMENT, TEXT("DMA common buffer[1] UA = 0x%x, PA = 0x%x "),
pBuf[1], phyAddr[1].LowPart);
g_pKato->Log(LOG_COMMENT, TEXT("DMA common buffer[2] UA = 0x%x, PA = 0x%x "),
pBuf[2], phyAddr[2].LowPart);
g_pKato->Log(LOG_COMMENT, TEXT("DMA common buffer[3] UA = 0x%x, PA = 0x%x "),
pBuf[3], phyAddr[3].LowPart);
// Create event for signaling end of transfer
hEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);
hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);
if (hEvent1 == NULL || hEvent2 == NULL)
{
g_pKato->Log(LOG_FAIL, TEXT("CreateEvent failed!"));
goto cleanUp;
}
// Request the first SYSINTR from OAL
// Request channel may turn out return different available channel no
irq = IRQ_DMACH0+chan1;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(irq),
&sysintr1, sizeof(sysintr1), NULL))
{
g_pKato->Log(LOG_FAIL, TEXT("IOCTL_HAL_REQUEST_SYSINTR failed!"));
goto cleanUp;
}
g_pKato->Log(LOG_COMMENT, TEXT("IRQ1 = %d, SYSINTR1 = %d"), irq, sysintr1);
// Request the second SYSINTR from OAL
// Request channel may turn out return different available channel no
irq = IRQ_DMACH0+chan2;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(irq),
&sysintr2, sizeof(sysintr2), NULL))
{
g_pKato->Log(LOG_FAIL, TEXT("IOCTL_HAL_REQUEST_SYSINTR failed!"));
goto cleanUp;
}
g_pKato->Log(LOG_COMMENT, TEXT("IRQ2 = %d, SYSINTR2 = %d"), irq, sysintr2);
// Register our interrupt
if (!InterruptInitialize(sysintr1, hEvent1, NULL, 0))
{
g_pKato->Log(LOG_FAIL, TEXT("InterruptInitialize failed!"));
goto cleanUp;
}
if (!InterruptInitialize(sysintr2, hEvent2, NULL, 0))
{
g_pKato->Log(LOG_FAIL, TEXT("InterruptInitialize failed!"));
goto cleanUp;
}
// Initialize buffers
memset(pBuf[0], 0x00, bufSize);
memset(pBuf[1], 0xFF, bufSize);
memset(pBuf[2], 0xFF, bufSize);
memset(pBuf[3], 0x00, bufSize);
dmaCfg1.SrcAddr = phyAddr[0].LowPart;
dmaCfg1.DstAddr = phyAddr[2].LowPart;
dmaCfg1.DataSize = bufSize;
dmaCfg1.DstMode = DMAC_TRANSFER_MODE_LINEAR_MEMORY;
dmaCfg1.SrcMode = DMAC_TRANSFER_MODE_LINEAR_MEMORY;
dmaCfg1.MemDirIncrease = TRUE;
dmaCfg1.DstSize = DMAC_TRANSFER_SIZE_32BIT;
dmaCfg1.SrcSize = DMAC_TRANSFER_SIZE_32BIT;
dmaCfg1.RepeatType = DMAC_REPEAT_DISABLED;
dmaCfg1.ExtReqEnable = FALSE;
//dmaCfg1.ReqSrc = 0;
dmaCfg1.BurstLength = 4;
dmaCfg1.ReqTimeout = FALSE;
dmaCfg1.ReqTOCounter = 0;
dmaCfg1.BusClkCounter = 0;
dmaCfg2.SrcAddr = phyAddr[1].LowPart;
dmaCfg2.DstAddr = phyAddr[3].LowPart;
dmaCfg2.DataSize = bufSize;
dmaCfg2.DstMode = DMAC_TRANSFER_MODE_LINEAR_MEMORY;
dmaCfg2.SrcMode = DMAC_TRANSFER_MODE_LINEAR_MEMORY;
dmaCfg2.MemDirIncrease = TRUE;
dmaCfg2.DstSize = DMAC_TRANSFER_SIZE_32BIT;
dmaCfg2.SrcSize = DMAC_TRANSFER_SIZE_32BIT;
dmaCfg2.RepeatType = DMAC_REPEAT_DISABLED;
dmaCfg2.ExtReqEnable = FALSE;
//dmaCfg2.ReqSrc = 0;
dmaCfg2.BurstLength = 4;
dmaCfg2.ReqTimeout = FALSE;
dmaCfg2.ReqTOCounter = 0;
dmaCfg2.BusClkCounter = 0;
if(DDKDmacConfigureChan(chan1, &dmaCfg1) == DMAC_CHANNEL_INVALID)
{
g_pKato->Log(LOG_FAIL, TEXT("DDKDmacConfigureChan failed!"));
goto cleanUp;
}
if(DDKDmacConfigureChan(chan2, &dmaCfg2) == DMAC_CHANNEL_INVALID)
{
g_pKato->Log(LOG_FAIL, TEXT("DDKDmacConfigureChan failed!"));
goto cleanUp;
}
// PreClear any interrupt status
DDKDmacClearChannelIntr(chan1);
DDKDmacClearChannelIntr(chan2);
// Enable the interrupt status
DDKDmacEnableChannelIntr(chan1);
DDKDmacEnableChannelIntr(chan2);
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &start_count_1 ) );
// Start the transfer
if (!DDKDmacStartChan(chan1))
{
g_pKato->Log(LOG_FAIL, TEXT("DDKDmacStartChan failed!"));
goto cleanUp;
}
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &start_count_2 ) );
if (!DDKDmacStartChan(chan2))
{
g_pKato->Log(LOG_FAIL, TEXT("DDKDmacStartChan failed!"));
goto cleanUp;
}
// Wait for interrupt signaling end of transfer
if (WaitForSingleObject(hEvent1, 5000) != WAIT_OBJECT_0)
{
g_pKato->Log(LOG_FAIL, TEXT("WaitForSingleObject failed!"));
goto cleanUp;
}
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &finish_count_1 ) );
// Wait for interrupt signaling end of transfer
if (WaitForSingleObject(hEvent2, 5000) != WAIT_OBJECT_0)
{
g_pKato->Log(LOG_FAIL, TEXT("WaitForSingleObject failed!"));
goto cleanUp;
}
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &finish_count_2 ) );
// Check transfer results
if (memcmp(pBuf[0], pBuf[2], bufSize) != 0)
{
g_pKato->Log(LOG_FAIL, TEXT("Transfer failed!"));
goto cleanUp;
}
if (memcmp(pBuf[1], pBuf[3], bufSize) != 0)
{
g_pKato->Log(LOG_FAIL, TEXT("Transfer failed!"));
goto cleanUp;
}
g_pKato->Log(LOG_COMMENT, TEXT("Transfer #1 completed successfully..."));
// Signal interrupt processing complete and disable the interrupt
InterruptDone(sysintr1);
InterruptDone(sysintr2);
RETAILMSG(1, (TEXT("1) Finish_Count = %d\r\n"), finish_count_1));
RETAILMSG(1, (TEXT("1) Diff = %d\r\n"), (finish_count_1-start_count_1)));
RETAILMSG(1, (TEXT("1) Total %dms\r\n"), (finish_count_1-start_count_1)*1000/resolution));
RETAILMSG(1, (TEXT("2) Finish_Count = %d\r\n"), finish_count_2));
RETAILMSG(1, (TEXT("2) Diff = %d\r\n"), (finish_count_2-start_count_2)));
RETAILMSG(1, (TEXT("2) Total %dms\r\n"), (finish_count_2-start_count_2)*1000/resolution));
rc = TPR_PASS;
cleanUp:
g_pKato->Log(LOG_COMMENT, TEXT("Ending Mem2MemTest..."));
InterruptDone(sysintr1);
InterruptDisable(sysintr1);
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &sysintr1, sizeof(sysintr1),
NULL, 0, NULL);
DDKDmacReleaseChan(chan1);
InterruptDone(sysintr2);
InterruptDisable(sysintr2);
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &sysintr2, sizeof(sysintr2),
NULL, 0, NULL);
DDKDmacReleaseChan(chan2);
return rc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -