OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [peripheral/] [dma.c] - Blame information for rev 793

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 jeremybenn
/* dma.c -- Simulation of DMA
2
 
3
   Copyright (C) 2001 by Erez Volk, erez@opencores.org
4
   Copyright (C) 2008 Embecosm Limited
5
 
6
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7
 
8
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9
 
10
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14
 
15
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19
 
20
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26
/* This simulation of the DMA core is not meant to be full.  It is written
27
   only to allow simulating the Ethernet core.  Of course, if anyone feels
28
   like perfecting it, feel free...  */
29
 
30
 
31
/* Autoconf and/or portability configuration */
32
#include "config.h"
33
#include "port.h"
34
 
35
/* System includes */
36
#include <stdlib.h>
37
 
38
/* Package includes */
39
#include "dma.h"
40
#include "fields.h"
41
#include "abstract.h"
42
#include "sched.h"
43
#include "pic.h"
44
#include "toplevel-support.h"
45
#include "sim-cmd.h"
46
 
47
 
48
/* We keep a copy of all our controllers because we have to export an interface
49
 * to other peripherals eg. ethernet */
50
static struct dma_controller *dmas = NULL;
51
 
52
static unsigned long dma_read_ch_csr (struct dma_channel *channel);
53
static void dma_write_ch_csr (struct dma_channel *channel,
54
                              unsigned long value);
55
static void dma_load_descriptor (struct dma_channel *channel);
56
static void dma_init_transfer (struct dma_channel *channel);
57
static void dma_channel_terminate_transfer (struct dma_channel *channel,
58
                                            int generate_interrupt);
59
 
60
static void dma_channel_clock (void *dat);
61
 
62
static void masked_increase (oraddr_t * value, unsigned long mask);
63
 
64
#define CHANNEL_ND_I(ch) (TEST_FLAG(ch->regs.csr,DMA_CH_CSR,MODE) && TEST_FLAG(ch->regs.csr,DMA_CH_CSR,USE_ED) && ch->dma_nd_i)
65
 
66
 
67
/* Reset. Initializes all registers to default and places devices in memory address space. */
68
static void
69
dma_reset (void *dat)
70
{
71
  struct dma_controller *dma = dat;
72
  unsigned channel_number;
73
 
74
  memset (dma->ch, 0, sizeof (dma->ch));
75
 
76
  dma->regs.csr = 0;
77
  dma->regs.int_msk_a = 0;
78
  dma->regs.int_msk_b = 0;
79
  dma->regs.int_src_a = 0;
80
  dma->regs.int_src_b = 0;
81
 
82
  for (channel_number = 0; channel_number < DMA_NUM_CHANNELS;
83
       ++channel_number)
84
    {
85
      dma->ch[channel_number].controller = dma;
86
      dma->ch[channel_number].channel_number = channel_number;
87
      dma->ch[channel_number].channel_mask = 1LU << channel_number;
88
      dma->ch[channel_number].regs.am0 = dma->ch[channel_number].regs.am1 =
89
        0xFFFFFFFC;
90
    }
91
}
92
 
93
/* Print register values on stdout */
94
static void
95
dma_status (void *dat)
96
{
97
  unsigned j;
98
  struct dma_controller *dma = dat;
99
 
100
  if (dma->baseaddr == 0)
101
    return;
102
 
103
  PRINTF ("\nDMA controller at 0x%" PRIxADDR ":\n", dma->baseaddr);
104
  PRINTF ("CSR       : 0x%08lX\n", dma->regs.csr);
105
  PRINTF ("INT_MSK_A : 0x%08lX\n", dma->regs.int_msk_a);
106
  PRINTF ("INT_MSK_B : 0x%08lX\n", dma->regs.int_msk_b);
107
  PRINTF ("INT_SRC_A : 0x%08lX\n", dma->regs.int_src_a);
108
  PRINTF ("INT_SRC_B : 0x%08lX\n", dma->regs.int_src_b);
109
 
110
  for (j = 0; j < DMA_NUM_CHANNELS; ++j)
111
    {
112
      struct dma_channel *channel = &(dma->ch[j]);
113
      if (!channel->referenced)
114
        continue;
115
      PRINTF ("CH%u_CSR   : 0x%08lX\n", j, channel->regs.csr);
116
      PRINTF ("CH%u_SZ    : 0x%08lX\n", j, channel->regs.sz);
117
      PRINTF ("CH%u_A0    : 0x%08lX\n", j, channel->regs.a0);
118
      PRINTF ("CH%u_AM0   : 0x%08lX\n", j, channel->regs.am0);
119
      PRINTF ("CH%u_A1    : 0x%08lX\n", j, channel->regs.a1);
120
      PRINTF ("CH%u_AM1   : 0x%08lX\n", j, channel->regs.am1);
121
      PRINTF ("CH%u_DESC  : 0x%08lX\n", j, channel->regs.desc);
122
      PRINTF ("CH%u_SWPTR : 0x%08lX\n", j, channel->regs.swptr);
123
    }
124
}
125
 
