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/riscv/htif/htif.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  * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
    3  * All rights reserved.
    4  *
    5  * Portions of this software were developed by SRI International and the
    6  * University of Cambridge Computer Laboratory under DARPA/AFRL contract
    7  * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
    8  *
    9  * Portions of this software were developed by the University of Cambridge
   10  * Computer Laboratory as part of the CTSRD Project, with support from the
   11  * UK Higher Education Innovation Fund (HEIF).
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  */
   34 
   35 #include <sys/cdefs.h>
   36 __FBSDID("$FreeBSD: releng/11.2/sys/riscv/htif/htif.c 295972 2016-02-24 16:50:34Z br $");
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/bus.h>
   41 #include <sys/kernel.h>
   42 #include <sys/module.h>
   43 #include <sys/rman.h>
   44 #include <sys/pcpu.h>
   45 #include <sys/proc.h>
   46 
   47 #include <vm/vm.h>
   48 #include <vm/pmap.h>
   49 
   50 #include <dev/fdt/fdt_common.h>
   51 #include <dev/ofw/openfirm.h>
   52 #include <dev/ofw/ofw_bus.h>
   53 #include <dev/ofw/ofw_bus_subr.h>
   54 
   55 #include <machine/bus.h>
   56 #include <machine/cpu.h>
   57 #include <machine/intr.h>
   58 #include <machine/asm.h>
   59 #include <machine/trap.h>
   60 #include <machine/vmparam.h>
   61 
   62 #include "htif.h"
   63 
   64 static struct resource_spec htif_spec[] = {
   65         { SYS_RES_IRQ,          0,      RF_ACTIVE | RF_SHAREABLE},
   66         { -1, 0 }
   67 };
   68 
   69 struct intr_entry {
   70         void (*func) (void *, uint64_t);
   71         void *arg;
   72 };
   73 
   74 struct intr_entry intrs[HTIF_NDEV];
   75 
   76 uint64_t
   77 htif_command(uint64_t arg)
   78 {
   79 
   80         return (machine_command(ECALL_HTIF_CMD, arg));
   81 }
   82 
   83 int
   84 htif_setup_intr(int id, void *func, void *arg)
   85 {
   86 
   87         if (id >= HTIF_NDEV)
   88                 return (-1);
   89 
   90         intrs[id].func = func;
   91         intrs[id].arg = arg;
   92 
   93         return (0);
   94 }
   95 
   96 static void
   97 htif_handle_entry(struct htif_softc *sc)
   98 {
   99         uint64_t entry;
  100         uint8_t devcmd;
  101         uint8_t devid;
  102 
  103         entry = machine_command(ECALL_HTIF_GET_ENTRY, 0);
  104         while (entry) {
  105                 devid = HTIF_DEV_ID(entry);
  106                 devcmd = HTIF_DEV_CMD(entry);
  107 
  108                 if (devcmd == HTIF_CMD_IDENTIFY) {
  109                         /* Enumeration interrupt */
  110                         if (devid == sc->identify_id)
  111                                 sc->identify_done = 1;
  112                 } else {
  113                         /* Device interrupt */
  114                         if (intrs[devid].func != NULL)
  115                                 intrs[devid].func(intrs[devid].arg, entry);
  116                 }
  117 
  118                 entry = machine_command(ECALL_HTIF_GET_ENTRY, 0);
  119         }
  120 }
  121 
  122 static int
  123 htif_intr(void *arg)
  124 {
  125         struct htif_softc *sc;
  126 
  127         sc = arg;
  128 
  129         csr_clear(sip, SIP_SSIP);
  130 
  131         htif_handle_entry(sc);
  132 
  133         return (FILTER_HANDLED);
  134 }
  135 
  136 static int
  137 htif_add_device(struct htif_softc *sc, int i, char *id, char *name)
  138 {
  139         struct htif_dev_ivars *di;
  140 
  141         di = malloc(sizeof(struct htif_dev_ivars), M_DEVBUF, M_WAITOK | M_ZERO);
  142         di->sc = sc;
  143         di->index = i;
  144         di->id = malloc(HTIF_ID_LEN, M_DEVBUF, M_WAITOK | M_ZERO);
  145         memcpy(di->id, id, HTIF_ID_LEN);
  146 
  147         di->dev = device_add_child(sc->dev, name, -1);
  148         device_set_ivars(di->dev, di);
  149 
  150         return (0);
  151 }
  152 
  153 static int
  154 htif_enumerate(struct htif_softc *sc)
  155 {
  156         char id[HTIF_ID_LEN] __aligned(HTIF_ALIGN);
  157         uint64_t paddr;
  158         uint64_t data;
  159         uint64_t cmd;
  160         int len;
  161         int i;
  162 
  163         device_printf(sc->dev, "Enumerating devices\n");
  164 
  165         for (i = 0; i < HTIF_NDEV; i++) {
  166                 paddr = pmap_kextract((vm_offset_t)&id);
  167                 data = (paddr << IDENTIFY_PADDR_SHIFT);
  168                 data |= IDENTIFY_IDENT;
  169 
  170                 sc->identify_id = i;
  171                 sc->identify_done = 0;
  172 
  173                 cmd = i;
  174                 cmd <<= HTIF_DEV_ID_SHIFT;
  175                 cmd |= (HTIF_CMD_IDENTIFY << HTIF_CMD_SHIFT);
  176                 cmd |= data;
  177 
  178                 htif_command(cmd);
  179 
  180                 /* Do poll as interrupts are disabled yet */
  181                 while (sc->identify_done == 0) {
  182                         htif_handle_entry(sc);
  183                 }
  184 
  185                 len = strnlen(id, sizeof(id));
  186                 if (len <= 0)
  187                         break;
  188 
  189                 if (bootverbose)
  190                         printf(" %d %s\n", i, id);
  191 
  192                 if (strncmp(id, "disk", 4) == 0)
  193                         htif_add_device(sc, i, id, "htif_blk");
  194                 else if (strncmp(id, "bcd", 3) == 0)
  195                         htif_add_device(sc, i, id, "htif_console");
  196                 else if (strncmp(id, "syscall_proxy", 13) == 0)
  197                         htif_add_device(sc, i, id, "htif_syscall_proxy");
  198         }
  199 
  200         return (bus_generic_attach(sc->dev));
  201 }
  202 
  203 int
  204 htif_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
  205 {
  206         struct htif_dev_ivars *ivars;
  207 
  208         ivars = device_get_ivars(child);
  209 
  210         switch (which) {
  211         case HTIF_IVAR_INDEX:
  212                 *result = ivars->index;
  213                 break;
  214         case HTIF_IVAR_ID:
  215                 *result = (uintptr_t)ivars->id;
  216         default:
  217                 return (EINVAL);
  218         }
  219 
  220         return (0);
  221 }
  222 
  223 static int
  224 htif_probe(device_t dev)
  225 {
  226 
  227         if (!ofw_bus_status_okay(dev))
  228                 return (ENXIO);
  229 
  230         if (!ofw_bus_is_compatible(dev, "riscv,htif"))
  231                 return (ENXIO);
  232 
  233         device_set_desc(dev, "HTIF bus device");
  234         return (BUS_PROBE_DEFAULT);
  235 }
  236 
  237 static int
  238 htif_attach(device_t dev)
  239 {
  240         struct htif_softc *sc;
  241         int error;
  242 
  243         sc = device_get_softc(dev);
  244         sc->dev = dev;
  245 
  246         if (bus_alloc_resources(dev, htif_spec, sc->res)) {
  247                 device_printf(dev, "could not allocate resources\n");
  248                 return (ENXIO);
  249         }
  250 
  251         /* Setup IRQs handler */
  252         error = bus_setup_intr(dev, sc->res[0], INTR_TYPE_CLK,
  253             htif_intr, NULL, sc, &sc->ihl[0]);
  254         if (error) {
  255                 device_printf(dev, "Unable to alloc int resource.\n");
  256                 return (ENXIO);
  257         }
  258 
  259         csr_set(sie, SIE_SSIE);
  260 
  261         return (htif_enumerate(sc));
  262 }
  263 
  264 static device_method_t htif_methods[] = {
  265         DEVMETHOD(device_probe,         htif_probe),
  266         DEVMETHOD(device_attach,        htif_attach),
  267 
  268         /* Bus interface */
  269         DEVMETHOD(bus_read_ivar,        htif_read_ivar),
  270 
  271         DEVMETHOD_END
  272 };
  273 
  274 static driver_t htif_driver = {
  275         "htif",
  276         htif_methods,
  277         sizeof(struct htif_softc)
  278 };
  279 
  280 static devclass_t htif_devclass;
  281 
  282 DRIVER_MODULE(htif, simplebus, htif_driver,
  283     htif_devclass, 0, 0);

Cache object: fa326b88a73ecb88fca9802cfb26ec4c


[ 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.