diff --git a/sys/arm64/intel/stratix10-soc-fpga-mgr.c b/sys/arm64/intel/stratix10-soc-fpga-mgr.c index 177fb694c87..baa35b9a85a 100644 --- a/sys/arm64/intel/stratix10-soc-fpga-mgr.c +++ b/sys/arm64/intel/stratix10-soc-fpga-mgr.c @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2019 Ruslan Bukin + * Copyright (c) 2019-2024 Ruslan Bukin * * This software was developed by SRI International and the University of * Cambridge Computer Laboratory (Department of Computer Science and @@ -32,6 +32,9 @@ /* * Intel Stratix 10 FPGA Manager. + * + * FPGA Programming Example: + * dd if=cheri.core.rbf of=/dev/fpga_partial0 bs=512k */ #include @@ -57,7 +60,7 @@ #include #include -#define SVC_BUF_SIZE (2 * 1024 * 1024) +#define SVC_BUF_SIZE (512 * 1024) struct fpgamgr_s10_softc { struct cdev *mgr_cdev; @@ -109,12 +112,45 @@ fpga_open(struct cdev *dev, int flags __unused, return (0); } +static int +fpga_submit(struct cdev *dev) +{ + struct fpgamgr_s10_softc *sc; + struct s10_svc_msg msg; + int ret; + + sc = dev->si_drv1; + + bzero(&msg, sizeof(struct s10_svc_msg)); + msg.command = COMMAND_RECONFIG_DATA_SUBMIT; + msg.payload = (void *)sc->mem.paddr; + msg.payload_length = sc->mem.fill; + ret = s10_svc_send(sc->s10_svc_dev, &msg); + if (ret != 0) { + device_printf(sc->dev, "Failed to submit data\n"); + s10_svc_free_memory(sc->s10_svc_dev, &sc->mem); + sc->opened = 0; + return (ENXIO); + } + + /* Claim memory buffer back. */ + bzero(&msg, sizeof(struct s10_svc_msg)); + msg.command = COMMAND_RECONFIG_DATA_CLAIM; + ret = s10_svc_send(sc->s10_svc_dev, &msg); + if (ret) + device_printf(sc->dev, "Can't claim buffer back.\n"); + + return (ret); +} + static int fpga_write(struct cdev *dev, struct uio *uio, int ioflag) { struct fpgamgr_s10_softc *sc; vm_offset_t addr; + int error; int amnt; + int ret; sc = dev->si_drv1; @@ -127,11 +163,22 @@ fpga_write(struct cdev *dev, struct uio *uio, int ioflag) while (uio->uio_resid > 0) { addr = sc->mem.vaddr + sc->mem.fill; - if (sc->mem.fill >= SVC_BUF_SIZE) - return (ENOMEM); amnt = MIN(uio->uio_resid, (SVC_BUF_SIZE - sc->mem.fill)); - uiomove((void *)addr, amnt, uio); + error = uiomove((void *)addr, amnt, uio); + if (error) { + device_printf(sc->dev, "uiomove returned error %d\n", + error); + break; + } sc->mem.fill += amnt; + if (sc->mem.fill == SVC_BUF_SIZE) { + ret = fpga_submit(dev); + if (ret) { + sx_xunlock(&sc->sx); + return (ret); + } + sc->mem.fill = 0; + } } sx_xunlock(&sc->sx); @@ -144,7 +191,6 @@ fpga_close(struct cdev *dev, int flags __unused, int fmt __unused, struct thread *td __unused) { struct fpgamgr_s10_softc *sc; - struct s10_svc_msg msg; int ret; sc = dev->si_drv1; @@ -156,25 +202,15 @@ fpga_close(struct cdev *dev, int flags __unused, return (ENXIO); } - /* Submit bitstream */ - bzero(&msg, sizeof(struct s10_svc_msg)); - msg.command = COMMAND_RECONFIG_DATA_SUBMIT; - msg.payload = (void *)sc->mem.paddr; - msg.payload_length = sc->mem.fill; - ret = s10_svc_send(sc->s10_svc_dev, &msg); - if (ret != 0) { - device_printf(sc->dev, "Failed to submit data\n"); - s10_svc_free_memory(sc->s10_svc_dev, &sc->mem); - sc->opened = 0; - sx_xunlock(&sc->sx); - return (0); + if (sc->mem.fill > 0) { + ret = fpga_submit(dev); + if (ret) { + sx_xunlock(&sc->sx); + return (ret); + } + sc->mem.fill = 0; } - /* Claim memory buffer back */ - bzero(&msg, sizeof(struct s10_svc_msg)); - msg.command = COMMAND_RECONFIG_DATA_CLAIM; - s10_svc_send(sc->s10_svc_dev, &msg); - s10_svc_free_memory(sc->s10_svc_dev, &sc->mem); sc->opened = 0; sx_xunlock(&sc->sx);