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/mips/broadcom/bhnd_nexus.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 Landon Fuller <landon@freebsd.org>
    3  * Copyright (c) 2017 The FreeBSD Foundation
    4  * All rights reserved.
    5  *
    6  * Portions of this software were developed by Landon Fuller
    7  * under sponsorship from the FreeBSD Foundation.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer,
   14  *    without modification.
   15  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   16  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   17  *    redistribution must be conditioned upon including a substantially
   18  *    similar Disclaimer requirement for further binary redistribution.
   19  *
   20  * NO WARRANTY
   21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   24  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   25  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   26  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   29  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   31  * THE POSSIBILITY OF SUCH DAMAGES.
   32  * 
   33  * $FreeBSD: releng/12.0/sys/mips/broadcom/bhnd_nexus.c 331746 2018-03-29 19:48:50Z landonf $
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD: releng/12.0/sys/mips/broadcom/bhnd_nexus.c 331746 2018-03-29 19:48:50Z landonf $");
   38 
   39 /*
   40  * bhnd(4) driver mix-in providing shared common methods for
   41  * bhnd bus devices attached via a MIPS root nexus.
   42  */
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/bus.h>
   47 #include <sys/intr.h>
   48 #include <sys/kernel.h>
   49 #include <sys/module.h>
   50 #include <sys/rman.h>
   51 #include <sys/malloc.h>
   52 
   53 #include <machine/bus.h>
   54 
   55 #include <dev/bhnd/bhndvar.h>
   56 #include <dev/bhnd/bhnd_ids.h>
   57 
   58 #include <dev/bhnd/cores/chipc/chipcreg.h>
   59 
   60 #include "bcm_machdep.h"
   61 #include "bcm_mipsvar.h"
   62 
   63 #include "bhnd_nexusvar.h"
   64 
   65 
   66 /**
   67  * Default bhnd_nexus implementation of BHND_BUS_GET_SERVICE_REGISTRY().
   68  */
   69 static struct bhnd_service_registry *
   70 bhnd_nexus_get_service_registry(device_t dev, device_t child)
   71 {
   72         struct bcm_platform *bp = bcm_get_platform();
   73         return (&bp->services);
   74 }
   75 
   76 /**
   77  * Default bhnd_nexus implementation of BHND_BUS_ACTIVATE_RESOURCE().
   78  */
   79 static int
   80 bhnd_nexus_activate_resource(device_t dev, device_t child, int type, int rid,
   81     struct bhnd_resource *r)
   82 {
   83         int error;
   84 
   85         /* Always direct */
   86         if ((error = bus_activate_resource(child, type, rid, r->res)))
   87                 return (error);
   88 
   89         r->direct = true;
   90         return (0);
   91 }
   92 
   93 /**
   94  * Default bhnd_nexus implementation of BHND_BUS_DEACTIVATE_RESOURCE().
   95  */
   96 static int
   97 bhnd_nexus_deactivate_resource(device_t dev, device_t child,
   98     int type, int rid, struct bhnd_resource *r)
   99 {
  100         int error;
  101 
  102         /* Always direct */
  103         KASSERT(r->direct, ("indirect resource delegated to bhnd_nexus\n"));
  104 
  105         if ((error = bus_deactivate_resource(child, type, rid, r->res)))
  106                 return (error);
  107 
  108         r->direct = false;
  109         return (0);
  110 }
  111 
  112 /**
  113  * Default bhnd_nexus implementation of BHND_BUS_IS_HW_DISABLED().
  114  */
  115 static bool
  116 bhnd_nexus_is_hw_disabled(device_t dev, device_t child)
  117 {
  118         struct bcm_platform     *bp;
  119         struct bhnd_chipid      *cid;
  120 
  121         bp = bcm_get_platform();
  122         cid = &bp->cid;
  123 
  124         /* The BCM4706 low-cost package leaves secondary GMAC cores
  125          * floating */
  126         if (cid->chip_id == BHND_CHIPID_BCM4706 &&
  127             cid->chip_pkg == BHND_PKGID_BCM4706L &&
  128             bhnd_get_device(child) == BHND_COREID_4706_GMAC &&
  129             bhnd_get_core_unit(child) != 0)
  130         {
  131                 return (true);
  132         }
  133 
  134         return (false);
  135 }
  136 
  137 /**
  138  * Default bhnd_nexus implementation of BHND_BUS_AGET_ATTACH_TYPE().
  139  */
  140 static bhnd_attach_type
  141 bhnd_nexus_get_attach_type(device_t dev, device_t child)
  142 {
  143         return (BHND_ATTACH_NATIVE);
  144 }
  145 
  146 /**
  147  * Default bhnd_nexus implementation of BHND_BUS_GET_CHIPID().
  148  */
  149 static const struct bhnd_chipid *
  150 bhnd_nexus_get_chipid(device_t dev, device_t child)
  151 {
  152         return (&bcm_get_platform()->cid);
  153 }
  154 
  155 /**
  156  * Default bhnd_nexus implementation of BHND_BUS_READ_BOARD_INFO().
  157  */
  158 static int
  159 bhnd_nexus_read_board_info(device_t dev, device_t child,
  160     struct bhnd_board_info *info)
  161 {
  162         int error;
  163 
  164         /* Initialize with NVRAM-derived values */
  165         if ((error = bhnd_bus_generic_read_board_info(dev, child, info)))
  166                 return (error);
  167 
  168         /* The board vendor should default to PCI_VENDOR_BROADCOM if not
  169          * otherwise specified */
  170         if (info->board_vendor == 0)
  171                 info->board_vendor = PCI_VENDOR_BROADCOM;
  172 
  173         return (0);
  174 }
  175 
  176 /**
  177  * Default bhnd_nexus implementation of BHND_BUS_MAP_INTR().
  178  */
  179 static int
  180 bhnd_nexus_map_intr(device_t dev, device_t child, u_int intr, rman_res_t *irq)
  181 {
  182         struct bcm_mips_intr_map_data   *imd;
  183         u_int                            ivec;
  184         uintptr_t                        xref;
  185         int                              error;
  186 
  187         /* Fetch the backplane interrupt vector */
  188         if ((error = bhnd_get_intr_ivec(child, intr, &ivec))) {
  189                 device_printf(dev, "error fetching ivec for intr %u: %d\n",
  190                     intr, error);
  191                 return (error);
  192         }
  193 
  194         /* Determine our interrupt domain */
  195         xref = BHND_BUS_GET_INTR_DOMAIN(dev, child, false);
  196         KASSERT(xref != 0, ("missing interrupt domain"));
  197 
  198         /* Allocate our map data */
  199         imd = (struct bcm_mips_intr_map_data *)intr_alloc_map_data(
  200             INTR_MAP_DATA_BCM_MIPS, sizeof(*imd), M_WAITOK | M_ZERO);
  201         imd->ivec = ivec;
  202 
  203         /* Map the IRQ */
  204         *irq = intr_map_irq(NULL, xref, &imd->mdata);
  205         return (0);
  206 }
  207 
  208 /**
  209  * Default bhnd_nexus implementation of BHND_BUS_UNMAP_INTR().
  210  */
  211 static void
  212 bhnd_nexus_unmap_intr(device_t dev, device_t child, rman_res_t irq)
  213 {
  214         if (irq > UINT_MAX)
  215                 panic("invalid irq: %ju", (uintmax_t)irq);
  216 
  217         intr_unmap_irq(irq);
  218 }
  219 
  220 /**
  221  * Default bhnd_nexus implementation of BHND_BUS_GET_DMA_TRANSLATION().
  222  */
  223 static int
  224 bhnd_nexus_get_dma_translation(device_t dev, device_t child,
  225     u_int width, uint32_t flags, bus_dma_tag_t *dmat,
  226     struct bhnd_dma_translation *translation)
  227 {
  228         struct bcm_platform *bp = bcm_get_platform();
  229 
  230         /* We don't (currently) support any flags */
  231         if (flags != 0x0)
  232                 return (ENOENT);
  233 
  234         KASSERT(width > 0 && width <= BHND_DMA_ADDR_64BIT,
  235             ("invalid width %u", width));
  236 
  237         /* Is the requested width supported? */
  238         if (width > BHND_DMA_ADDR_32BIT) {
  239                 /* Backplane must support 64-bit addressing */
  240                 if (!(bp->cid.chip_caps & BHND_CAP_BP64))
  241                         width = BHND_DMA_ADDR_32BIT;
  242         }
  243 
  244         /* No DMA address translation required */
  245         if (dmat != NULL)
  246                 *dmat = bus_get_dma_tag(dev);
  247 
  248         if (translation != NULL) {
  249                 *translation = (struct bhnd_dma_translation) {
  250                         .base_addr      = 0x0,
  251                         .addr_mask      = BHND_DMA_ADDR_BITMASK(width),
  252                         .addrext_mask   = 0
  253                 };
  254         }
  255 
  256         return (0);
  257 }
  258 
  259 static device_method_t bhnd_nexus_methods[] = {
  260         /* bhnd interface */
  261         DEVMETHOD(bhnd_bus_get_service_registry,bhnd_nexus_get_service_registry),
  262         DEVMETHOD(bhnd_bus_register_provider,   bhnd_bus_generic_sr_register_provider),
  263         DEVMETHOD(bhnd_bus_deregister_provider, bhnd_bus_generic_sr_deregister_provider),
  264         DEVMETHOD(bhnd_bus_retain_provider,     bhnd_bus_generic_sr_retain_provider),
  265         DEVMETHOD(bhnd_bus_release_provider,    bhnd_bus_generic_sr_release_provider),
  266         DEVMETHOD(bhnd_bus_activate_resource,   bhnd_nexus_activate_resource),
  267         DEVMETHOD(bhnd_bus_deactivate_resource, bhnd_nexus_deactivate_resource),
  268         DEVMETHOD(bhnd_bus_is_hw_disabled,      bhnd_nexus_is_hw_disabled),
  269         DEVMETHOD(bhnd_bus_get_attach_type,     bhnd_nexus_get_attach_type),
  270         DEVMETHOD(bhnd_bus_get_chipid,          bhnd_nexus_get_chipid),
  271         DEVMETHOD(bhnd_bus_get_dma_translation, bhnd_nexus_get_dma_translation),
  272         DEVMETHOD(bhnd_bus_get_intr_domain,     bhnd_bus_generic_get_intr_domain),
  273         DEVMETHOD(bhnd_bus_map_intr,            bhnd_nexus_map_intr),
  274         DEVMETHOD(bhnd_bus_read_board_info,     bhnd_nexus_read_board_info),
  275         DEVMETHOD(bhnd_bus_unmap_intr,          bhnd_nexus_unmap_intr),
  276 
  277         DEVMETHOD_END
  278 };
  279 
  280 DEFINE_CLASS_0(bhnd, bhnd_nexus_driver, bhnd_nexus_methods,
  281     sizeof(struct bhnd_softc));

Cache object: 37a6e26d6693fc938bf80cbf751ff8a9


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