Skip to content
Snippets Groups Projects
Commit c9973e18 authored by Wesley W. Terpstra's avatar Wesley W. Terpstra
Browse files

Implement the mandatory Etherbone config space registers.

Currently hardcode SDWB address as hardware does not support it.
parent 5303eb90
Branches
Tags
No related merge requests found
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
static unsigned int debug = 0; static unsigned int debug = 0;
void wb_cycle(struct wishbone* wb, int on) static void wb_cycle(struct wishbone* wb, int on)
{ {
struct pcie_wb_dev* dev; struct pcie_wb_dev* dev;
unsigned char* control; unsigned char* control;
...@@ -44,7 +44,7 @@ void wb_cycle(struct wishbone* wb, int on) ...@@ -44,7 +44,7 @@ void wb_cycle(struct wishbone* wb, int on)
if (!on) mutex_unlock(&dev->mutex); if (!on) mutex_unlock(&dev->mutex);
} }
void wb_byteenable(struct wishbone* wb, unsigned char be) static void wb_byteenable(struct wishbone* wb, unsigned char be)
{ {
struct pcie_wb_dev* dev; struct pcie_wb_dev* dev;
...@@ -92,7 +92,7 @@ void wb_byteenable(struct wishbone* wb, unsigned char be) ...@@ -92,7 +92,7 @@ void wb_byteenable(struct wishbone* wb, unsigned char be)
} }
} }
void wb_write(struct wishbone* wb, wb_addr_t addr, wb_data_t data) static void wb_write(struct wishbone* wb, wb_addr_t addr, wb_data_t data)
{ {
struct pcie_wb_dev* dev; struct pcie_wb_dev* dev;
unsigned char* control; unsigned char* control;
...@@ -125,7 +125,7 @@ void wb_write(struct wishbone* wb, wb_addr_t addr, wb_data_t data) ...@@ -125,7 +125,7 @@ void wb_write(struct wishbone* wb, wb_addr_t addr, wb_data_t data)
} }
} }
wb_data_t wb_read(struct wishbone* wb, wb_addr_t addr) static wb_data_t wb_read(struct wishbone* wb, wb_addr_t addr)
{ {
struct pcie_wb_dev* dev; struct pcie_wb_dev* dev;
unsigned char* control; unsigned char* control;
...@@ -158,11 +158,31 @@ wb_data_t wb_read(struct wishbone* wb, wb_addr_t addr) ...@@ -158,11 +158,31 @@ wb_data_t wb_read(struct wishbone* wb, wb_addr_t addr)
return 0; return 0;
} }
static wb_data_t wb_read_cfg(struct wishbone *wb, wb_addr_t addr)
{
struct pcie_wb_dev* dev;
unsigned char* control;
dev = container_of(wb, struct pcie_wb_dev, wb);
control = dev->pci_res[0].addr;
rmb(); // has to be executed before reading
switch (addr) {
case 0: return ioread32(control + ERROR_FLAG_HIGH);
case 4: return ioread32(control + ERROR_FLAG_LOW);
case 8: return 0; // ioread32(control + SDWB_ADDRESS_HIGH);
case 12: return 0x300000; // ioread32(control + SDWB_ADDRESS_LOW);
default: return 0;
}
}
static const struct wishbone_operations wb_ops = { static const struct wishbone_operations wb_ops = {
.cycle = wb_cycle, .cycle = wb_cycle,
.byteenable = wb_byteenable, .byteenable = wb_byteenable,
.write = wb_write, .write = wb_write,
.read = wb_read, .read = wb_read,
.read_cfg = wb_read_cfg,
}; };
#if 0 #if 0
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#define ERROR_FLAG_LOW 12 #define ERROR_FLAG_LOW 12
#define WINDOW_OFFSET_HIGH 16 #define WINDOW_OFFSET_HIGH 16
#define WINDOW_OFFSET_LOW 20 #define WINDOW_OFFSET_LOW 20
#define SDWB_ADDRESS_HIGH 24
#define SDWB_ADDRESS_LOW 28
#define WINDOW_HIGH 0xFFFF0000UL #define WINDOW_HIGH 0xFFFF0000UL
#define WINDOW_LOW 0x0000FFFCUL #define WINDOW_LOW 0x0000FFFCUL
......
...@@ -102,18 +102,26 @@ static void etherbone_process(struct etherbone_context* context) ...@@ -102,18 +102,26 @@ static void etherbone_process(struct etherbone_context* context)
wb_addr_t base_address; wb_addr_t base_address;
unsigned char j; unsigned char j;
int wff = flags & ETHERBONE_WFF; int wff = flags & ETHERBONE_WFF;
int wca = flags & ETHERBONE_WCA;
/* Erase the header */ /* Erase the header */
eb_from_cpu(buf+i, 0); eb_from_cpu(buf+i, 0);
i = RING_INDEX(i + sizeof(wb_data_t)); i = RING_INDEX(i + sizeof(wb_data_t));
base_address = eb_to_cpu(buf+i); base_address = eb_to_cpu(buf+i);
for (j = wcount; j > 0; --j) { if (wca) {
eb_from_cpu(buf+i, 0); for (j = wcount; j > 0; --j) {
i = RING_INDEX(i + sizeof(wb_data_t)); eb_from_cpu(buf+i, 0);
wops->write(wb, base_address, eb_to_cpu(buf+i)); i = RING_INDEX(i + sizeof(wb_data_t));
}
if (!wff) base_address += sizeof(wb_data_t); } else {
for (j = wcount; j > 0; --j) {
eb_from_cpu(buf+i, 0);
i = RING_INDEX(i + sizeof(wb_data_t));
wops->write(wb, base_address, eb_to_cpu(buf+i));
if (!wff) base_address += sizeof(wb_data_t);
}
} }
} }
...@@ -126,13 +134,21 @@ static void etherbone_process(struct etherbone_context* context) ...@@ -126,13 +134,21 @@ static void etherbone_process(struct etherbone_context* context)
if (rcount > 0) { if (rcount > 0) {
unsigned char j; unsigned char j;
int rca = flags & ETHERBONE_RCA;
/* Move past header, and leave BaseRetAddr intact */ /* Move past header, and leave BaseRetAddr intact */
i = RING_INDEX(i + sizeof(wb_data_t) + sizeof(wb_data_t)); i = RING_INDEX(i + sizeof(wb_data_t) + sizeof(wb_data_t));
for (j = rcount; j > 0; --j) { if (rca) {
eb_from_cpu(buf+i, wops->read(wb, eb_to_cpu(buf+i))); for (j = rcount; j > 0; --j) {
i = RING_INDEX(i + sizeof(wb_data_t)); eb_from_cpu(buf+i, wops->read_cfg(wb, eb_to_cpu(buf+i)));
i = RING_INDEX(i + sizeof(wb_data_t));
}
} else {
for (j = rcount; j > 0; --j) {
eb_from_cpu(buf+i, wops->read(wb, eb_to_cpu(buf+i)));
i = RING_INDEX(i + sizeof(wb_data_t));
}
} }
} }
......
...@@ -26,6 +26,7 @@ struct wishbone_operations ...@@ -26,6 +26,7 @@ struct wishbone_operations
void (*byteenable)(struct wishbone* wb, unsigned char mask); void (*byteenable)(struct wishbone* wb, unsigned char mask);
void (*write)(struct wishbone* wb, wb_addr_t addr, wb_data_t); void (*write)(struct wishbone* wb, wb_addr_t addr, wb_data_t);
wb_data_t (*read)(struct wishbone* wb, wb_addr_t addr); wb_data_t (*read)(struct wishbone* wb, wb_addr_t addr);
wb_data_t (*read_cfg)(struct wishbone* wb, wb_addr_t addr);
}; };
/* One per wishbone backend hardware */ /* One per wishbone backend hardware */
......
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