Beispiel #1
0
/* Creates a new instance of the dev_pcie */
static llio_dev_pcie_t * llio_dev_pcie_new (const char *dev_entry)
{
    llio_dev_pcie_t *self = (llio_dev_pcie_t *) zmalloc (sizeof *self);
    ASSERT_ALLOC (self, err_llio_dev_pcie_alloc);

    self->dev = (pd_device_t *) zmalloc (sizeof *self->dev);
    ASSERT_ALLOC (self->dev, err_dev_pcie_alloc);

    /* FIXME: hardcoded dev number */
    /* TODO: should we use llio_endpoint_get to get the endpoint name? */
    int err = pd_open (0, self->dev, dev_entry);

    if (err != 0) {
        perror ("pd_open");
    }
    ASSERT_TEST(err==0, "Error opening device", err_dev_pcie_open);

    /* Map all available BARs */
    self->bar0 = (uint32_t *) pd_mapBAR (self->dev, BAR0NO);
    ASSERT_TEST(self->bar0!=NULL, "Could not allocate bar0", err_bar0_alloc);
    self->bar2 = (uint32_t *) pd_mapBAR (self->dev, BAR2NO);
    ASSERT_TEST(self->bar2!=NULL, "Could not allocate bar2", err_bar2_alloc);
    DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, "[ll_io_pcie] BAR2 addr = %p\n",
            self->bar2);
    self->bar4 = (uint64_t *) pd_mapBAR (self->dev, BAR4NO);
    ASSERT_TEST(self->bar4!=NULL, "Could not allocate bar4", err_bar4_alloc);
    DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, "[ll_io_pcie] BAR4 addr = %p\n",
            self->bar4);

    self->bar0_size = pd_getBARsize (self->dev, BAR0NO);
    ASSERT_TEST(self->bar0_size > 0, "Could not get bar0 size", err_bar0_size);
    self->bar2_size = pd_getBARsize (self->dev, BAR2NO);
    ASSERT_TEST(self->bar2_size > 0, "Could not get bar2 size", err_bar2_size);
    self->bar4_size = pd_getBARsize (self->dev, BAR4NO);
    ASSERT_TEST(self->bar4_size > 0, "Could not get bar4 size", err_bar4_size);

    /* Initialize PCIE timeout pattern */
    memset (&pcie_timeout_patt, PCIE_TIMEOUT_PATT_INIT, sizeof (pcie_timeout_patt));
    DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, "[ll_io_pcie] Created instance of llio_dev_pcie\n");

    return self;

err_bar4_size:
err_bar2_size:
err_bar0_size:
    pd_unmapBAR (self->dev, BAR4NO, self->bar4);
err_bar4_alloc:
    pd_unmapBAR (self->dev, BAR2NO, self->bar2);
err_bar2_alloc:
    pd_unmapBAR (self->dev, BAR0NO, self->bar0);
err_bar0_alloc:
    pd_close (self->dev);
err_dev_pcie_open:
    free (self->dev);
err_dev_pcie_alloc:
    free (self);
err_llio_dev_pcie_alloc:
    return NULL;
}
Beispiel #2
0
/* Stops the framework by unmpaping the pcie BAR
 * Arguments: pdev - pcie device handler obtained from a successful call to open()
 * Returns: 0 on sucess, -1 otherwise
 */
