Пример #1
0
static void xdma_start_transfer(struct xdma_chan *chan,
				int start_index,
				int end_index)
{
	dma_addr_t cur_phys;
	dma_addr_t tail_phys;
	u32 regval;

	if (chan->err)
		return;

	cur_phys = chan->bd_phys_addr + (start_index *
					sizeof(struct xdma_desc_hw));
	tail_phys = chan->bd_phys_addr + (end_index *
					sizeof(struct xdma_desc_hw));
	/* If hardware is busy, move the tail & return */
	if (dma_is_running(chan) || dma_is_idle(chan)) {
		/* Update tail ptr register and start the transfer */
		DMA_OUT(&chan->regs->tdr, tail_phys);
		return;
	}

	DMA_OUT(&chan->regs->cdr, cur_phys);

	dma_start(chan);

	/* Enable interrupts */
	regval = DMA_IN(&chan->regs->cr);
	regval |= (chan->poll_mode ? XDMA_XR_IRQ_ERROR_MASK
					: XDMA_XR_IRQ_ALL_MASK);
	DMA_OUT(&chan->regs->cr, regval);

	/* Update tail ptr register and start the transfer */
	DMA_OUT(&chan->regs->tdr, tail_phys);
}
Пример #2
0
void test_dma_writes(ssize_t f) {

  int PAGE_SIZE = 4*1024;
  int BUF_SIZE = PAGE_SIZE;
  char *data = 0;
  char *ret_data = 0;
  
  posix_memalign ((void*)&data, PAGE_SIZE, BUF_SIZE);
  posix_memalign ((void*)&ret_data, PAGE_SIZE, BUF_SIZE);
  
  memset (data, 1234, BUF_SIZE/4);
  sprintf (data, "Hello from DE4!\n");
  data[15] = '\0';
  fprintf (stderr, "First small part of what we're writing: %s\n", data);
  // fprintf (stderr, "Writing %d bytes to %p from %p\n", BUF_SIZE, 0, data);

  write_mem (f, 0, (void*)(0), data, BUF_SIZE);
  while (!dma_is_idle(f))
   dma_update(f);
  
  // fprintf (stderr, "Reading back %d bytes from %p to %p\n", BUF_SIZE, 0, ret_data);
  
  read_mem (f, 0, (void*)(0), ret_data, BUF_SIZE);
  while (!dma_is_idle(f))
   dma_update(f);
   
  fprintf (stderr, "First small part of data we got back: %s\n", ret_data);
  
  
  assert (memcmp(data, ret_data, BUF_SIZE) == 0);
  fprintf (stderr, "DMA write passed!\n");
  
  
  
  return;
}
Пример #3
0
/* Test reading and writing long chunks of data */
void test_large_read_write (ssize_t f) {

  int j, num_write_runs = 5;
  size_t buf_size = 80 * 1024 * 1024;
  char *buf1 = NULL;
  char *buf2 = NULL;
  const size_t ALIGNMENT = 4096;
  posix_memalign ((void**)&buf1, ALIGNMENT, buf_size);
  posix_memalign ((void**)&buf2, ALIGNMENT, buf_size);
  
  if (buf1 == NULL || buf2 == NULL) {
    printf ("Couldn't allocate memory! FAILED\n");
  }
  
  /* Some "real" data to fill memory with. */
  FILE *data_file = fopen ("tests/ulysses.txt", "r");
  if (data_file == NULL) {
    printf ("Couldn't open data file! FAILED\n");
  }

  /* read data file in chunks of 4 KB */
  size_t read_step = 1024 * 4;
  size_t num_read = 0;
  size_t incr = 0, file_size = 0;
  while ( (num_read = fread (buf1 + incr, sizeof(char), read_step, data_file)) ) {
    incr += num_read;
    if (num_read < read_step) {
      /* Done reading */
      break;
    }
  }
  /* Copy the file content until fill the buffer */
  file_size = incr;
  while (incr < (buf_size - file_size)) {
    memcpy (buf1 + incr, buf1, file_size);
    incr += file_size;
  }
  assert (incr < buf_size);
  incr = incr - (incr % ALIGNMENT);
  printf ("Useful data size for large read/write test is %zu bytes\n", incr);
  
  clock_t start = clock();
  clock_t e1, e2;
  
  /* Write to different locations on each run just to avoid
   * any kind of caching on PCIe block. */
  for (j = 0; j < num_write_runs; j++) {
    write_mem (f, 0, (void*)(incr * j), buf1, incr);
    while (!dma_is_idle(f))
      dma_update(f);
  }
  e1 = clock();

  read_mem (f, 0, 0, buf2, incr);
  while (!dma_is_idle(f))
      dma_update(f);
  e2 = clock();
  
  double t1 = ((double)e1 - start) / CLOCKS_PER_SEC;
  double t2 = ((double)e2 - e1) / CLOCKS_PER_SEC;
  int mb = 1024 * 1024;
  printf ("Writing %zu bytes took %.3f seconds (%.3f MB / sec)\n", 
        incr, t1, incr / mb / t1 * num_write_runs );
  printf ("Reading %zu bytes took %.3f seconds (%.3f MB / sec)\n", 
        incr, t2, incr / mb / t2 );
  
  /* Make sure what we read back is the same as what we wrote */
  assert (memcmp (buf1, buf2, incr) == 0);
  printf ("test_large_read_write PASSED\n");
  
  free (buf1);
  free (buf2);
  return;
}