126
 
127
/* Read a register */
128
static uint32_t
129
dma_read32 (oraddr_t addr, void *dat)
130
{
131
  struct dma_controller *dma = dat;
132
  uint32_t ret;
133
 
134
  if (addr < DMA_CH_BASE)
135
    {
136
      /* case of global (not per-channel) registers */
137
      switch (addr)
138
        {
139
        case DMA_CSR:
140
          return dma->regs.csr;
141
        case DMA_INT_MSK_A:
142
          return dma->regs.int_msk_a;
143
        case DMA_INT_MSK_B:
144
          return dma->regs.int_msk_b;
145
        case DMA_INT_SRC_A:
146
          if (dma->regs.int_src_a)
147
            clear_interrupt (dma->irq);
148
          ret = dma->regs.int_src_a;
149
          dma->regs.int_src_a = 0;
150
          return ret;
151
        case DMA_INT_SRC_B:
152
          return dma->regs.int_src_b;
153
        default:
154
          fprintf (stderr,
155
                   "dma_read32( 0x%" PRIxADDR " ): Illegal register\n",
156
                   addr + dma->baseaddr);
157
          return 0;
158
        }
159
    }
160
  else
161
    {
162
      /* case of per-channel registers */
163
      unsigned chno = (addr - DMA_CH_BASE) / DMA_CH_SIZE;
164
      addr = (addr - DMA_CH_BASE) % DMA_CH_SIZE;
165
      switch (addr)
166
        {
167
        case DMA_CH_CSR:
168
          return dma_read_ch_csr (&(dma->ch[chno]));
169
        case DMA_CH_SZ:
170
          return dma->ch[chno].regs.sz;
171
        case DMA_CH_A0:
172
          return dma->ch[chno].regs.a0;
173
        case DMA_CH_AM0:
174
          return dma->ch[chno].regs.am0;
175
        case DMA_CH_A1:
176
          return dma->ch[chno].regs.a1;
177
        case DMA_CH_AM1:
178
          return dma->ch[chno].regs.am1;
179
        case DMA_CH_DESC:
180
          return dma->ch[chno].regs.desc;
181
        case DMA_CH_SWPTR:
182
          return dma->ch[chno].regs.swptr;
183
        }
184
    }
185
  return 0;
186
}
187
 
188
 
189
/* Handle read from a channel CSR */
190
static unsigned long
191
dma_read_ch_csr (struct dma_channel *channel)
192
{
193
  unsigned long result = channel->regs.csr;
194
 
195
  /* before returning, clear all relevant bits */
196
  CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, INT_CHUNK_DONE);
197
  CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, INT_DONE);
198
  CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, INT_ERR);
199
  CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, ERR);
200
 
201
  return result;
202
}
203
 
204
 
205
 
