Re: [PATCH V4 XRT Alveo 11/20] fpga: xrt: fpga-mgr and region implementation for xclbin download
Hi Tom, On 04/01/2021 07:43 AM, Tom Rix wrote: small alloc's should use kzalloc. On 3/23/21 10:29 PM, Lizhi Hou wrote: fpga-mgr and region implementation for xclbin download which will be called from main platform driver Signed-off-by: Sonal Santan Signed-off-by: Max Zhen Signed-off-by: Lizhi Hou --- drivers/fpga/xrt/mgmt/fmgr-drv.c| 191 +++ drivers/fpga/xrt/mgmt/fmgr.h| 19 ++ drivers/fpga/xrt/mgmt/main-region.c | 483 3 files changed, 693 insertions(+) create mode 100644 drivers/fpga/xrt/mgmt/fmgr-drv.c create mode 100644 drivers/fpga/xrt/mgmt/fmgr.h a better file name would be xrt-mgr.* Will change file name to xrt-mgr.* create mode 100644 drivers/fpga/xrt/mgmt/main-region.c diff --git a/drivers/fpga/xrt/mgmt/fmgr-drv.c b/drivers/fpga/xrt/mgmt/fmgr-drv.c new file mode 100644 index ..12e1cc788ad9 --- /dev/null +++ b/drivers/fpga/xrt/mgmt/fmgr-drv.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * FPGA Manager Support for Xilinx Alveo Management Function Driver Since there is only one fpga mgr for xrt, this could be shortened to * FPGA Manager Support for Xilinx Alevo Sure. + * + * Copyright (C) 2020-2021 Xilinx, Inc. + * + * Authors: sonal.san...@xilinx.com + */ + +#include +#include +#include +#include +#include +#include + +#include "xclbin-helper.h" +#include "xleaf.h" +#include "fmgr.h" +#include "xleaf/axigate.h" +#include "xleaf/icap.h" +#include "xmgnt.h" + +struct xfpga_class { + const struct platform_device *pdev; + char name[64]; +}; + +/* + * xclbin download plumbing -- find the download subsystem, ICAP and + * pass the xclbin for heavy lifting + */ +static int xmgmt_download_bitstream(struct platform_device *pdev, + const struct axlf *xclbin) + +{ + struct xclbin_bit_head_info bit_header = { 0 }; + struct platform_device *icap_leaf = NULL; + struct xrt_icap_wr arg; + char *bitstream = NULL; + u64 bit_len; + int ret; + + ret = xrt_xclbin_get_section(DEV(pdev), xclbin, BITSTREAM, (void **)&bitstream, &bit_len); + if (ret) { + xrt_err(pdev, "bitstream not found"); + return -ENOENT; + } + ret = xrt_xclbin_parse_bitstream_header(DEV(pdev), bitstream, + XCLBIN_HWICAP_BITFILE_BUF_SZ, + &bit_header); + if (ret) { + ret = -EINVAL; + xrt_err(pdev, "invalid bitstream header"); + goto fail; + } + if (bit_header.header_length + bit_header.bitstream_length > bit_len) { + ret = -EINVAL; + xrt_err(pdev, "invalid bitstream length. header %d, bitstream %d, section len %lld", + bit_header.header_length, bit_header.bitstream_length, bit_len); + goto fail; + } + + icap_leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_ICAP, PLATFORM_DEVID_NONE); + if (!icap_leaf) { + ret = -ENODEV; + xrt_err(pdev, "icap does not exist"); + goto fail; + } + arg.xiiw_bit_data = bitstream + bit_header.header_length; + arg.xiiw_data_len = bit_header.bitstream_length; + ret = xleaf_call(icap_leaf, XRT_ICAP_WRITE, &arg); + if (ret) { + xrt_err(pdev, "write bitstream failed, ret = %d", ret); + xleaf_put_leaf(pdev, icap_leaf); + goto fail; + } ok, free_header removed + + xleaf_put_leaf(pdev, icap_leaf); + vfree(bitstream); + + return 0; + +fail: + vfree(bitstream); + + return ret; +} + +/* + * There is no HW prep work we do here since we need the full + * xclbin for its sanity check. + */ +static int xmgmt_pr_write_init(struct fpga_manager *mgr, +struct fpga_image_info *info, +const char *buf, size_t count) +{ + const struct axlf *bin = (const struct axlf *)buf; + struct xfpga_class *obj = mgr->priv; + + if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { + xrt_info(obj->pdev, "%s only supports partial reconfiguration\n", obj->name); + return -EINVAL; + } + + if (count < sizeof(struct axlf)) + return -EINVAL; + + if (count > bin->header.length) + return -EINVAL; + + xrt_info(obj->pdev, "Prepare download of xclbin %pUb of length %lld B", + &bin->header.uuid, bin->header.length); + + return 0; +} + +/* + * The implementation requries full xclbin image before we can start + * programming the hardware via ICAP subsystem. The full image is required ok + * for checking the validity of xclbin and walking the sections to + * discover the bitstream. + */ +static int xmgmt_pr_write(struct fpga_manager *mgr, + const char *buf, size_t count) +{ + const struct axlf *bin = (const struct axlf *)buf; + struct xfpga_class *o
Re: [PATCH V4 XRT Alveo 11/20] fpga: xrt: fpga-mgr and region implementation for xclbin download
small alloc's should use kzalloc. On 3/23/21 10:29 PM, Lizhi Hou wrote: > fpga-mgr and region implementation for xclbin download which will be > called from main platform driver > > Signed-off-by: Sonal Santan > Signed-off-by: Max Zhen > Signed-off-by: Lizhi Hou > --- > drivers/fpga/xrt/mgmt/fmgr-drv.c| 191 +++ > drivers/fpga/xrt/mgmt/fmgr.h| 19 ++ > drivers/fpga/xrt/mgmt/main-region.c | 483 > 3 files changed, 693 insertions(+) > create mode 100644 drivers/fpga/xrt/mgmt/fmgr-drv.c > create mode 100644 drivers/fpga/xrt/mgmt/fmgr.h a better file name would be xrt-mgr.* > create mode 100644 drivers/fpga/xrt/mgmt/main-region.c > > diff --git a/drivers/fpga/xrt/mgmt/fmgr-drv.c > b/drivers/fpga/xrt/mgmt/fmgr-drv.c > new file mode 100644 > index ..12e1cc788ad9 > --- /dev/null > +++ b/drivers/fpga/xrt/mgmt/fmgr-drv.c > @@ -0,0 +1,191 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * FPGA Manager Support for Xilinx Alveo Management Function Driver Since there is only one fpga mgr for xrt, this could be shortened to * FPGA Manager Support for Xilinx Alevo > + * > + * Copyright (C) 2020-2021 Xilinx, Inc. > + * > + * Authors: sonal.san...@xilinx.com > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "xclbin-helper.h" > +#include "xleaf.h" > +#include "fmgr.h" > +#include "xleaf/axigate.h" > +#include "xleaf/icap.h" > +#include "xmgnt.h" > + > +struct xfpga_class { > + const struct platform_device *pdev; > + char name[64]; > +}; > + > +/* > + * xclbin download plumbing -- find the download subsystem, ICAP and > + * pass the xclbin for heavy lifting > + */ > +static int xmgmt_download_bitstream(struct platform_device *pdev, > + const struct axlf *xclbin) > + > +{ > + struct xclbin_bit_head_info bit_header = { 0 }; > + struct platform_device *icap_leaf = NULL; > + struct xrt_icap_wr arg; > + char *bitstream = NULL; > + u64 bit_len; > + int ret; > + > + ret = xrt_xclbin_get_section(DEV(pdev), xclbin, BITSTREAM, (void > **)&bitstream, &bit_len); > + if (ret) { > + xrt_err(pdev, "bitstream not found"); > + return -ENOENT; > + } > + ret = xrt_xclbin_parse_bitstream_header(DEV(pdev), bitstream, > + XCLBIN_HWICAP_BITFILE_BUF_SZ, > + &bit_header); > + if (ret) { > + ret = -EINVAL; > + xrt_err(pdev, "invalid bitstream header"); > + goto fail; > + } > + if (bit_header.header_length + bit_header.bitstream_length > bit_len) { > + ret = -EINVAL; > + xrt_err(pdev, "invalid bitstream length. header %d, bitstream > %d, section len %lld", > + bit_header.header_length, bit_header.bitstream_length, > bit_len); > + goto fail; > + } > + > + icap_leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_ICAP, > PLATFORM_DEVID_NONE); > + if (!icap_leaf) { > + ret = -ENODEV; > + xrt_err(pdev, "icap does not exist"); > + goto fail; > + } > + arg.xiiw_bit_data = bitstream + bit_header.header_length; > + arg.xiiw_data_len = bit_header.bitstream_length; > + ret = xleaf_call(icap_leaf, XRT_ICAP_WRITE, &arg); > + if (ret) { > + xrt_err(pdev, "write bitstream failed, ret = %d", ret); > + xleaf_put_leaf(pdev, icap_leaf); > + goto fail; > + } ok, free_header removed > + > + xleaf_put_leaf(pdev, icap_leaf); > + vfree(bitstream); > + > + return 0; > + > +fail: > + vfree(bitstream); > + > + return ret; > +} > + > +/* > + * There is no HW prep work we do here since we need the full > + * xclbin for its sanity check. > + */ > +static int xmgmt_pr_write_init(struct fpga_manager *mgr, > +struct fpga_image_info *info, > +const char *buf, size_t count) > +{ > + const struct axlf *bin = (const struct axlf *)buf; > + struct xfpga_class *obj = mgr->priv; > + > + if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { > + xrt_info(obj->pdev, "%s only supports partial > reconfiguration\n", obj->name); > + return -EINVAL; > + } > + > + if (count < sizeof(struct axlf)) > + return -EINVAL; > + > + if (count > bin->header.length) > + return -EINVAL; > + > + xrt_info(obj->pdev, "Prepare download of xclbin %pUb of length %lld B", > + &bin->header.uuid, bin->header.length); > + > + return 0; > +} > + > +/* > + * The implementation requries full xclbin image before we can start > + * programming the hardware via ICAP subsystem. The full image is required ok > + * for checking the validity of xclbin and walking the sections to > + * discover the bitstream. > + */ > +sta
[PATCH V4 XRT Alveo 11/20] fpga: xrt: fpga-mgr and region implementation for xclbin download
fpga-mgr and region implementation for xclbin download which will be called from main platform driver Signed-off-by: Sonal Santan Signed-off-by: Max Zhen Signed-off-by: Lizhi Hou --- drivers/fpga/xrt/mgmt/fmgr-drv.c| 191 +++ drivers/fpga/xrt/mgmt/fmgr.h| 19 ++ drivers/fpga/xrt/mgmt/main-region.c | 483 3 files changed, 693 insertions(+) create mode 100644 drivers/fpga/xrt/mgmt/fmgr-drv.c create mode 100644 drivers/fpga/xrt/mgmt/fmgr.h create mode 100644 drivers/fpga/xrt/mgmt/main-region.c diff --git a/drivers/fpga/xrt/mgmt/fmgr-drv.c b/drivers/fpga/xrt/mgmt/fmgr-drv.c new file mode 100644 index ..12e1cc788ad9 --- /dev/null +++ b/drivers/fpga/xrt/mgmt/fmgr-drv.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * FPGA Manager Support for Xilinx Alveo Management Function Driver + * + * Copyright (C) 2020-2021 Xilinx, Inc. + * + * Authors: sonal.san...@xilinx.com + */ + +#include +#include +#include +#include +#include +#include + +#include "xclbin-helper.h" +#include "xleaf.h" +#include "fmgr.h" +#include "xleaf/axigate.h" +#include "xleaf/icap.h" +#include "xmgnt.h" + +struct xfpga_class { + const struct platform_device *pdev; + char name[64]; +}; + +/* + * xclbin download plumbing -- find the download subsystem, ICAP and + * pass the xclbin for heavy lifting + */ +static int xmgmt_download_bitstream(struct platform_device *pdev, + const struct axlf *xclbin) + +{ + struct xclbin_bit_head_info bit_header = { 0 }; + struct platform_device *icap_leaf = NULL; + struct xrt_icap_wr arg; + char *bitstream = NULL; + u64 bit_len; + int ret; + + ret = xrt_xclbin_get_section(DEV(pdev), xclbin, BITSTREAM, (void **)&bitstream, &bit_len); + if (ret) { + xrt_err(pdev, "bitstream not found"); + return -ENOENT; + } + ret = xrt_xclbin_parse_bitstream_header(DEV(pdev), bitstream, + XCLBIN_HWICAP_BITFILE_BUF_SZ, + &bit_header); + if (ret) { + ret = -EINVAL; + xrt_err(pdev, "invalid bitstream header"); + goto fail; + } + if (bit_header.header_length + bit_header.bitstream_length > bit_len) { + ret = -EINVAL; + xrt_err(pdev, "invalid bitstream length. header %d, bitstream %d, section len %lld", + bit_header.header_length, bit_header.bitstream_length, bit_len); + goto fail; + } + + icap_leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_ICAP, PLATFORM_DEVID_NONE); + if (!icap_leaf) { + ret = -ENODEV; + xrt_err(pdev, "icap does not exist"); + goto fail; + } + arg.xiiw_bit_data = bitstream + bit_header.header_length; + arg.xiiw_data_len = bit_header.bitstream_length; + ret = xleaf_call(icap_leaf, XRT_ICAP_WRITE, &arg); + if (ret) { + xrt_err(pdev, "write bitstream failed, ret = %d", ret); + xleaf_put_leaf(pdev, icap_leaf); + goto fail; + } + + xleaf_put_leaf(pdev, icap_leaf); + vfree(bitstream); + + return 0; + +fail: + vfree(bitstream); + + return ret; +} + +/* + * There is no HW prep work we do here since we need the full + * xclbin for its sanity check. + */ +static int xmgmt_pr_write_init(struct fpga_manager *mgr, + struct fpga_image_info *info, + const char *buf, size_t count) +{ + const struct axlf *bin = (const struct axlf *)buf; + struct xfpga_class *obj = mgr->priv; + + if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { + xrt_info(obj->pdev, "%s only supports partial reconfiguration\n", obj->name); + return -EINVAL; + } + + if (count < sizeof(struct axlf)) + return -EINVAL; + + if (count > bin->header.length) + return -EINVAL; + + xrt_info(obj->pdev, "Prepare download of xclbin %pUb of length %lld B", +&bin->header.uuid, bin->header.length); + + return 0; +} + +/* + * The implementation requries full xclbin image before we can start + * programming the hardware via ICAP subsystem. The full image is required + * for checking the validity of xclbin and walking the sections to + * discover the bitstream. + */ +static int xmgmt_pr_write(struct fpga_manager *mgr, + const char *buf, size_t count) +{ + const struct axlf *bin = (const struct axlf *)buf; + struct xfpga_class *obj = mgr->priv; + + if (bin->header.length != count) + return -EINVAL; + + return xmgmt_download_bitstream((void *)obj->pdev, bin); +} + +static int xmgmt_pr_write_complete(struct fpga_manager *mgr, +