diff --git a/server/include/gtfpga.h b/server/include/gtfpga.h index b449d5f60..d1cc54378 100644 --- a/server/include/gtfpga.h +++ b/server/include/gtfpga.h @@ -9,8 +9,33 @@ #ifndef _GTFPGA_H_ #define _GTFPGA_H_ -struct gtfpga { +#include +#define GTFPGA_BAR 0 + +#define GTFPGA_MAX_TX 64 +#define GTFPGA_MAX_RX 64 + +#define GTFPGA_VID 0x10ee +#define GTFPGA_DID 0x0007 + +struct gtfpga { + struct pci_filter filter; + + int fd_mmap, fd_uio; + void *map; + + struct pci_access *pacc; + struct pci_dev *dev; }; + +int gtfpga_open(struct node *n); + +int gtfpga_close(struct node *n); + +int gtfpga_read(struct node *n, struct msg *m); + +int gtfpga_write(struct node *n, struct msg *m); + #endif /* _GTFPGA_H_ */ diff --git a/server/src/cfg.c b/server/src/cfg.c index 6a3cf53ba..9502d51ef 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -282,9 +282,11 @@ int config_parse_opal(config_setting_t *cfg, struct node *n) rfound += og->send_ids[i] == o->send_id; if (!sfound) - cerror(config_setting_get_member(cfg, "send_id"), "Invalid send_id '%u' for node '%s'", o->send_id, n->name); + cerror(config_setting_get_member(cfg, "send_id"), + "Invalid send_id '%u' for node '%s'", o->send_id, n->name); if (!rfound) - cerror(config_setting_get_member(cfg, "recv_id"), "Invalid recv_id '%u' for node '%s'", o->recv_id, n->name); + cerror(config_setting_get_member(cfg, "recv_id"), + "Invalid recv_id '%u' for node '%s'", o->recv_id, n->name); n->opal = o; n->opal->global = og; @@ -299,6 +301,31 @@ int config_parse_opal(config_setting_t *cfg, struct node *n) /** @todo Implement */ int config_parse_gtfpga(config_setting_t *cfg, struct node *n) { + char *slot, *id; + config_setting_t *cfg_slot, *cfg_id; + struct gtfpga *g = alloc(sizeof(struct gtfpga)); + + pci_filter_init(NULL, &g->filter); + + if (cfg_slot = config_setting_get_member(cfg, "slot")) { + if (slot = config_setting_get_string(cfg_slot)) { + if ((err = pci_filter_parse_slot(&g->filter, slot)) + cerror(cfg_slot, "%s", err); + } + else + cerror(cfg_slot, "Invalid slot format"); + } + + if (cfg_id = config_setting_get_member(cfg, "id")) { + if (id = config_setting_get_string(cfg_id)) { + if ((err = pci_filter_parse_id(&g->filter, id)) + cerror(cfg_id, "%s", err); + } + else + cerror(cfg_slot, "Invalid id format"); + } + + return 0; } #endif /* ENABLE_GTFPGA */ diff --git a/server/src/gtfpga.c b/server/src/gtfpga.c index 1c911e730..314f6d2c3 100644 --- a/server/src/gtfpga.c +++ b/server/src/gtfpga.c @@ -7,3 +7,108 @@ */ #include "gtfpga.h" + +#define SYSFS_PATH "/sys/bus/pci" + +static int gtfpga_load_driver(struct node *n) +{ + +} + +static struct pci_dev * gtfpga_find_device(struct node *n) +{ + struct gtfpga *g = n->gtfpga; + + struct pci_dev *dev; + + pacc = pci_alloc(); /* Get the pci_access structure */ + + pci_init(pacc); /* Initialize the PCI library */ + pci_scan_bus(pacc); /* We want to get the list of devices */ + + /* Iterate over all devices */ + for (dev = pacc->devices; dev; dev = dev->next) { + if (pci_filter_match(&filter, dev)) + return dev; + } + + return NULL; +} + +static int gtfpga_mmap(struct node *n) +{ + struct gtfpga *g = n->gtfpga; + + int fd = open("/dev/mem", O_RDWR | O_SYNC); + if (!fd) + serror("Failed open()"); + + long int addr = g->dev->base_addr[GTFPGA_BAR] & ~0xfff; + int size = g->dev->size[GTFPGA_BAR]; + + /* mmap() first BAR */ + printf("mmap(NULL, %#x, PROT_READ | PROT_WRITE, MAP_SHARED, %u, %#lx)", size, fd, addr); + void *map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr); + if (map == MAP_FAILED) + serror("Failed mmap()"); +} + +int gtfpga_open(struct node *n) +{ + struct gtfpga *g = n->gtfpga; + struct pci_dev *dev; + + int ret; + + dev = gtfpga_find_device(g->filter); + if (!dev) + error("No GTFPGA card detected"); + + g->dev = dev; + + ret = gtfpga_load_driver(dev); + if (ret) + error("Failed to load and bind driver (uio_pci_generic)"); + + ret = gtfpga_mmap(g); + if (ret) + error("Failed to setup memory mapping for GTFGPA card"); + + /* Show some debug infos */ + pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); /* Fill in header info we need */ + + debug(3, "Found GTFPGA card: %04x:%02x:%02x.%d vendor=%04x device=%04x class=%04x irq=%d", + dev->domain, dev->bus, dev->dev, dev->func, dev->vendor_id, dev->device_id, + dev->device_class, dev->irq); + + debug(3, " (%s)\n", pci_lookup_name(pacc, namebuf, sizeof(namebuf), PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id)); + + return 0; +} + +int gtfpga_close(struct node *n) +{ + struct gtfpga *g = n->gtfpga; + + munmap(g->map, g->dev->size[GTFPGA_BAR]); + + close(g->fd_mmap); + close(g->fd_uio); + + return 0; +} + +int gtfpga_read(struct node *n, struct msg *m) +{ + struct gtfpga *g = n->gtfpga; + + return 0; +} + +int gtfpga_write(struct node *n, struct msg *m) +{ + struct gtfpga *g = n->gtfpga; + + return 0; +} +