206
/* Write a register */
207
static void
208
dma_write32 (oraddr_t addr, uint32_t value, void *dat)
209
{
210
  struct dma_controller *dma = dat;
211
 
212
  /* case of global (not per-channel) registers */
213
  if (addr < DMA_CH_BASE)
214
    {
215
      switch (addr)
216
        {
217
        case DMA_CSR:
218
          if (TEST_FLAG (value, DMA_CSR, PAUSE))
219
            fprintf (stderr, "dma: PAUSE not implemented\n");
220
          break;
221
 
222
        case DMA_INT_MSK_A:
223
          dma->regs.int_msk_a = value;
224
          break;
225
        case DMA_INT_MSK_B:
226
          dma->regs.int_msk_b = value;
227
          break;
228
        case DMA_INT_SRC_A:
229
          dma->regs.int_src_a = value;
230
          break;
231
        case DMA_INT_SRC_B:
232
          dma->regs.int_src_b = value;
233
          break;
234
        default:
235
          fprintf (stderr,
236
                   "dma_write32( 0x%" PRIxADDR " ): Illegal register\n",
237
                   addr + dma->baseaddr);
238
          return;
239
        }
240
    }
241
  else
242
    {
243
      /* case of per-channel registers */
244
      unsigned chno = (addr - DMA_CH_BASE) / DMA_CH_SIZE;
245
      struct dma_channel *channel = &(dma->ch[chno]);
246
      channel->referenced = 1;
247
      addr = (addr - DMA_CH_BASE) % DMA_CH_SIZE;
248
      switch (addr)
249
        {
250
        case DMA_CSR:
251
          dma_write_ch_csr (&(dma->ch[chno]), value);
252
          break;
253
        case DMA_CH_SZ:
254
          channel->regs.sz = value;
255
          break;
256
        case DMA_CH_A0:
257
          channel->regs.a0 = value;
258
          break;
259
        case DMA_CH_AM0:
260
          channel->regs.am0 = value;
261
          break;
262
        case DMA_CH_A1:
263
          channel->regs.a1 = value;
264
          break;
265
        case DMA_CH_AM1:
266
          channel->regs.am1 = value;
267
          break;
268
        case DMA_CH_DESC:
269
          channel->regs.desc = value;
270
          break;
271
        case DMA_CH_SWPTR:
272
          channel->regs.swptr = value;
273
          break;
274
        }
275
    }
276
}
277
 
278
 
279
/* Write a channel CSR
280
 * This ensures only the writable bits are modified.
281
 */
282
static void
283
dma_write_ch_csr (struct dma_channel *channel, unsigned long value)
284
{
285
  /* Check if we should *start* a transfer */
286
  if (!TEST_FLAG (channel->regs.csr, DMA_CH_CSR, CH_EN) &&
287
      TEST_FLAG (value, DMA_CH_CSR, CH_EN))
288
    SCHED_ADD (dma_channel_clock, channel, 1);
289
  else if (!TEST_FLAG (value, DMA_CH_CSR, CH_EN))
290
    /* The CH_EN flag is clear, check if we have a transfer in progress and
291
     * clear it */
292
    SCHED_FIND_REMOVE (dma_channel_clock, channel);
293
 
294
  /* Copy the writable bits to the channel CSR */
295
  channel->regs.csr &= ~DMA_CH_CSR_WRITE_MASK;
296
  channel->regs.csr |= value & DMA_CH_CSR_WRITE_MASK;
297
}
298
 
299
 
300
 
301
/* Clock tick for one channel on one DMA controller.
302
 * This does the actual "DMA" operation.
303
 * One chunk is transferred per clock.
304
 */
305
static void
306
dma_channel_clock (void *dat)
307
{
308
  struct dma_channel *channel = dat;
309
 
310
  /* Do we need to abort? */
311
  if (TEST_FLAG (channel->regs.csr, DMA_CH_CSR, STOP))
312
    {
313
      CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, CH_EN);
314
      CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, BUSY);
315
      SET_FLAG (channel->regs.csr, DMA_CH_CSR, ERR);
316
 
317
      if (TEST_FLAG (channel->regs.csr, DMA_CH_CSR, INE_ERR) &&
318
          (channel->controller->regs.int_msk_a & channel->channel_mask))
319
        {
320
          SET_FLAG (channel->regs.csr, DMA_CH_CSR, INT_ERR);
321
          channel->controller->regs.int_src_a = channel->channel_mask;
322
          report_interrupt (channel->controller->irq);
323
        }
324
 
325
      return;
326
    }
327
 
328
  /* In HW Handshake mode, only work when dma_req_i asserted */
329
  if (TEST_FLAG (channel->regs.csr, DMA_CH_CSR, MODE) && !channel->dma_req_i)
