[PATCH 1/3] FPGA: add a simple programming handler framework
Juergen Beisert
jbe at pengutronix.de
Wed Nov 6 09:24:39 EST 2013
This framework handles a list of registered FPGA programming handlers
to unify a firmware programming interface by hiding the details how
to program a specific FPGA in its handler.
Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
common/Kconfig | 3 ++
common/Makefile | 1 +
common/fpgamgr.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/fpgamgr.h | 58 ++++++++++++++++++++++++++
4 files changed, 184 insertions(+)
create mode 100644 common/fpgamgr.c
create mode 100644 include/fpgamgr.h
diff --git a/common/Kconfig b/common/Kconfig
index ccfbc80..d87e59b 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -297,6 +297,9 @@ config MAXARGS
prompt "max. Number of arguments accepted for monitor commands"
default 16
+config FPGAMANAGER
+ bool
+
choice
prompt "Select your shell"
diff --git a/common/Makefile b/common/Makefile
index 6f6e360..537dea4 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -48,6 +48,7 @@ obj-y += bootsource.o
obj-$(CONFIG_BOOTM) += bootm.o
extra-$(CONFIG_MODULES) += module.lds
extra-y += barebox_default_env barebox_default_env.h
+obj-$(CONFIG_FPGAMANAGER) += fpgamgr.o
ifdef CONFIG_DEFAULT_ENVIRONMENT
$(obj)/startup.o: $(obj)/barebox_default_env.h
diff --git a/common/fpgamgr.c b/common/fpgamgr.c
new file mode 100644
index 0000000..4e36330
--- /dev/null
+++ b/common/fpgamgr.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013 Juergen Beisert <kernel at pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <fpgamgr.h>
+#include <linux/list.h>
+#include <xfuncs.h>
+#include <malloc.h>
+
+struct fpga_mgr {
+ struct list_head list;
+ struct fpga_handler *handler; /* the program handler */
+ unsigned index;
+ unsigned flags;
+};
+
+static LIST_HEAD(fpgamgr_prog_handlers);
+
+static struct fpga_mgr *fpgamgr_init(void)
+{
+ struct fpga_mgr *handler;
+
+ handler = xzalloc(sizeof(struct fpga_mgr));
+ return handler;
+}
+
+struct fpga_mgr *fpgamgr_find_handler(const char *name, int index)
+{
+ struct fpga_mgr *mgr;
+
+ if (!name)
+ return -EINVAL;
+
+ list_for_each_entry(mgr, &fpgamgr_prog_handlers, list) {
+ if (!strcmp(mgr->handler->name, name)) {
+ if (index == -1 || index == mgr->index)
+ return mgr;
+ }
+ }
+
+ return NULL;
+}
+
+void fpgamgr_handlers_list(void)
+{
+ struct fpga_mgr *mgr;
+
+ if (list_empty(&fpgamgr_prog_handlers))
+ printf("(none)\n");
+
+ list_for_each_entry(mgr, &fpgamgr_prog_handlers, list)
+ printf("%s%-11s idx %u\n",
+ mgr->flags & FPGAMGR_HANDLER_FLAG_DEFAULT ?
+ "* " : " ", mgr->handler->name, mgr->index);
+}
+
+/* make the device accessible to the public via its handler */
+int fpgamgr_register_handler(struct fpga_handler *h)
+{
+ struct fpga_mgr *mgr;
+ int index = 0;
+
+ if (fpgamgr_find_handler(h->name, -1) != 0) {
+ /* find the next free index for this name */
+ do
+ index++;
+ while (fpgamgr_find_handler(h->name, index) != NULL);
+ }
+
+ mgr = fpgamgr_init();
+ mgr->handler = h;
+ mgr->index = index;
+
+ list_add_tail(&mgr->list, &fpgamgr_prog_handlers);
+
+ return 0;
+}
+
+int fpgamgr_open_fpga(struct fpga_mgr *m)
+{
+ struct fpga_handler *h = m->handler;
+
+ if (h->open)
+ return h->open(h);
+
+ return -ENOSYS;
+}
+
+/*
+ * Expectation is 'cnt' in bytes and it *must* be a multiple of 8 bytes.
+ * Only the last call prior calling fpgamgr_close_fpga() can violate
+ * this rule.
+ */
+int fpgamgr_prog_fpga(struct fpga_mgr *m, const void *data, size_t cnt)
+{
+ struct fpga_handler *h = m->handler;
+
+ if (h->write)
+ return h->write(h, data, cnt);
+
+ return -ENOSYS;
+}
+
+int fpgamgr_close_fpga(struct fpga_mgr *m)
+{
+ struct fpga_handler *h = m->handler;
+
+ if (h->close)
+ return h->close(h);
+
+ return -ENOSYS;
+}
diff --git a/include/fpgamgr.h b/include/fpgamgr.h
new file mode 100644
index 0000000..8f94998
--- /dev/null
+++ b/include/fpgamgr.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013 Juergen Beisert <kernel at pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <types.h>
+
+struct fpga_handler {
+ const char *name; /* the name of the FPGA */
+ void *private_data; /* handler's private data */
+ /* called once to prepare the FPGA's programming cycle */
+ int (*open)(struct fpga_handler*);
+ /* called multiple times to program the FPGA with the given data */
+ int (*write)(struct fpga_handler*, const void*, size_t);
+ /* called once to finish programming cycle */
+ int (*close)(struct fpga_handler*);
+};
+
+struct fpga_mgr;
+
+int fpgamgr_register_handler(struct fpga_handler *);
+
+/* second argument can be -1 to be ignored */
+struct fpga_mgr *fpgamgr_find_handler(const char *, int);
+
+/*
+ * returns:
+ * 0 success
+ * -EIO preparing the FPGA for programming has failed
+ * -ENOSYS no such function available
+ */
+int fpgamgr_open_fpga(struct fpga_mgr *);
+
+/*
+ * returns:
+ * 0 success
+ * -EIO programming the FPGA has failed
+ * -ENOSYS no such function available
+ */
+int fpgamgr_prog_fpga(struct fpga_mgr *, const void *, size_t);
+
+/*
+ * returns:
+ * 0 success
+ * -EIO program cycle hasn't finished successfully
+ * -ENOSYS no such function available
+ */
+int fpgamgr_close_fpga(struct fpga_mgr *);
+
+void fpgamgr_handlers_list(void);
--
1.8.4.rc3
More information about the barebox
mailing list