Open source FPGA image header
Subsystems (2)
cover Open source FPGA image header
This patch set adds open source FPGA image headers. This allows FPGA FPGA image specific information to be added to the images themselves. The header format is a simplified form of u-boot FIT images and can be expanded as real use cases are raised. As all the FPGA kernel frameworks are intended to be vendor agnostic, so also is the header. As libfdt's licensing is permissive, this header is also intended to be useful for OS's other than Linux.
In February, there was a conversation on the linux-fpga mailing list where Moritz and Jason suggested headers, so with their permission I'll be happy to add 'Suggested-by'.
An API function and a sysfs interface are added for applying FPGA images to regions.
Patches 1-2 are documentation
Patches 3-4 are small API changes and could be rolled into my "non-DT
support for FPGA regions" patchset.
Patch 5 is the bulk of it.
todo: I've been working on scatter gather table support for this. It's not done yet, so I pulled it out for now.
This patch applies on top of my "non-DT support for FPGA regions" v3 patchset.
Alan Tull
Alan Tull (5):
doc: fpga: add document for the fdt FPGA header
doc: fpga: add sysfs document for fpga region
fpga: add dev to fpga_image_info
fpga-region: new function fpga_region_free fpga-region support for fdt headers on fpga images
Documentation/ABI/testing/sysfs-class-fpga-region | 7 + Documentation/fpga/fpga-header.txt | 103 +++++ drivers/fpga/Kconfig | 7 + drivers/fpga/fpga-mgr.c | 14 +- drivers/fpga/fpga-region.c | 460 ++++++++++++++++++++++ drivers/fpga/of-fpga-region.c | 16 +- include/linux/fpga/fpga-mgr.h | 13 +- include/linux/fpga/fpga-region.h | 3 + 8 files changed, 612 insertions(+), 11 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-region create mode 100644 Documentation/fpga/fpga-header.txt
Signature · 1 line
2.7.4
RFC 1/5 doc: fpga: add document for the fdt FPGA header
Add a document for the open source fdt FPGA header.
--- Documentation/fpga/fpga-header.txt | 103 +++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 Documentation/fpga/fpga-header.txt
Documentation/fpga/fpga-header.txt new file +103 -0
@@ -0,0 +1,103 @@ +Open source FPGA image headers + +Alan Tull 2017 + +CONTENTS +- Introduction +- Format +- Example +- Using mkimage + +Introduction +============ + +Open source FPGA image headers have been added to allow FPGA image specific +information to be included with the image. The header format is a simplified +form of u-boot FIT images and can be expanded as real use cases are raised. +As all the FPGA kernel frameworks are intended to be vendor agnostic, so also +is the header. As libfdt's licensing is permissive, this header is also +intended to be useful for OS's other than Linux such that the FPGA image need +not be rebuilt for use under another OS. + +Format +====== + +The format of the header is a reduced FIT-like header, so it can be built +using mkimage. The header is a FDT followed by two optional binary data +sections: a Device Tree overlay and a raw FPGA image. When the image is +applied to a FPGA region, first the FPGA is programmed (if the raw image is +present) and then the DT overlay, if present, is applied. If the DT overlay +is eliminated, this header format may be used on systems running without +Device Tree. + +Example +======= + +/dts-v1/; + +/ { + description = "Program FPGA image and apply DT overlay"; + #address-cells = <1>; + + images { + fdt@1 { + description = "Flattened Device Tree blob"; + type = "flat_dt"; + data = /incbin/("/some/path/persona0.dtb"); + }; + fpga@1 { + description = "FPGA image"; + type = "fpga"; + data = /incbin/("/some/path/persona0.rbf"); + partial-fpga-config; + region-unfreeze-timeout-us = <4>; + region-freeze-timeout-us = <4>; + config-complete-timeout-us = <100>; + }; + }; +}; + +This format is compatible with FIT, but leaves out a few things that were not +needed. The compression property is left out (assuming none). The +'configurations' section is left out since there is only one possible +configuration presented here. If we see an actual use case for +configurations in the future, we could expand to support it seamlessly. + +Any FPGA image info must be included in the FPGA image section. FPGA image +info properties are defined in the fpga-region.txt Device Tree binding +document at ../devicetree/bindings/fpga/fpga-region.txt. + +The FPGA image section has to come last. + +Using mkimage +============= + +If the above example is named persona0.its, it can be compiled by using +mkimage as follows. The output file is persona0.fit. + + mkimage -f persona0.its persona0.fit + +Applying the image +================== + +A sysfs attribute 'firmware_name' is added for each FPGA region. + +To apply the image: + + echo persona.fit > /sys/class/fpga_region/region0/firmware_name + +To free up the region for reprogramming: + + echo > /sys/class/fpga_region/region0/firmware_name + +FPGA Region API Function +======================== + +An API for FPGA region has been added: + + int fpga_region_fdt_image_apply(struct fpga_region *region) + +This function will parse the header of a FPGA image and do the programming +and apply the DT overlay. The FPGA image is presented as a scatter gather +table, a contiguous buffer, or name of a firmware file in the region's FPGA +image info (region->info).
Signature · 1 line
2.7.4
RFC 2/5 doc: fpga: add sysfs document for fpga region
In reply to Alan TullDocument the firmware_name attribute added for each region.
--- Documentation/ABI/testing/sysfs-class-fpga-region | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-region
Documentation/ABI/testing/sysfs-class-fpga-region new file +7 -0
@@ -0,0 +1,7 @@ +What: /sys/class/fpga_region/<fpga>/firmware_name +Date: July 2017 +KernelVersion: 4.15 +Contact: Alan Tull <[email protected]> +Description: Write the name of FPGA image file on the firmware path to + program the FPGA region. Write nothing to free up the + FPGA region for reprogramming.
Signature · 1 line
2.7.4
RFC 3/5 fpga: add dev to fpga_image_info
In reply to Alan TullThis patch should be rolled into the next version of my "non-dt support for FPGA regions" patchset.
Add a pointer to the device that owns the fpga_image_info to fpga_image_info. That way the fpga_image_info_free can drop the 'dev' parameter and we are left with:
struct fpga_image_info *fpga_image_info_alloc(struct device *dev);
void fpga_image_info_free(struct fpga_image_info *info);
--- drivers/fpga/fpga-mgr.c | 14 ++++++++++---- drivers/fpga/of-fpga-region.c | 6 +++--- include/linux/fpga/fpga-mgr.h | 4 +++- 3 files changed, 16 insertions(+), 8 deletions(-)
drivers/fpga/fpga-mgr.c +10 -4
@@ -40,20 +40,26 @@ struct fpga_image_info *fpga_image_info_alloc(struct device *dev)if (!info)return ERR_PTR (-ENOMEM ); +get_device (dev); + info->dev = dev; +return info; }EXPORT_SYMBOL_GPL (fpga_image_info_alloc); -void fpga_image_info_free (struct device *dev, -struct fpga_image_info *info) +void fpga_image_info_free (struct fpga_image_info *info) { +struct device *dev; +if (!info)return ;if (info->firmware_name) -devm_kfree (dev, info->firmware_name); +devm_kfree (info->dev, info->firmware_name); -devm_kfree (dev, info); + dev = info->dev; +devm_kfree (info->dev, info); +put_device (dev); }EXPORT_SYMBOL_GPL (fpga_image_info_free);
drivers/fpga/of-fpga-region.c +3 -3
@@ -273,7 +273,7 @@ static struct fpga_image_info *of_fpga_region_parse_ov(return info; ret_no_info: -fpga_image_info_free (dev, info); +fpga_image_info_free (info);return ERR_PTR (ret); }
@@ -314,7 +314,7 @@ static int of_fpga_region_notify_pre_apply(struct fpga_region *region, ret =fpga_region_program_fpga (region);if (ret) {/* error; reject overlay */ -fpga_image_info_free (dev, info); +fpga_image_info_free (info); region->info =NULL ; }
@@ -335,7 +335,7 @@ static void of_fpga_region_notify_post_remove(struct fpga_region *region, {fpga_bridges_disable (®ion->bridge_list);fpga_bridges_put (®ion->bridge_list); -fpga_image_info_free (®ion->dev, region->info); +fpga_image_info_free (region->info); region->info =NULL ; }
include/linux/fpga/fpga-mgr.h +3 -1
@@ -79,6 +79,7 @@ enum fpga_mgr_states {/** * struct fpga_image_info - information specific to a FPGA image +* @dev: device that owns this info * @flags: boolean flags as defined above * @enable_timeout_us: maximum time to enable traffic through bridge (uSec) * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
@@ -91,6 +92,7 @@ enum fpga_mgr_states {* @overlay: Device Tree overlay */ struct fpga_image_info { +struct device *dev;u32 flags;u32 enable_timeout_us;u32 disable_timeout_us;
@@ -153,7 +155,7 @@ struct fpga_manager {struct fpga_image_info *fpga_image_info_alloc (struct device *dev); -void fpga_image_info_free (struct device *dev,struct fpga_image_info *info); +void fpga_image_info_free (struct fpga_image_info *info);int fpga_mgr_load (struct fpga_manager *mgr,struct fpga_image_info *info);
Signature · 1 line
2.7.4
RFC 4/5 fpga-region: new function fpga_region_free
In reply to Alan TullAdd FPGA region API function fpga_region_free() that undoes some of what fpga_region_program_fpga() does to free up a region to be reprogrammed.
--- drivers/fpga/fpga-region.c | 20 ++++++++++++++++++++ drivers/fpga/of-fpga-region.c | 5 +---- include/linux/fpga/fpga-region.h | 2 ++ 3 files changed, 23 insertions(+), 4 deletions(-)
drivers/fpga/fpga-region.c +20 -0
@@ -162,6 +162,26 @@ int fpga_region_program_fpga(struct fpga_region *region) }EXPORT_SYMBOL_GPL (fpga_region_program_fpga); +/** +* fpga_region_free +* Undo some of what fpga_region_program_fpga() did to free up +* region to be reprogrammed. +* @region: FPGA region +*/ +void fpga_region_free (struct fpga_region *region) +{ +if (!region->info) +return ; + +fpga_bridges_disable (®ion->bridge_list); +if (region->get_bridges) +fpga_bridges_put (®ion->bridge_list); + +fpga_image_info_free (region->info); + region->info =NULL ; +} +EXPORT_SYMBOL_GPL (fpga_region_free); +int fpga_region_register (struct device *dev,struct fpga_region *region) {int id, ret =0 ;
drivers/fpga/of-fpga-region.c +1 -4
@@ -333,10 +333,7 @@ static int of_fpga_region_notify_pre_apply(struct fpga_region *region,static void of_fpga_region_notify_post_remove (struct fpga_region *region,struct of_overlay_notify_data *nd) { -fpga_bridges_disable (®ion->bridge_list); -fpga_bridges_put (®ion->bridge_list); -fpga_image_info_free (region->info); - region->info =NULL ; +fpga_region_free (region); }/**
include/linux/fpga/fpga-region.h +2 -0
@@ -32,6 +32,8 @@ struct fpga_region *fpga_region_class_find( int (*match)(struct device *, const void *));int fpga_region_program_fpga (struct fpga_region *region); +void fpga_region_free (struct fpga_region *region); +int fpga_region_register (struct device *dev,struct fpga_region *region);int fpga_region_unregister (struct fpga_region *region);
Signature · 1 line
2.7.4
RFC 5/5 fpga-region support for fdt headers on fpga images
In reply to Alan TullSupport a FDT header for FPGA images. Header format is a simplified FIT containing at most one FPGA image and one DT overlay.
The FPGA image section includes FPGA image info properties needed for programming.
If present, the DT overlay image is applied after the FPGA is programmed.
Both images are optional. If the DT overlay isn't present, this interface may be used on systems running without a live Device Tree.
todo: add scatter gather table support.
--- drivers/fpga/Kconfig | 7 + drivers/fpga/fpga-region.c | 440 +++++++++++++++++++++++++++++++++++++++ drivers/fpga/of-fpga-region.c | 7 + include/linux/fpga/fpga-mgr.h | 9 + include/linux/fpga/fpga-region.h | 1 + 5 files changed, 464 insertions(+)
drivers/fpga/Kconfig +7 -0
@@ -19,6 +19,13 @@ config FPGA_REGION and the FPGA Bridges associated with either a reconfigurable region of an FPGA or a whole FPGA. +config FPGA_REGION_SYSFS + bool "FPGA Region Sysfs" + depends on FPGA_REGION + help + FPGA Region sysfs interface. This creates sysfs files under + /sys/class/fpga_region/ to control programming FPGA regions. + config OF_FPGA_REGION tristate "FPGA Region Device Tree Overlay Support" depends on OF && FPGA_REGION
drivers/fpga/fpga-region.c +440 -0
482 lines not on this page · raw message
drivers/fpga/of-fpga-region.c +7 -0
@@ -375,6 +375,13 @@ static int of_fpga_region_notify(struct notifier_block *nb,if (!region)return NOTIFY_OK ; +/* +* If notification is because bitstream had a fdt in the header, +* silently ignore notification. +*/ +if (region->info && region->info->fdt_blob) +return NOTIFY_OK ; + ret =0 ;switch (action) {case OF_OVERLAY_PRE_APPLY :
include/linux/fpga/fpga-mgr.h +9 -0
@@ -16,6 +16,7 @@* You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/firmware.h> #include <linux/mutex.h> #include <linux/platform_device.h>
@@ -86,10 +87,14 @@ enum fpga_mgr_states {* @config_complete_timeout_us: maximum time for FPGA to switch to operating * status in the write_complete op. * @firmware_name: name of FPGA image firmware file +* @fw: FPGA image firmware * @sgt: scatter/gather table containing FPGA image * @buf: contiguous buffer containing FPGA image * @count: size of buf +* @fdt_blob: fdt from FPGA image header +* @header: header * @overlay: Device Tree overlay +* @ov_id: id of applied overlay */ struct fpga_image_info {struct device *dev;
@@ -98,11 +103,15 @@ struct fpga_image_info {u32 disable_timeout_us;u32 config_complete_timeout_us;char *firmware_name; +const struct firmware *fw;struct sg_table *sgt;const char *buf;size_t count; +char *fdt_blob; +char *header;#ifdef CONFIG_OF struct device_node *overlay; +int ov_id;#endif };
include/linux/fpga/fpga-region.h +1 -0
@@ -33,6 +33,7 @@ struct fpga_region *fpga_region_class_find(int fpga_region_program_fpga (struct fpga_region *region);void fpga_region_free (struct fpga_region *region); +int fpga_region_fdt_image_apply (struct fpga_region *region);int fpga_region_register (struct device *dev,struct fpga_region *region);int fpga_region_unregister (struct fpga_region *region);
Signature · 1 line
2.7.4