Line 22... |
Line 22... |
* This simulation of the DMA core is not meant to be full.
|
* This simulation of the DMA core is not meant to be full.
|
* It is written only to allow simulating the Ethernet core.
|
* It is written only to allow simulating the Ethernet core.
|
* Of course, if anyone feels like perfecting it, feel free...
|
* Of course, if anyone feels like perfecting it, feel free...
|
*/
|
*/
|
|
|
|
#include <string.h>
|
|
|
#include "dma.h"
|
#include "dma.h"
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "pic.h"
|
#include "pic.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "fields.h"
|
#include "fields.h"
|
|
#include "debug.h"
|
|
|
/* The representation of the DMA controllers */
|
/* The representation of the DMA controllers */
|
static struct dma_controller dmas[MAX_DMAS];
|
static struct dma_controller dmas[MAX_DMAS];
|
|
|
static unsigned long dma_read32( unsigned long addr );
|
static unsigned long dma_read32( unsigned long addr );
|
Line 81... |
Line 84... |
struct dma_controller *dma = &(dmas[i]);
|
struct dma_controller *dma = &(dmas[i]);
|
|
|
if ( dma->baseaddr == 0 )
|
if ( dma->baseaddr == 0 )
|
continue;
|
continue;
|
|
|
PRINTF( "\nDMA controller %u at 0x%08X:\n", i, dma->baseaddr );
|
PRINTF( "\nDMA controller %u at 0x%08lX:\n", i, dma->baseaddr );
|
PRINTF( "CSR : 0x%08lX\n", dma->regs.csr );
|
PRINTF( "CSR : 0x%08lX\n", dma->regs.csr );
|
PRINTF( "INT_MSK_A : 0x%08lX\n", dma->regs.int_msk_a );
|
PRINTF( "INT_MSK_A : 0x%08lX\n", dma->regs.int_msk_a );
|
PRINTF( "INT_MSK_B : 0x%08lX\n", dma->regs.int_msk_b );
|
PRINTF( "INT_MSK_B : 0x%08lX\n", dma->regs.int_msk_b );
|
PRINTF( "INT_SRC_A : 0x%08lX\n", dma->regs.int_src_a );
|
PRINTF( "INT_SRC_A : 0x%08lX\n", dma->regs.int_src_a );
|
PRINTF( "INT_SRC_B : 0x%08lX\n", dma->regs.int_src_b );
|
PRINTF( "INT_SRC_B : 0x%08lX\n", dma->regs.int_src_b );
|
Line 302... |
Line 305... |
* This does the actual "DMA" operation.
|
* This does the actual "DMA" operation.
|
* One chunk is transferred per clock.
|
* One chunk is transferred per clock.
|
*/
|
*/
|
void dma_controller_clock( struct dma_controller *dma )
|
void dma_controller_clock( struct dma_controller *dma )
|
{
|
{
|
unsigned chno, i;
|
unsigned chno;
|
int breakpoint = 0;
|
int breakpoint = 0;
|
|
|
for ( chno = 0; chno < DMA_NUM_CHANNELS; ++ chno ) {
|
for ( chno = 0; chno < DMA_NUM_CHANNELS; ++ chno ) {
|
struct dma_channel *channel = &(dma->ch[chno]);
|
struct dma_channel *channel = &(dma->ch[chno]);
|
|
|
Line 444... |
Line 447... |
}
|
}
|
|
|
/* If needed, write amount of data transferred back to memory */
|
/* If needed, write amount of data transferred back to memory */
|
if ( TEST_FLAG( channel->regs.csr, DMA_CH_CSR, SZ_WB ) &&
|
if ( TEST_FLAG( channel->regs.csr, DMA_CH_CSR, SZ_WB ) &&
|
TEST_FLAG( channel->regs.csr, DMA_CH_CSR, USE_ED ) ) {
|
TEST_FLAG( channel->regs.csr, DMA_CH_CSR, USE_ED ) ) {
|
int breakpoint = 0;
|
|
unsigned long desc_csr = eval_mem32( channel->regs.desc + DMA_DESC_CSR, &breakpoint );
|
|
/* TODO: What should we write back? Doc says "total number of remaining bytes" !? */
|
/* TODO: What should we write back? Doc says "total number of remaining bytes" !? */
|
unsigned long remaining_words = channel->total_size - channel->words_transferred;
|
unsigned long remaining_words = channel->total_size - channel->words_transferred;
|
SET_FIELD( channel->regs.sz, DMA_DESC_CSR, TOT_SZ, remaining_words );
|
SET_FIELD( channel->regs.sz, DMA_DESC_CSR, TOT_SZ, remaining_words );
|
}
|
}
|
|
|