330
    {
331
      /* Reschedule */
332
      SCHED_ADD (dma_channel_clock, dat, 1);
333
      return;
334
    }
335
 
336
  /* If this is the first cycle of the transfer, initialize our state */
337
  if (!TEST_FLAG (channel->regs.csr, DMA_CH_CSR, BUSY))
338
    {
339
      CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, DONE);
340
      CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, ERR);
341
      SET_FLAG (channel->regs.csr, DMA_CH_CSR, BUSY);
342
 
343
      /* If using linked lists, copy the appropriate fields to our registers */
344
      if (TEST_FLAG (channel->regs.csr, DMA_CH_CSR, USE_ED))
345
        dma_load_descriptor (channel);
346
      else
347
        channel->load_next_descriptor_when_done = 0;
348
 
349
      /* Set our internal status */
350
      dma_init_transfer (channel);
351
 
352
      /* Might need to skip descriptor */
353
      if (CHANNEL_ND_I (channel))
354
        {
355
          dma_channel_terminate_transfer (channel, 0);
356
          return;
357
        }
358
    }
359
 
360
  /* Transfer one word */
361
  set_direct32 (channel->destination, eval_direct32 (channel->source, 0, 0),
362
                0, 0);
363
 
364
  /* Advance the source and destionation pointers */
365
  masked_increase (&(channel->source), channel->source_mask);
366
  masked_increase (&(channel->destination), channel->destination_mask);
367
  ++channel->words_transferred;
368
 
369
  /* Have we finished a whole chunk? */
370
  channel->dma_ack_o =
371
    (channel->words_transferred % channel->chunk_size == 0);
372
 
373
  /* When done with a chunk, check for dma_nd_i */
374
  if (CHANNEL_ND_I (channel))
375
    {
376
      dma_channel_terminate_transfer (channel, 0);
377
      return;
378
    }
379
 
380
  /* Are we done? */
381
  if (channel->words_transferred >= channel->total_size)
382
    {
383
      dma_channel_terminate_transfer (channel, 1);
384
      return;
385
    }
386
 
387
  /* Reschedule to transfer the next chunk */
388
  SCHED_ADD (dma_channel_clock, dat, 1);
389
}
390
 
391
 
392
/* Copy relevant valued from linked list descriptor to channel registers */
393
static void
394
dma_load_descriptor (struct dma_channel *channel)
395
{
396
  unsigned long desc_csr =
397
    eval_direct32 (channel->regs.desc + DMA_DESC_CSR, 0, 0);
398
 
399
  channel->load_next_descriptor_when_done =
400
    !TEST_FLAG (desc_csr, DMA_DESC_CSR, EOL);
401
 
402
  ASSIGN_FLAG (channel->regs.csr, DMA_CH_CSR, INC_SRC,
403
               TEST_FLAG (desc_csr, DMA_DESC_CSR, INC_SRC));
404
  ASSIGN_FLAG (channel->regs.csr, DMA_CH_CSR, INC_DST,
405
               TEST_FLAG (desc_csr, DMA_DESC_CSR, INC_DST));
406
  ASSIGN_FLAG (channel->regs.csr, DMA_CH_CSR, SRC_SEL,
407
               TEST_FLAG (desc_csr, DMA_DESC_CSR, SRC_SEL));
408
  ASSIGN_FLAG (channel->regs.csr, DMA_CH_CSR, DST_SEL,
409
               TEST_FLAG (desc_csr, DMA_DESC_CSR, DST_SEL));
410
 
411
  SET_FIELD (channel->regs.sz, DMA_CH_SZ, TOT_SZ,
412
             GET_FIELD (desc_csr, DMA_DESC_CSR, TOT_SZ));
413
 
414
  channel->regs.a0 = eval_direct32 (channel->regs.desc + DMA_DESC_ADR0, 0, 0);
415
  channel->regs.a1 = eval_direct32 (channel->regs.desc + DMA_DESC_ADR1, 0, 0);
416
 
417
  channel->current_descriptor = channel->regs.desc;
418
  channel->regs.desc =
419
    eval_direct32 (channel->regs.desc + DMA_DESC_NEXT, 0, 0);
420
}
421
 
