Commit b9a11b52 authored by Lucas Russo's avatar Lucas Russo

hal/ll_io/ops/ll_io_pcie.c: add read/write block functions

parent 2739301b
......@@ -35,6 +35,12 @@
#define WRITE_TO_BAR 0
static ssize_t _pcie_rw_32 (llio_t *self, loff_t offs, uint32_t *data, int rw);
static ssize_t _pcie_rw_bar2_block_raw (llio_t *self, uint32_t pg_start, loff_t pg_offs,
uint32_t *data, uint32_t size, int rw);
static ssize_t _pcie_rw_bar4_block_raw (llio_t *self, uint32_t pg_start, loff_t pg_offs,
uint32_t *data, uint32_t size, int rw);
static ssize_t _pcie_rw_block (llio_t *self, loff_t offs, size_t size,
uint32_t *data, int rw);
/************ Our methods implementation **********/
......@@ -203,21 +209,14 @@ ssize_t pcie_write_64 (llio_t *self, loff_t offs, const uint64_t *data)
/* Read data block from PCIe device, size in bytes */
ssize_t pcie_read_block (llio_t *self, loff_t offs, size_t size, uint32_t *data)
{
(void) self;
(void) offs;
(void) size;
(void) data;
return -1;
return _pcie_rw_block (self, offs, size, data, READ_FROM_BAR);
}
/* Write data block from PCIe device, size in bytes */
ssize_t pcie_write_block (llio_t *self, loff_t offs, size_t size, const uint32_t *data)
ssize_t pcie_write_block (llio_t *self, loff_t offs, size_t size, uint32_t *data)
{
(void) self;
(void) offs;
(void) size;
(void) data;
return -1;
/* _pcie_rw_block with WRITE_TO_BAR does not modify "data" */
return _pcie_rw_block (self, offs, size, data, WRITE_TO_BAR);
}
/* Read data block from PCIe device, size in bytes */
......@@ -231,7 +230,7 @@ ssize_t pcie_read_dma (llio_t *self, loff_t offs, size_t size, uint32_t *data)
}
/* Write data block from PCIe device, size in bytes */
ssize_t pcie_write_dma (llio_t *self, loff_t offs, size_t size, const uint32_t *data)
ssize_t pcie_write_dma (llio_t *self, loff_t offs, size_t size, uint32_t *data)
{
(void) self;
(void) offs;
......@@ -312,6 +311,119 @@ static ssize_t _pcie_rw_32 (llio_t *self, loff_t offs, uint32_t *data, int rw)
return sizeof (*data);
}
static ssize_t _pcie_rw_bar2_block_raw (llio_t *self, uint32_t pg_start, loff_t pg_offs,
uint32_t *data, uint32_t size, int rw)
{
uint32_t offs = pg_offs;
uint32_t num_bytes_rem = size;
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_bar2_block_raw] pg_start = %u, pg_end = %lu...\n",
pg_start, pg_start + (pg_offs+size)/PCIE_SDRAM_PG_SIZE + 1);
for (unsigned int pg = pg_start;
pg < (pg_start + (pg_offs+size)/PCIE_SDRAM_PG_SIZE + 1);
++pg) {
SET_SDRAM_PG (pg);
uint32_t num_bytes_page = (num_bytes_rem > PCIE_SDRAM_PG_SIZE) ?
(PCIE_SDRAM_PG_SIZE-offs) : (num_bytes_rem);
num_bytes_rem -= num_bytes_page;
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_bar2_block_raw] Reading %u bytes from addr: %p\n",
num_bytes_page, BAR2);
BAR2_RW_BLOCK(BAR2, offs, num_bytes_page,
(uint32_t *)((uint8_t *)data + (pg-pg_start)*PCIE_SDRAM_PG_SIZE), rw);
/* Always 0 after the first page */
offs = 0;
}
return size /*- num_bytes_rem*/;
}
static ssize_t _pcie_rw_bar4_block_raw (llio_t *self, uint32_t pg_start, loff_t pg_offs,
uint32_t *data, uint32_t size, int rw)
{
uint32_t offs = pg_offs;
uint32_t num_bytes_rem = size;
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_bar4_block_raw] pg_start = %u, pg_end = %lu...\n",
pg_start, pg_start + (pg_offs+size)/PCIE_WB_PG_SIZE + 1);
for (unsigned int pg = pg_start;
pg < pg_start + (pg_offs+size)/PCIE_WB_PG_SIZE + 1;
++pg) {
SET_WB_PG (pg);
uint32_t num_bytes_page = (num_bytes_rem > PCIE_WB_PG_SIZE) ?
(PCIE_WB_PG_SIZE-offs) : (num_bytes_rem);
num_bytes_rem -= num_bytes_page;
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_bar4_block_raw] Reading %u bytes from addr: %p\n",
num_bytes_page, BAR4);
BAR4_RW_BLOCK(BAR4, offs, num_bytes_page,
(uint32_t *)((uint8_t *)data + (pg-pg_start)*PCIE_WB_PG_SIZE), rw);
/* Always 0 after the first page */
offs = 0;
}
return size /*- num_bytes_rem*/;
}
static ssize_t _pcie_rw_block (llio_t *self, loff_t offs, size_t size, uint32_t *data, int rw)
{
if (!self->endpoint->opened) {
return -1;
}
/* Determine which bar to operate on */
int bar_no = PCIE_ADDR_BAR (offs);
loff_t full_offs = PCIE_ADDR_GEN (offs);
int pg_start;
loff_t pg_offs;
ssize_t ret_size = -1;
switch (bar_no) {
/* PCIe config registers */
case BAR0NO:
/* Not available */
break;
/* FPGA SDRAM */
case BAR2NO:
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_block] Going to read/write in BAR2\n");
pg_start = PCIE_ADDR_SDRAM_PG (full_offs);
pg_offs = PCIE_ADDR_SDRAM_PG_OFFS (full_offs);
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_block] bar_no = %d, pg_start = %d,\n\tfull_offs = 0x%lx, pg_offs = 0x%lx\n",
bar_no, pg_start, full_offs, pg_offs);
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_block] full_addr = 0x%p\n", ((llio_dev_pcie_t *) self->dev_handler)->bar2 + pg_offs);
ret_size = _pcie_rw_bar2_block_raw (self, pg_start, pg_offs, data, size, rw);
break;
/* FPGA Wishbone */
case BAR4NO:
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_block] Going to read/write in BAR4\n");
pg_start = PCIE_ADDR_WB_PG (full_offs);
pg_offs = PCIE_ADDR_WB_PG_OFFS (full_offs);
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_block] bar_no = %d, pg_start = %d,\n\tfull_offs = 0x%lx, pg_offs = 0x%lx\n",
bar_no, pg_start, full_offs, pg_offs);
DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE,
"[ll_io_pcie:_pcie_rw_block] full_addr = %p\n", ((llio_dev_pcie_t *) self->dev_handler)->bar4 + pg_offs);
ret_size = _pcie_rw_bar4_block_raw (self, pg_start, pg_offs, data, size, rw);
break;
/* Invalid BAR */
default:
break;
}
return ret_size;
}
const llio_ops_t llio_ops_pcie = {
.open = pcie_open, /* Open device */
.release = pcie_release, /* Release device */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment