Commit 81e2a8e2 authored by Manohar Vanga's avatar Manohar Vanga

simulation: multiple fixes

Fix bugs in release method of device 0.
Change ops to additionally provide bus as argument.
Fix endian issues in bus scanning
Signed-off-by: 's avatarManohar Vanga <manohar.vanga@cern.ch>
parent 0f81a893
# Trivial top-level Makefile
LINUX ?= $(HOME)/linux-for-wbonesim
#LINUX ?= $(HOME)/linux-for-wbonesim
CPU?=L865
KVER?=2.6.24.7-rt27
LINUX?=/acc/sys/$(CPU)/usr/src/kernels/$(KVER)
# temporarily, use local <linux/wishbone.h>
EXTRA_CFLAGS := -I$(obj)/include
......
......@@ -20,6 +20,7 @@
* 02110-1301, USA.
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
......@@ -39,7 +40,7 @@ const struct firmware *wb_fw;
LIST_HEAD(spec_devices);
static struct mutex list_lock;
void *fake_read_cfg(wb_addr_t addr, void *buf, size_t len)
void *fake_read_cfg(struct wb_bus *bus, wb_addr_t addr, void *buf, size_t len)
{
if (wb_fw->size < addr + len)
return NULL;
......@@ -94,7 +95,11 @@ static void fake_wbbus_release(struct device *dev)
}
static struct device fake_wbbus_device = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
.bus_id = "fake-wbbus0",
#else
.init_name = "fake-wbbus0",
#endif
.release = fake_wbbus_release,
};
......
......@@ -35,24 +35,24 @@
#define WB_NO_CLASS ((uint32_t)(~0))
/* Wishbone I/O operations */
#define wb_readb(bus, addr) bus->ops->read8(addr)
#define wb_readw(bus, addr) bus->ops->read16(addr)
#define wb_readl(bus, addr) bus->ops->read32(addr)
#define wb_readll(bus, addr) bus->ops->read64(addr)
#define wb_readb(bus, addr) bus->ops->read8(bus, addr)
#define wb_readw(bus, addr) bus->ops->read16(bus, addr)
#define wb_readl(bus, addr) bus->ops->read32(bus, addr)
#define wb_readll(bus, addr) bus->ops->read64(bus, addr)
#define wb_writeb(bus, addr, val) bus->ops->write8(addr, val)
#define wb_writew(bus, addr, val) bus->ops->write16(addr, val)
#define wb_writel(bus, addr, val) bus->ops->write32(addr, val)
#define wb_writell(bus, addr, val) bus->ops->write64(addr, val)
#define wb_writeb(bus, addr, val) bus->ops->write8(bus, addr, val)
#define wb_writew(bus, addr, val) bus->ops->write16(bus, addr, val)
#define wb_writel(bus, addr, val) bus->ops->write32(bus, addr, val)
#define wb_writell(bus, addr, val) bus->ops->write64(bus, addr, val)
#define memcpy_from_wb(bus, addr, buf, len) \
bus->ops->memcpy_from_wb(addr, buf, len)
bus->ops->memcpy_from_wb(bus, addr, buf, len)
#define memcpy_to_wb(bus, addr, buf, len) \
bus->ops->memcpy_to_wb(addr, buf, len)
bus->ops->memcpy_to_wb(bus, addr, buf, len)
#define wb_read_cfg(bus, addr, buf, len) \
bus->ops->read_cfg(addr, buf, len)
bus->ops->read_cfg(bus, addr, buf, len)
typedef uint64_t wb_addr_t;
......@@ -103,17 +103,20 @@ struct wb_device {
#define to_wb_device(dev) container_of(dev, struct wb_device, dev);
struct wb_ops {
uint8_t (*read8)(wb_addr_t);
uint16_t (*read16)(wb_addr_t);
uint32_t (*read32)(wb_addr_t);
uint64_t (*read64)(wb_addr_t);
void (*write8)(wb_addr_t, uint8_t);
void (*write16)(wb_addr_t, uint16_t);
void (*write32)(wb_addr_t, uint32_t);
void (*write64)(wb_addr_t, uint64_t);
void * (*memcpy_from_wb) (wb_addr_t addr, void *buf, size_t len);
void * (*memcpy_to_wb) (wb_addr_t addr, const void *buf, size_t len);
void * (*read_cfg)(wb_addr_t addr, void *buf, size_t len);
uint8_t (*read8)(struct wb_bus *, wb_addr_t);
uint16_t (*read16)(struct wb_bus *, wb_addr_t);
uint32_t (*read32)(struct wb_bus *, wb_addr_t);
uint64_t (*read64)(struct wb_bus *, wb_addr_t);
void (*write8)(struct wb_bus *, wb_addr_t, uint8_t);
void (*write16)(struct wb_bus *, wb_addr_t, uint16_t);
void (*write32)(struct wb_bus *, wb_addr_t, uint32_t);
void (*write64)(struct wb_bus *, wb_addr_t, uint64_t);
void * (*memcpy_from_wb) (struct wb_bus *, wb_addr_t addr, void *buf,
size_t len);
void * (*memcpy_to_wb) (struct wb_bus *, wb_addr_t addr,
const void *buf, size_t len);
void * (*read_cfg)(struct wb_bus *, wb_addr_t addr, void *buf,
size_t len);
};
struct wb_bus {
......
......@@ -36,9 +36,17 @@ static int wb_bus_match(struct device *, struct device_driver *);
static int wb_drv_probe(struct device *);
static int wb_drv_remove(struct device *);
static void wb_zero_release(struct device *dev)
{
}
static struct device wb_dev_zero = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
.bus_id = "wb0",
#else
.init_name = "wb0",
.release = wb_dev_release,
#endif
.release = wb_zero_release,
};
static struct bus_type wb_bus_type = {
......@@ -79,8 +87,13 @@ int wb_register_device(struct wb_device *wbdev)
wbdev->dev.bus = &wb_bus_type;
wbdev->dev.parent = &wbdev->bus->dev;
wbdev->dev.release = wb_dev_release;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
snprintf(wbdev->dev.bus_id, BUS_ID_SIZE, "wb%d-%s-%s", devno,
wbdev->wbd.vendor_name, wbdev->wbd.device_name);
#else
dev_set_name(&wbdev->dev, "wb%d-%s-%s", devno, wbdev->wbd.vendor_name,
wbdev->wbd.device_name);
#endif
INIT_LIST_HEAD(&wbdev->list);
return device_register(&wbdev->dev);
......@@ -132,6 +145,9 @@ static struct wb_device *wb_get_next_device(struct wb_bus *bus, wb_addr_t wb_ptr
if (wbd.wbd_magic != SDWB_WBD_MAGIC)
return NULL;
wbd.hdl_base = be64_to_cpu(wbd.hdl_base);
wbd.hdl_size = be64_to_cpu(wbd.hdl_size);
wbdev = kzalloc(sizeof(struct wb_device), GFP_KERNEL);
if (!wbdev)
return NULL;
......@@ -142,6 +158,25 @@ static struct wb_device *wb_get_next_device(struct wb_bus *bus, wb_addr_t wb_ptr
return wbdev;
}
void wb_read_sdwb_header(struct wb_bus *bus, struct sdwb_head *head)
{
wb_read_cfg(bus, bus->sdwb_header_base, (void *)head,
sizeof(struct sdwb_head));
head->wbid_address = be64_to_cpu(head->wbid_address);
head->wbd_address = be64_to_cpu(head->wbd_address);
}
void wb_read_sdwb_id(struct wb_bus *bus, struct sdwb_head *head,
struct sdwb_wbid *wbid)
{
wb_read_cfg(bus, head->wbid_address, (void *)wbid,
sizeof(struct sdwb_wbid));
wbid->bstream_type = be64_to_cpu(wbid->bstream_type);
wbid->bstream_version = be64_to_cpu(wbid->bstream_version);
wbid->bstream_date = be64_to_cpu(wbid->bstream_date);
}
int wb_scan_bus(struct wb_bus *bus)
{
int ret;
......@@ -151,8 +186,7 @@ int wb_scan_bus(struct wb_bus *bus)
struct wb_device *wbdev;
struct wb_device *next;
wb_read_cfg(bus, bus->sdwb_header_base, (void *)&head,
sizeof(struct sdwb_head));
wb_read_sdwb_header(bus, &head);
/* verify our header using the magic field */
if (head.magic != SDWB_HEAD_MAGIC) {
......@@ -161,9 +195,8 @@ int wb_scan_bus(struct wb_bus *bus)
return -ENODEV;
}
wb_read_cfg(bus, head.wbid_address, (void *)&wbid,
sizeof(struct sdwb_wbid));
pr_info(KBUILD_MODNAME ": found sdwb bistream: 0x%llx\n",
wb_read_sdwb_id(bus, &head, &wbid);
pr_info(KBUILD_MODNAME ": found sdwb bitstream: 0x%llx\n",
wbid.bstream_type);
wbd_ptr = head.wbd_address;
......@@ -191,7 +224,6 @@ err_wbdev_register:
list_for_each_entry_safe(wbdev, next, &bus->devices, list) {
list_del(&wbdev->list);
wb_unregister_device(wbdev);
kfree(wbdev);
}
bus->ndev = 0;
......@@ -215,7 +247,12 @@ int wb_register_bus(struct wb_bus *bus)
bus->dev.bus = &wb_bus_type;
bus->dev.parent = &wb_dev_zero;
bus->dev.release = wb_bus_release;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
snprintf(bus->dev.bus_id, BUS_ID_SIZE, "wb-bus%d-%s", devno,
bus->name);
#else
dev_set_name(&bus->dev, "wb-bus%d-%s", devno, bus->name);
#endif
if (device_register(&bus->dev) < 0) {
pr_err(KBUILD_MODNAME ": failed to register bus device %d\n",
......@@ -243,9 +280,8 @@ void wb_unregister_bus(struct wb_bus *bus)
struct wb_device *next;
list_for_each_entry_safe(wbdev, next, &bus->devices, list) {
list_del(&wbdev->list);
wb_unregister_device(wbdev);
kfree(wbdev);
list_del(&wbdev->list);
}
device_unregister(&bus->dev);
}
......
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