422
 
423
/* Initialize internal parameters used to implement transfers */
424
static void
425
dma_init_transfer (struct dma_channel *channel)
426
{
427
  channel->source = channel->regs.a0;
428
  channel->destination = channel->regs.a1;
429
  channel->source_mask =
430
    TEST_FLAG (channel->regs.csr, DMA_CH_CSR,
431
               INC_SRC) ? channel->regs.am0 : 0;
432
  channel->destination_mask =
433
    TEST_FLAG (channel->regs.csr, DMA_CH_CSR,
434
               INC_DST) ? channel->regs.am1 : 0;
435
  channel->total_size = GET_FIELD (channel->regs.sz, DMA_CH_SZ, TOT_SZ);
436
  channel->chunk_size = GET_FIELD (channel->regs.sz, DMA_CH_SZ, CHK_SZ);
437
  if (!channel->chunk_size || (channel->chunk_size > channel->total_size))
438
    channel->chunk_size = channel->total_size;
439
  channel->words_transferred = 0;
440
}
441
 
442
 
443
/* Take care of transfer termination */
444
static void
445
dma_channel_terminate_transfer (struct dma_channel *channel,
446
                                int generate_interrupt)
447
{
448
  /* Might be working in a linked list */
449
  if (channel->load_next_descriptor_when_done)
450
    {
451
      dma_load_descriptor (channel);
452
      dma_init_transfer (channel);
453
      /* Reschedule */
454
      SCHED_ADD (dma_channel_clock, channel, 1);
455
      return;
456
    }
457
 
458
  /* Might be in auto-restart mode */
459
  if (TEST_FLAG (channel->regs.csr, DMA_CH_CSR, ARS))
460
    {
461
      dma_init_transfer (channel);
462
      return;
463
    }
464
 
465
  /* If needed, write amount of data transferred back to memory */
466
  if (TEST_FLAG (channel->regs.csr, DMA_CH_CSR, SZ_WB) &&
467
      TEST_FLAG (channel->regs.csr, DMA_CH_CSR, USE_ED))
468
    {
469
      /* TODO: What should we write back? Doc says "total number of remaining bytes" !? */
470
      unsigned long remaining_words =
471
        channel->total_size - channel->words_transferred;
472
      SET_FIELD (channel->regs.sz, DMA_DESC_CSR, TOT_SZ, remaining_words);
473
    }
474
 
475
  /* Mark end of transfer */
476
  CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, CH_EN);
477
  SET_FLAG (channel->regs.csr, DMA_CH_CSR, DONE);
478
  CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, ERR);
479
  CLEAR_FLAG (channel->regs.csr, DMA_CH_CSR, BUSY);
480
 
481
  /* If needed, generate interrupt */
482
  if (generate_interrupt)
483
    {
484
      /* TODO: Which channel should we interrupt? */
485
      if (TEST_FLAG (channel->regs.csr, DMA_CH_CSR, INE_DONE) &&
486
          (channel->controller->regs.int_msk_a & channel->channel_mask))
487
        {
488
          SET_FLAG (channel->regs.csr, DMA_CH_CSR, INT_DONE);
489
          channel->controller->regs.int_src_a = channel->channel_mask;
490
          report_interrupt (channel->controller->irq);
491
        }
492
    }
493
}
494
 
495
/* Utility function: Add 4 to a value with a mask */
496
static void
497
masked_increase (oraddr_t * value, unsigned long mask)
498
{
499
  *value = (*value & ~mask) | ((*value + 4) & mask);
500
}
501
 
502
/*-------------------------------------------[ DMA<->Peripheral interface ]---*/
503
/*
504
 * Simulation of control signals
505
 * To be used by simulations for other devices, e.g. ethernet
506
 */
507
 
508
void
509
set_dma_req_i (struct dma_channel *channel)
510
{
511
  channel->dma_req_i = 1;
512
}
513
 
514
void
515
clear_dma_req_i (struct dma_channel *channel)
516
{
517
  channel->dma_req_i = 0;
518
}
519
 