int stopDMA(pd_device_t *pdev)
{ 
  if(pd_unmapBAR(pdev,0,bar)<0){
     PRINT("Error: Could not unmpap BAR0\n");
     return -1;
   }
 
  return 0;
}
Beispiel #3
0
/* Destroy an instance of the Endpoint */
static llio_err_e llio_dev_pcie_destroy (llio_dev_pcie_t **self_p)
{
    if (*self_p) {
        llio_dev_pcie_t *self = *self_p;

        /* Unmap all bars first and then destroy the remaining structures */
        pd_unmapBAR (self->dev, BAR4NO, self->bar4);
        pd_unmapBAR (self->dev, BAR2NO, self->bar2);
        pd_unmapBAR (self->dev, BAR0NO, self->bar0);
        pd_close (self->dev);

        free (self->dev);
        free (self);

        self_p = NULL;
    }

    return LLIO_SUCCESS;
}
Beispiel #4
0
void testDirectIO(pd_device_t *dev)
{
	int i,j,ret;
	unsigned long val,buf[MAX];
	unsigned long *bar0, *bar1;

	bar0 = pd_mapBAR( dev, 0 );
	bar1 = pd_mapBAR( dev, 1 );

	/* test register memory */
	bar0[0] = 0x1234565;
	bar0[1] = 0x5aa5c66c;

	for(i=0;i<MAX;i++) {
		val = bar0[i];
		printf("%08x\n",val);
	}		

	/* write block */
	for(i=0;i<MAX;i++) {
		buf[i] = ~i;
	}
	memcpy( (void*)bar0, (void*)buf, MAX*sizeof(unsigned int) );

	/* read block */
	memcpy( (void*)buf, (void*)bar0, MAX*sizeof(unsigned int) );
	for(i=0;i<MAX;i++) {
		val = buf[i];
		printf("%08x\n",val);
	}
	printf("\n\n");

	/* unmap BARs */
	pd_unmapBAR( dev,0, bar0 );
	pd_unmapBAR( dev,1, bar1 );
	
}
Beispiel #5
0
int main(int argc, char *argv[])
{
    int verbose = 0;
    char *devicefile_str = NULL;
    int rw_fpga = -1;
    char *barno_str = NULL;
    char *address_str = NULL;
    char *data_str = NULL;
    int opt;
    pd_device_t _dev = {0};
    pd_device_t *dev = &_dev;
    uint32_t *bar0 = NULL;
    uint32_t bar0_size;
    uint32_t *bar2 = NULL;
    uint32_t bar2_size;
    uint64_t *bar4 = NULL;
    uint32_t bar4_size;
	
    while ((opt = getopt_long (argc, argv, shortopt, long_options, NULL)) != -1) {
        /* Get the user selected options */
        switch (opt) {
            /* Display Help */
            case 'h':
                print_help (argv [0]);
                exit (1);
                break;

            case 'b':
                devicefile_str = strdup (optarg);
                break;

            case 'v':
                verbose = 1;
                break;

            case 'r':
                rw_fpga = 1;
                break;

            case 'w':
                rw_fpga = 0;
                break;

            case 'n':
                barno_str = strdup (optarg);
                break;

            case 'a':
                address_str = strdup (optarg);
                break;

            case 'd':
                data_str = strdup (optarg);
                break;
            
            case '?':
                fprintf (stderr, "Option not recognized or missing argument\n");
                print_help (argv [0]);
                exit (1);
                break;

            default:
                fprintf (stderr, "Could not parse options\n");
                print_help (argv [0]);
                exit (1);
        }
    }

    /* Device file is mandatory */
    if (devicefile_str == NULL) {
         fprintf (stderr, "--devicefile option not set!\n");
         print_help (argv [0]);
         goto exit;
    } 

    /* BAR number must be set */
    int barno = 0;
    if (barno_str == NULL) {
         fprintf (stderr, "--barno option not set!\n");
         print_help (argv [0]);
         goto exit;
    } 
    else {
        barno = strtoul (barno_str, NULL, 10);

        if (barno != 0 && barno != 2 && barno != 4) {
            fprintf (stderr, "Invalid option for BAR number!\n");
            print_help (argv [0]);
            goto exit;
        }
    }

    if (rw_fpga != 0 && rw_fpga != 1) {
       fprintf (stderr, "Neither --read or --write was set!\n");
       print_help (argv [0]);
       goto exit;
    }

    /* If read access, address must be set */
    if (rw_fpga == 1 && address_str == NULL) {
         fprintf (stderr, "--read_fpga is set but no --address!\n");
         print_help (argv [0]);
         goto exit;
    } 

    if (rw_fpga == 0 && (address_str == NULL || data_str == NULL)) {
         fprintf (stderr, "--write_fpga is set but either --address or --data not set!\n");
         print_help (argv [0]);
         goto exit;
    } 

    /* Parse data/address */
    uint64_t address = 0;
    if (address_str != NULL) {
        if (sscanf (address_str, "%"PRIx64, &address) != 1) {
             fprintf (stderr, "--address format is invalid!\n");
             print_help (argv [0]);
             goto exit;
        }
        if (verbose) {
            fprintf (stdout, "Address = 0x%08X\n", address);
        }
    } 

    uint32_t data = 0;
    if (data_str != NULL) {
        if (sscanf (data_str, "%"PRIx32, &data) != 1) {
             fprintf (stderr, "--data format is invalid!\n");
             print_help (argv [0]);
             goto exit;
        }
        if (verbose) {
            fprintf (stdout, "Data = 0x%08X\n", data);
        }
    }

    /* Open device */
    int err = pd_open (0, dev, devicefile_str);
    if (err != 0) {
         fprintf (stderr, "Could not open device %s, error = %d\n", devicefile_str, err);
         exit (1);
         goto exit;
    }

    /* Map BARs */
    bar0 = pd_mapBAR (dev, 0);
    if (bar0 == NULL) {
         fprintf (stderr, "Could not map BAR 0\n");
         exit (1);
         goto exit_close;
    }

    bar2 = pd_mapBAR (dev, 2);
    if (bar2 == NULL) {
         fprintf (stderr, "Could not map BAR 2\n");
         goto exit_unmap_bar0;
    }

    bar4 = pd_mapBAR (dev, 4);
    if (bar4 == NULL) {
         fprintf (stderr, "Could not map BAR 4\n");
         goto exit_unmap_bar2;
    }

    if (verbose) {
        fprintf (stdout, "BAR 0 host address = %p\n", bar0);
        fprintf (stdout, "BAR 2 host address = %p\n", bar2);
        fprintf (stdout, "BAR 4 host address = %p\n", bar4);
    }

    /* Get BAR sizes */
    bar0_size = pd_getBARsize (dev, 0);
    if (bar0_size == -1) {
         fprintf (stderr, "Could not get BAR 0 size\n");
         goto exit_unmap_bar4;
    }

    bar2_size = pd_getBARsize (dev, 2);
    if (bar2_size == -1) {
         fprintf (stderr, "Could not get BAR 2 size\n");
         goto exit_unmap_bar4;
    }

    bar4_size = pd_getBARsize (dev, 4);
    if (bar4_size == -1) {
         fprintf (stderr, "Could not get BAR 4 size\n");
         goto exit_unmap_bar4;
    }

    if (verbose) {
        fprintf (stdout, "BAR 0 size = %u bytes\n", bar0_size);
        fprintf (stdout, "BAR 2 size = %u bytes\n", bar2_size);
        fprintf (stdout, "BAR 4 size = %u bytes\n", bar4_size);
    }

    /* Read/Write to BAR */
    int pg_num = 0;
    uint64_t pg_offs = 0;
    switch (barno) {
        case 0:
            BAR0_RW(bar0, address, &data, rw_fpga);
            if (verbose) {
                fprintf (stdout, "%s from BAR0, data = 0x%08X, addr = 0x%08X\n", 
                    (rw_fpga)? "Reading":"Writing", data, address);
            }
            break;
        case 2:
            pg_num = PCIE_ADDR_SDRAM_PG (address);
            pg_offs = PCIE_ADDR_SDRAM_PG_OFFS (address);
            SET_SDRAM_PG (bar0, pg_num); 
            BAR2_RW(bar2, pg_offs, &data, rw_fpga);
            if (verbose) {
                fprintf (stdout, "%s from BAR2, data = 0x%08X, addr = 0x%08X, page = %d\n", 
                    (rw_fpga)? "Reading":"Writing", data, address, pg_num);
            }
            break;
        case 4:
            pg_num = PCIE_ADDR_WB_PG (address);
            pg_offs = PCIE_ADDR_WB_PG_OFFS (address);
            SET_WB_PG (bar0, pg_num);
            BAR4_RW(bar4, pg_offs, &data, rw_fpga);
            if (verbose) {
                fprintf (stdout, "%s from BAR4, data = 0x%08X, addr = 0x%08X, page = %d\n", 
                    (rw_fpga)? "Reading":"Writing", data, address, pg_num);
            }
            break;

        default:
            fprintf (stderr, "Invalid BAR number, %d\n", barno);
            goto exit_unmap_bar4;
    }

    /* Output Reading value only */
    if (rw_fpga) {
        fprintf (stdout, "0x%08X\n", data);
    }

exit_unmap_bar4:
    pd_unmapBAR (dev, 4, bar4);
exit_unmap_bar2:
    pd_unmapBAR (dev, 2, bar2);
exit_unmap_bar0:
    pd_unmapBAR (dev, 0, bar0);
exit_close:
    pd_close (dev);
exit:
    free (devicefile_str);
    free (barno_str);
    free (address_str);
    free (data_str);

    return 0;
}
Beispiel #6
0
void testDMA(pd_device_t *dev)
{
	int i,j,ret;
	unsigned int val;
	unsigned int *bar0, *bar1;
	pd_kmem_t km;
	unsigned int *ptr;
	bda_t dma;
	const unsigned long BASE_DMA_UP   = (0x0C000 >>2);
	const unsigned long BASE_DMA_DOWN = (0x0C040 >>2);	
	const unsigned long BRAM_SIZE = 0x1000;

	bar0 = pd_mapBAR( dev, 0 );
	bar1 = pd_mapBAR( dev, 1 );

	/* test register memory */
	bar0[0] = 0x1234565;
	bar0[1] = 0x5aa5c66c;

	ptr = (unsigned int*)pd_allocKernelMemory( dev, 32768, &km );
	if (ptr == NULL) {
		printf("failed\n");
		pd_unmapBAR( dev,0, bar0 );
		pd_unmapBAR( dev,1, bar1 );
		exit(-1);
	}


	/* Print kernel buffer info */
	printf("Kernel buffer physical address: %lx\n", km.pa);
	printf("Kernel buffer size: %lx\n", km.size);

	/* Reset the DMA channel */
	*(bar1+BASE_DMA_DOWN+0x5) = 0x0000000A;

	/* Fill buffer with zeros */
	memset( ptr, 0, BRAM_SIZE );

	/* Send a DMA transfer */
	dma.src_addr_h = 0x00000000;
	dma.src_addr_l = km.pa;
	dma.dst_addr_h = 0x00000000;
	dma.dst_addr_l = 0x00000000;
	dma.length = BRAM_SIZE;
	dma.control = 0x01000000;		
	dma.next_bda_h = 0x00000000;
	dma.next_bda_l = 0x00000000;

	write_dma(bar1+BASE_DMA_DOWN,&dma);	

	/* wait */
	sleep(5);

	for(i=0;i<BRAM_SIZE/4;i++) {
		val = bar0[i];
		printf("%08x\n",val);
	}		

	ret = pd_freeKernelMemory( &km );

	/* unmap BARs */
	pd_unmapBAR( dev,0,bar0 );
	pd_unmapBAR( dev,1,bar1 );
	
}