The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm64/intel/stratix10-soc-fpga-mgr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause
    3  *
    4  * Copyright (c) 2019 Ruslan Bukin <br@bsdpad.com>
    5  *
    6  * This software was developed by SRI International and the University of
    7  * Cambridge Computer Laboratory (Department of Computer Science and
    8  * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
    9  * DARPA SSITH research programme.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Intel Stratix 10 FPGA Manager.
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __FBSDID("$FreeBSD$");
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/bus.h>
   43 #include <sys/kernel.h>
   44 #include <sys/module.h>
   45 #include <sys/malloc.h>
   46 #include <sys/rman.h>
   47 #include <sys/timeet.h>
   48 #include <sys/timetc.h>
   49 #include <sys/conf.h>
   50 #include <sys/uio.h>
   51 #include <sys/sx.h>
   52 
   53 #include <dev/ofw/openfirm.h>
   54 #include <dev/ofw/ofw_bus.h>
   55 #include <dev/ofw/ofw_bus_subr.h>
   56 
   57 #include <arm64/intel/stratix10-svc.h>
   58 
   59 #include <machine/bus.h>
   60 #include <machine/cpu.h>
   61 #include <machine/intr.h>
   62 
   63 #define SVC_BUF_SIZE    (2 * 1024 * 1024)
   64 
   65 struct fpgamgr_s10_softc {
   66         struct cdev             *mgr_cdev;
   67         struct cdev             *mgr_cdev_partial;
   68         device_t                dev;
   69         device_t                s10_svc_dev;
   70         struct s10_svc_mem      mem;
   71         struct sx               sx;
   72         int                     opened;
   73 };
   74 
   75 static int
   76 fpga_open(struct cdev *dev, int flags __unused,
   77     int fmt __unused, struct thread *td __unused)
   78 {
   79         struct fpgamgr_s10_softc *sc;
   80         struct s10_svc_msg msg;
   81         int ret;
   82         int err;
   83 
   84         sc = dev->si_drv1;
   85 
   86         sx_xlock(&sc->sx);
   87         if (sc->opened) {
   88                 sx_xunlock(&sc->sx);
   89                 return (EBUSY);
   90         }
   91 
   92         err = s10_svc_allocate_memory(sc->s10_svc_dev,
   93             &sc->mem, SVC_BUF_SIZE);
   94         if (err != 0) {
   95                 sx_xunlock(&sc->sx);
   96                 return (ENXIO);
   97         }
   98 
   99         bzero(&msg, sizeof(struct s10_svc_msg));
  100         msg.command = COMMAND_RECONFIG;
  101         if (dev == sc->mgr_cdev_partial)
  102                 msg.flags |= COMMAND_RECONFIG_FLAG_PARTIAL;
  103         ret = s10_svc_send(sc->s10_svc_dev, &msg);
  104         if (ret != 0) {
  105                 sx_xunlock(&sc->sx);
  106                 return (ENXIO);
  107         }
  108 
  109         sc->opened = 1;
  110         sx_xunlock(&sc->sx);
  111 
  112         return (0);
  113 }
  114 
  115 static int
  116 fpga_write(struct cdev *dev, struct uio *uio, int ioflag)
  117 {
  118         struct fpgamgr_s10_softc *sc;
  119         vm_offset_t addr;
  120         int amnt;
  121 
  122         sc = dev->si_drv1;
  123 
  124         sx_xlock(&sc->sx);
  125         if (sc->opened == 0) {
  126                 /* Device closed. */
  127                 sx_xunlock(&sc->sx);
  128                 return (ENXIO);
  129         }
  130 
  131         while (uio->uio_resid > 0) {
  132                 addr = sc->mem.vaddr + sc->mem.fill;
  133                 if (sc->mem.fill >= SVC_BUF_SIZE)
  134                         return (ENOMEM);
  135                 amnt = MIN(uio->uio_resid, (SVC_BUF_SIZE - sc->mem.fill));
  136                 uiomove((void *)addr, amnt, uio);
  137                 sc->mem.fill += amnt;
  138         }
  139 
  140         sx_xunlock(&sc->sx);
  141 
  142         return (0);
  143 }
  144 
  145 static int
  146 fpga_close(struct cdev *dev, int flags __unused,
  147     int fmt __unused, struct thread *td __unused)
  148 {
  149         struct fpgamgr_s10_softc *sc;
  150         struct s10_svc_msg msg;
  151         int ret;
  152 
  153         sc = dev->si_drv1;
  154 
  155         sx_xlock(&sc->sx);
  156         if (sc->opened == 0) {
  157                 /* Device closed. */
  158                 sx_xunlock(&sc->sx);
  159                 return (ENXIO);
  160         }
  161 
  162         /* Submit bitstream */
  163         bzero(&msg, sizeof(struct s10_svc_msg));
  164         msg.command = COMMAND_RECONFIG_DATA_SUBMIT;
  165         msg.payload = (void *)sc->mem.paddr;
  166         msg.payload_length = sc->mem.fill;
  167         ret = s10_svc_send(sc->s10_svc_dev, &msg);
  168         if (ret != 0) {
  169                 device_printf(sc->dev, "Failed to submit data\n");
  170                 s10_svc_free_memory(sc->s10_svc_dev, &sc->mem);
  171                 sc->opened = 0;
  172                 sx_xunlock(&sc->sx);
  173                 return (0);
  174         }
  175 
  176         /* Claim memory buffer back */
  177         bzero(&msg, sizeof(struct s10_svc_msg));
  178         msg.command = COMMAND_RECONFIG_DATA_CLAIM;
  179         s10_svc_send(sc->s10_svc_dev, &msg);
  180 
  181         s10_svc_free_memory(sc->s10_svc_dev, &sc->mem);
  182         sc->opened = 0;
  183         sx_xunlock(&sc->sx);
  184 
  185         return (0);
  186 }
  187 
  188 static int
  189 fpga_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
  190     struct thread *td)
  191 {
  192 
  193         return (0);
  194 }
  195 
  196 static struct cdevsw fpga_cdevsw = {
  197         .d_version =    D_VERSION,
  198         .d_open =       fpga_open,
  199         .d_close =      fpga_close,
  200         .d_write =      fpga_write,
  201         .d_ioctl =      fpga_ioctl,
  202         .d_name =       "FPGA Manager",
  203 };
  204 
  205 static int
  206 fpgamgr_s10_probe(device_t dev)
  207 {
  208 
  209         if (!ofw_bus_status_okay(dev))
  210                 return (ENXIO);
  211 
  212         if (!ofw_bus_is_compatible(dev, "intel,stratix10-soc-fpga-mgr"))
  213                 return (ENXIO);
  214 
  215         device_set_desc(dev, "Stratix 10 SOC FPGA Manager");
  216 
  217         return (BUS_PROBE_DEFAULT);
  218 }
  219 
  220 static int
  221 fpgamgr_s10_attach(device_t dev)
  222 {
  223         struct fpgamgr_s10_softc *sc;
  224         devclass_t dc;
  225 
  226         sc = device_get_softc(dev);
  227         sc->dev = dev;
  228 
  229         dc = devclass_find("s10_svc");
  230         if (dc == NULL)
  231                 return (ENXIO);
  232 
  233         sc->s10_svc_dev = devclass_get_device(dc, 0);
  234         if (sc->s10_svc_dev == NULL)
  235                 return (ENXIO);
  236 
  237         sc->mgr_cdev = make_dev(&fpga_cdevsw, 0, UID_ROOT, GID_WHEEL,
  238             0600, "fpga%d", device_get_unit(sc->dev));
  239         if (sc->mgr_cdev == NULL) {
  240                 device_printf(dev, "Failed to create character device.\n");
  241                 return (ENXIO);
  242         }
  243 
  244         sc->mgr_cdev_partial = make_dev(&fpga_cdevsw, 0, UID_ROOT, GID_WHEEL,
  245             0600, "fpga_partial%d", device_get_unit(sc->dev));
  246         if (sc->mgr_cdev_partial == NULL) {
  247                 device_printf(dev, "Failed to create character device.\n");
  248                 return (ENXIO);
  249         }
  250 
  251         sx_init(&sc->sx, "s10 fpga");
  252 
  253         sc->mgr_cdev->si_drv1 = sc;
  254         sc->mgr_cdev_partial->si_drv1 = sc;
  255 
  256         return (0);
  257 }
  258 
  259 static int
  260 fpgamgr_s10_detach(device_t dev)
  261 {
  262         struct fpgamgr_s10_softc *sc;
  263 
  264         sc = device_get_softc(dev);
  265 
  266         destroy_dev(sc->mgr_cdev);
  267         destroy_dev(sc->mgr_cdev_partial);
  268 
  269         sx_destroy(&sc->sx);
  270 
  271         return (0);
  272 }
  273 
  274 static device_method_t fpgamgr_s10_methods[] = {
  275         DEVMETHOD(device_probe,         fpgamgr_s10_probe),
  276         DEVMETHOD(device_attach,        fpgamgr_s10_attach),
  277         DEVMETHOD(device_detach,        fpgamgr_s10_detach),
  278         { 0, 0 }
  279 };
  280 
  281 static driver_t fpgamgr_s10_driver = {
  282         "fpgamgr_s10",
  283         fpgamgr_s10_methods,
  284         sizeof(struct fpgamgr_s10_softc),
  285 };
  286 
  287 DRIVER_MODULE(fpgamgr_s10, simplebus, fpgamgr_s10_driver, 0, 0);

Cache object: 411c262ec85aa61568cb305c62177ee2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.