520
void
521
set_dma_nd_i (struct dma_channel *channel)
522
{
523
  channel->dma_nd_i = 1;
524
}
525
 
526
void
527
clear_dma_nd_i (struct dma_channel *channel)
528
{
529
  channel->dma_nd_i = 0;
530
}
531
 
532
unsigned
533
check_dma_ack_o (struct dma_channel *channel)
534
{
535
  return channel->dma_ack_o;
536
}
537
 
538
struct dma_channel *
539
find_dma_controller_ch (unsigned controller, unsigned channel)
540
{
541
  struct dma_controller *cur = dmas;
542
 
543
  while (cur && controller)
544
    {
545
      cur = cur->next;
546
      controller--;
547
    }
548
 
549
  if (!cur)
550
    return NULL;
551
 
552
  return &(cur->ch[channel]);
553
}
554
 
555
 
556
/*----------------------------------------------------[ DMA configuration ]---*/
557
static void
558
dma_baseaddr (union param_val val, void *dat)
559
{
560
  struct dma_controller *dma = dat;
561
  dma->baseaddr = val.addr_val;
562
}
563
 
564
static void
565
dma_irq (union param_val val, void *dat)
566
{
567
  struct dma_controller *dma = dat;
568
  dma->irq = val.int_val;
569
}
570
 
571
static void
572
dma_vapi_id (union param_val val, void *dat)
573
{
574
  struct dma_controller *dma = dat;
575
  dma->vapi_id = val.int_val;
576
}
577
 
578
static void
579
dma_enabled (union param_val val, void *dat)
580
{
581
  struct dma_controller *dma = dat;
582
  dma->enabled = val.int_val;
583
}
584
 
585
 
586
/*---------------------------------------------------------------------------*/
587
/*!Initialize a new DMA configuration
588
 
589
   ALL parameters are set explicitly to default values.                      */
590
/*---------------------------------------------------------------------------*/
591
static void *
592
dma_sec_start ()
593
{
594
  struct dma_controller *new = malloc (sizeof (struct dma_controller));
595
 
596
  if (!new)
597
    {
598
      fprintf (stderr, "Peripheral DMA: Run out of memory\n");
599
      exit (-1);
600
    }
601
 
602
  new->next = NULL;
603
  new->enabled  = 1;
604
  new->baseaddr = 0;
605
  new->irq      = 0;
606
  new->vapi_id  = 0;
607
 
608
  return new;
609
 
610
}       /* dma_sec_start() */
611
 
612
static void
613
dma_sec_end (void *dat)
614
{
615
  struct dma_controller *dma = dat;
616
  struct dma_controller *cur;
617
  struct mem_ops ops;
618
 
619
  if (!dma->enabled)
620
    {
621
      free (dat);
622
      return;
623
    }
624
 
625
  memset (&ops, 0, sizeof (struct mem_ops));
626
 
627
  ops.readfunc32 = dma_read32;
628
  ops.writefunc32 = dma_write32;
629
  ops.read_dat32 = dat;
630
  ops.write_dat32 = dat;
631
 
632
  /* FIXME: Correct delay?? */
633
  ops.delayr = 2;
634
  ops.delayw = 2;
635
 
636
  reg_mem_area (dma->baseaddr, DMA_ADDR_SPACE, 0, &ops);
637
  reg_sim_reset (dma_reset, dat);
638
  reg_sim_stat (dma_status, dat);
639
 
640
  if (dmas)
641
    {
642
      for (cur = dmas; cur->next; cur = cur->next);
643
      cur->next = dma;
644
    }
645
  else
646
    dmas = dma;
647
}
648
 
649
void
650
reg_dma_sec (void)
651
{
652
  struct config_section *sec =
653
    reg_config_sec ("dma", dma_sec_start, dma_sec_end);
654
 
655 224 jeremybenn
  reg_config_param (sec, "enabled",  PARAMT_INT, dma_enabled);
656
  reg_config_param (sec, "baseaddr", PARAMT_ADDR, dma_baseaddr);
657
  reg_config_param (sec, "irq",      PARAMT_INT, dma_irq);
658
  reg_config_param (sec, "vapi_id",  PARAMT_ADDR, dma_vapi_id);
659 19 jeremybenn
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.