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/dev/bhnd/bhnd_erom.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-FreeBSD
    3  *
    4  * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
    5  * Copyright (c) 2017 The FreeBSD Foundation
    6  * All rights reserved.
    7  *
    8  * Portions of this software were developed by Landon Fuller
    9  * under sponsorship from the FreeBSD Foundation.
   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  *    without modification.
   17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   18  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   19  *    redistribution must be conditioned upon including a substantially
   20  *    similar Disclaimer requirement for further binary redistribution.
   21  *
   22  * NO WARRANTY
   23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   25  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   26  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   27  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   28  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   31  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   33  * THE POSSIBILITY OF SUCH DAMAGES.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD$");
   38 
   39 #include <sys/param.h>
   40 #include <sys/bus.h>
   41 #include <sys/kobj.h>
   42   
   43 #include <machine/bus.h>
   44 #include <sys/rman.h>
   45 #include <machine/resource.h>
   46 
   47 #include <dev/bhnd/bhndreg.h>
   48 #include <dev/bhnd/bhndvar.h>
   49 
   50 #include <dev/bhnd/bhnd_erom.h>
   51 #include <dev/bhnd/bhnd_eromvar.h>
   52 
   53 #include <dev/bhnd/cores/chipc/chipcreg.h>
   54 
   55 static int      bhnd_erom_iores_map(struct bhnd_erom_io *eio, bhnd_addr_t addr,
   56                     bhnd_size_t size);
   57 static int      bhnd_erom_iores_tell(struct bhnd_erom_io *eio,
   58                     bhnd_addr_t *addr, bhnd_size_t *size);
   59 static uint32_t bhnd_erom_iores_read(struct bhnd_erom_io *eio,
   60                     bhnd_size_t offset, u_int width);
   61 static void     bhnd_erom_iores_fini(struct bhnd_erom_io *eio);
   62 
   63 static int      bhnd_erom_iobus_map(struct bhnd_erom_io *eio, bhnd_addr_t addr,
   64                     bhnd_size_t size);
   65 static int      bhnd_erom_iobus_tell(struct bhnd_erom_io *eio,
   66                     bhnd_addr_t *addr, bhnd_size_t *size);
   67 static uint32_t bhnd_erom_iobus_read(struct bhnd_erom_io *eio,
   68                     bhnd_size_t offset, u_int width);
   69 
   70 /**
   71  * An implementation of bhnd_erom_io that manages mappings via
   72  * bhnd_alloc_resource() and bhnd_release_resource().
   73  */
   74 struct bhnd_erom_iores {
   75         struct bhnd_erom_io      eio;
   76         device_t                 owner;         /**< device from which we'll allocate resources */
   77         int                      owner_rid;     /**< rid to use when allocating new mappings */
   78         struct bhnd_resource    *mapped;        /**< current mapping, or NULL */
   79         int                      mapped_rid;    /**< resource ID of current mapping, or -1 */
   80 };
   81 
   82 /**
   83  * Fetch the device enumeration parser class from all bhnd(4)-compatible drivers
   84  * registered for @p bus_devclass, probe @p eio for supporting parser classes,
   85  * and return the best available supporting enumeration parser class.
   86  * 
   87  * @param       bus_devclass    The bus device class to be queried for
   88  *                              bhnd(4)-compatible drivers.
   89  * @param       eio             An erom bus I/O instance, configured with a
   90  *                              mapping of the first bus core.
   91  * @param       hint            Identification hint used to identify the device.
   92  *                              If the chipset supports standard chip
   93  *                              identification registers within the first core,
   94  *                              this parameter should be NULL.
   95  * @param[out]  cid             On success, the probed chip identifier.
   96  * 
   97  * @retval non-NULL     on success, the best available EROM class.
   98  * @retval NULL         if no erom class returned a successful probe result for
   99  *                      @p eio.
  100  */
  101 bhnd_erom_class_t *
  102 bhnd_erom_probe_driver_classes(devclass_t bus_devclass,
  103     struct bhnd_erom_io *eio, const struct bhnd_chipid *hint,
  104     struct bhnd_chipid *cid)
  105 {
  106         driver_t                **drivers;
  107         int                      drv_count;
  108         bhnd_erom_class_t       *erom_cls;
  109         int                      error, prio, result;
  110 
  111         erom_cls = NULL;
  112         prio = 0;
  113 
  114         /* Fetch all available drivers */
  115         error = devclass_get_drivers(bus_devclass, &drivers, &drv_count);
  116         if (error) {
  117                 printf("error fetching bhnd(4) drivers for %s: %d\n",
  118                     devclass_get_name(bus_devclass), error);
  119                 return (NULL);
  120         }
  121 
  122         /* Enumerate the drivers looking for the best available EROM class */
  123         for (int i = 0; i < drv_count; i++) {
  124                 struct bhnd_chipid       pcid;
  125                 bhnd_erom_class_t       *cls;
  126 
  127                 /* The default implementation of BHND_BUS_GET_EROM_CLASS()
  128                  * returns NULL if unimplemented; this should always be safe
  129                  * to call on arbitrary drivers */
  130                 cls = bhnd_driver_get_erom_class(drivers[i]);
  131                 if (cls == NULL)
  132                         continue;
  133 
  134                 kobj_class_compile(cls);
  135 
  136                 /* Probe the bus */
  137                 result = bhnd_erom_probe(cls, eio, hint, &pcid);
  138 
  139                 /* The parser did not match if an error was returned */
  140                 if (result > 0)
  141                         continue;
  142                 
  143                 /* Check for a new highest priority match */
  144                 if (erom_cls == NULL || result > prio) {
  145                         prio = result;
  146 
  147                         *cid = pcid;
  148                         erom_cls = cls;
  149                 }
  150 
  151                 /* Terminate immediately on BUS_PROBE_SPECIFIC */
  152                 if (result == BUS_PROBE_SPECIFIC)
  153                         break;
  154         }
  155 
  156         free(drivers, M_TEMP);
  157         return (erom_cls);
  158 }
  159 
  160 /**
  161  * Allocate and return a new device enumeration table parser.
  162  *
  163  * @param cls           The parser class for which an instance will be
  164  *                      allocated.
  165  * @param eio           The bus I/O callbacks to use when reading the device
  166  *                      enumeration table.
  167  * @param cid           The device's chip identifier.
  168  *
  169  * @retval non-NULL     success
  170  * @retval NULL         if an error occurred allocating or initializing the
  171  *                      EROM parser.
  172  */
  173 bhnd_erom_t *
  174 bhnd_erom_alloc(bhnd_erom_class_t *cls, const struct bhnd_chipid *cid,
  175     struct bhnd_erom_io *eio)
  176 {
  177         bhnd_erom_t     *erom;
  178         int              error;
  179 
  180         erom = (bhnd_erom_t *)kobj_create((kobj_class_t)cls, M_BHND,
  181             M_WAITOK|M_ZERO);
  182 
  183         if ((error = BHND_EROM_INIT(erom, cid, eio))) {
  184                 printf("error initializing %s parser at %#jx: %d\n", cls->name,
  185                     (uintmax_t)cid->enum_addr, error);
  186 
  187                 kobj_delete((kobj_t)erom, M_BHND);
  188                 return (NULL);
  189         }
  190 
  191         return (erom);
  192 }
  193 
  194 /**
  195  * Perform static initialization of a device enumeration table parser.
  196  * 
  197  * This may be used to initialize a caller-allocated erom instance state
  198  * during early boot, prior to malloc availability.
  199  * 
  200  * @param cls           The parser class for which an instance will be
  201  *                      allocated.
  202  * @param erom          The erom parser instance to initialize.
  203  * @param esize         The total available number of bytes allocated for
  204  *                      @p erom. If this is less than is required by @p cls,
  205  *                      ENOMEM will be returned.
  206  * @param cid           The device's chip identifier.
  207  * @param eio           The bus I/O callbacks to use when reading the device
  208  *                      enumeration table.
  209  *
  210  * @retval 0            success
  211  * @retval ENOMEM       if @p esize is smaller than required by @p cls.
  212  * @retval non-zero     if an error occurs initializing the EROM parser,
  213  *                      a regular unix error code will be returned.
  214  */
  215 int
  216 bhnd_erom_init_static(bhnd_erom_class_t *cls, bhnd_erom_t *erom, size_t esize,
  217     const struct bhnd_chipid *cid, struct bhnd_erom_io *eio)
  218 {
  219         kobj_class_t    kcls;
  220 
  221         kcls = (kobj_class_t)cls;
  222 
  223         /* Verify allocation size */
  224         if (kcls->size > esize)
  225                 return (ENOMEM);
  226 
  227         /* Perform instance initialization */
  228         kobj_init_static((kobj_t)erom, kcls);
  229         return (BHND_EROM_INIT(erom, cid, eio)); 
  230 }
  231 
  232 /**
  233  * Release any resources held by a @p erom parser previously
  234  * initialized via bhnd_erom_init_static().
  235  * 
  236  * @param       erom    An erom parser instance previously initialized via
  237  *                      bhnd_erom_init_static().
  238  */
  239 void
  240 bhnd_erom_fini_static(bhnd_erom_t *erom)
  241 {
  242         return (BHND_EROM_FINI(erom));
  243 }
  244 
  245 /**
  246  * Release all resources held by a @p erom parser previously
  247  * allocated via bhnd_erom_alloc().
  248  * 
  249  * @param       erom    An erom parser instance previously allocated via
  250  *                      bhnd_erom_alloc().
  251  */
  252 void
  253 bhnd_erom_free(bhnd_erom_t *erom)
  254 {
  255         BHND_EROM_FINI(erom);
  256         kobj_delete((kobj_t)erom, M_BHND);
  257 }
  258 
  259 /**
  260  * Read the chip identification registers mapped by @p eio, popuating @p cid
  261  * with the parsed result
  262  * 
  263  * @param       eio             A bus I/O instance, configured with a mapping
  264  *                              of the ChipCommon core.
  265  * @param[out]  cid             On success, the parsed chip identification.
  266  *
  267  * @warning
  268  * On early siba(4) devices, the ChipCommon core does not provide
  269  * a valid CHIPC_ID_NUMCORE field. On these ChipCommon revisions
  270  * (see CHIPC_NCORES_MIN_HWREV()), this function will parse and return
  271  * an invalid `ncores` value.
  272  */
  273 int
  274 bhnd_erom_read_chipid(struct bhnd_erom_io *eio, struct bhnd_chipid *cid)
  275 {
  276         bhnd_addr_t     cc_addr;
  277         bhnd_size_t     cc_size;
  278         uint32_t        idreg, cc_caps;
  279         int             error;
  280 
  281         /* Fetch ChipCommon address */
  282         if ((error = bhnd_erom_io_tell(eio, &cc_addr, &cc_size)))
  283                 return (error);
  284 
  285         /* Read chip identifier */
  286         idreg = bhnd_erom_io_read(eio, CHIPC_ID, 4);
  287 
  288         /* Extract the basic chip info */
  289         cid->chip_id = CHIPC_GET_BITS(idreg, CHIPC_ID_CHIP);
  290         cid->chip_pkg = CHIPC_GET_BITS(idreg, CHIPC_ID_PKG);
  291         cid->chip_rev = CHIPC_GET_BITS(idreg, CHIPC_ID_REV);
  292         cid->chip_type = CHIPC_GET_BITS(idreg, CHIPC_ID_BUS);
  293         cid->ncores = CHIPC_GET_BITS(idreg, CHIPC_ID_NUMCORE);
  294 
  295         /* Populate EROM address */
  296         if (BHND_CHIPTYPE_HAS_EROM(cid->chip_type)) {
  297                 cid->enum_addr = bhnd_erom_io_read(eio, CHIPC_EROMPTR, 4);
  298         } else {
  299                 cid->enum_addr = cc_addr;
  300         }
  301 
  302         /* Populate capability flags */
  303         cc_caps = bhnd_erom_io_read(eio, CHIPC_CAPABILITIES, 4);
  304         cid->chip_caps = 0x0;
  305 
  306         if (cc_caps & CHIPC_CAP_BKPLN64)
  307                 cid->chip_caps |= BHND_CAP_BP64;
  308 
  309         if (cc_caps & CHIPC_CAP_PMU)
  310                 cid->chip_caps |= BHND_CAP_PMU;
  311 
  312         return (0);
  313 }
  314 
  315 /**
  316  * Attempt to map @p size bytes at @p addr, replacing any existing
  317  * @p eio mapping.
  318  * 
  319  * @param eio   I/O instance state.
  320  * @param addr  The address to be mapped.
  321  * @param size  The number of bytes to be mapped at @p addr.
  322  * 
  323  * @retval 0            success
  324  * @retval non-zero     if mapping @p addr otherwise fails, a regular
  325  *                      unix error code should be returned.
  326  */
  327 int
  328 bhnd_erom_io_map(struct bhnd_erom_io *eio, bhnd_addr_t addr, bhnd_size_t size)
  329 {
  330         return (eio->map(eio, addr, size));
  331 }
  332 
  333 /**
  334  * Return the address range mapped by @p eio, if any.
  335  * 
  336  * @param       eio     I/O instance state.
  337  * @param[out]  addr    The address mapped by @p eio.
  338  * @param[out]  size    The number of bytes mapped at @p addr.
  339  * 
  340  * @retval      0       success
  341  * @retval      ENXIO   if @p eio has no mapping.
  342  */
  343 int
  344 bhnd_erom_io_tell(struct bhnd_erom_io *eio, bhnd_addr_t *addr,
  345     bhnd_size_t *size)
  346 {
  347         return (eio->tell(eio, addr, size));
  348 }
  349 
  350 /**
  351  * Read a 1, 2, or 4 byte data item from @p eio, at the given @p offset
  352  * relative to @p eio's current mapping.
  353  * 
  354  * @param eio           erom I/O callbacks
  355  * @param offset        read offset.
  356  * @param width         item width (1, 2, or 4 bytes).
  357  */
  358 uint32_t
  359 bhnd_erom_io_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width)
  360 {
  361         return (eio->read(eio, offset, width));
  362 }
  363 
  364 /**
  365  * Free all resources held by @p eio.
  366  */
  367 void
  368 bhnd_erom_io_fini(struct bhnd_erom_io *eio)
  369 {
  370         if (eio->fini != NULL)
  371                 return (eio->fini(eio));
  372 }
  373 
  374 /**
  375  * Allocate, initialize, and return a new I/O instance that will perform
  376  * mapping by allocating SYS_RES_MEMORY resources from @p dev using @p rid.
  377  * 
  378  * @param dev   The device to pass to bhnd_alloc_resource() and
  379  *              bhnd_release_resource() functions.
  380  * @param rid   The resource ID to be used when allocating memory resources.
  381  */
  382 struct bhnd_erom_io *
  383 bhnd_erom_iores_new(device_t dev, int rid)
  384 {
  385         struct bhnd_erom_iores  *iores;
  386 
  387         iores = malloc(sizeof(*iores), M_BHND, M_WAITOK | M_ZERO);
  388         iores->eio.map = bhnd_erom_iores_map;
  389         iores->eio.tell = bhnd_erom_iores_tell;
  390         iores->eio.read = bhnd_erom_iores_read;
  391         iores->eio.fini = bhnd_erom_iores_fini;
  392 
  393         iores->owner = dev;
  394         iores->owner_rid = rid;
  395         iores->mapped = NULL;
  396         iores->mapped_rid = -1;
  397 
  398         return (&iores->eio);
  399 }
  400 
  401 static int
  402 bhnd_erom_iores_map(struct bhnd_erom_io *eio, bhnd_addr_t addr,
  403     bhnd_size_t size)
  404 {
  405         struct bhnd_erom_iores *iores;
  406 
  407         iores = (struct bhnd_erom_iores *)eio;
  408 
  409         /* Sanity check the addr/size */
  410         if (size == 0)
  411                 return (EINVAL);
  412 
  413         if (BHND_ADDR_MAX - size < addr)
  414                 return (EINVAL);        /* would overflow */
  415 
  416         /* Check for an existing mapping */
  417         if (iores->mapped) {
  418                 /* If already mapped, nothing else to do */
  419                 if (rman_get_start(iores->mapped->res) == addr &&
  420                     rman_get_size(iores->mapped->res) == size)
  421                 {
  422                         return (0);
  423                 }
  424 
  425                 /* Otherwise, we need to drop the existing mapping */
  426                 bhnd_release_resource(iores->owner, SYS_RES_MEMORY,
  427                     iores->mapped_rid, iores->mapped);
  428                 iores->mapped = NULL;
  429                 iores->mapped_rid = -1;
  430         }
  431 
  432         /* Try to allocate the new mapping */
  433         iores->mapped_rid = iores->owner_rid;
  434         iores->mapped = bhnd_alloc_resource(iores->owner, SYS_RES_MEMORY,
  435             &iores->mapped_rid, addr, addr+size-1, size,
  436             RF_ACTIVE|RF_SHAREABLE);
  437         if (iores->mapped == NULL) {
  438                 iores->mapped_rid = -1;
  439                 return (ENXIO);
  440         }
  441 
  442         return (0);
  443 }
  444 
  445 static int
  446 bhnd_erom_iores_tell(struct bhnd_erom_io *eio, bhnd_addr_t *addr,
  447     bhnd_size_t *size)
  448 {
  449         struct bhnd_erom_iores *iores = (struct bhnd_erom_iores *)eio;
  450 
  451         if (iores->mapped == NULL)
  452                 return (ENXIO);
  453 
  454         *addr = rman_get_start(iores->mapped->res);
  455         *size = rman_get_size(iores->mapped->res);
  456 
  457         return (0);
  458 }
  459 
  460 static uint32_t
  461 bhnd_erom_iores_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width)
  462 {
  463         struct bhnd_erom_iores *iores = (struct bhnd_erom_iores *)eio;
  464 
  465         if (iores->mapped == NULL)
  466                 panic("read with invalid mapping");
  467 
  468         switch (width) {
  469         case 1:
  470                 return (bhnd_bus_read_1(iores->mapped, offset));
  471         case 2:
  472                 return (bhnd_bus_read_2(iores->mapped, offset));
  473         case 4:
  474                 return (bhnd_bus_read_4(iores->mapped, offset));
  475         default:
  476                 panic("invalid width %u", width);
  477         }
  478 }
  479 
  480 static void
  481 bhnd_erom_iores_fini(struct bhnd_erom_io *eio)
  482 {
  483         struct bhnd_erom_iores *iores = (struct bhnd_erom_iores *)eio;
  484 
  485         /* Release any mapping */
  486         if (iores->mapped) {
  487                 bhnd_release_resource(iores->owner, SYS_RES_MEMORY,
  488                     iores->mapped_rid, iores->mapped);
  489                 iores->mapped = NULL;
  490                 iores->mapped_rid = -1;
  491         }
  492 
  493         free(eio, M_BHND);
  494 }
  495 
  496 /**
  497  * Initialize an I/O instance that will perform mapping directly from the
  498  * given bus space tag and handle.
  499  * 
  500  * @param iobus The I/O instance to be initialized.
  501  * @param addr  The base address mapped by @p bsh.
  502  * @param size  The total size mapped by @p bsh.
  503  * @param bst   Bus space tag for @p bsh.
  504  * @param bsh   Bus space handle mapping the full bus enumeration space.
  505  * 
  506  * @retval 0            success
  507  * @retval non-zero     if initializing @p iobus otherwise fails, a regular
  508  *                      unix error code will be returned.
  509  */
  510 int
  511 bhnd_erom_iobus_init(struct bhnd_erom_iobus *iobus, bhnd_addr_t addr,
  512     bhnd_size_t size, bus_space_tag_t bst, bus_space_handle_t bsh)
  513 {
  514         iobus->eio.map = bhnd_erom_iobus_map;
  515         iobus->eio.tell = bhnd_erom_iobus_tell;
  516         iobus->eio.read = bhnd_erom_iobus_read;
  517         iobus->eio.fini = NULL;
  518 
  519         iobus->addr = addr;
  520         iobus->size = size;
  521         iobus->bst = bst;
  522         iobus->bsh = bsh;
  523         iobus->mapped = false;
  524 
  525         return (0);
  526 }
  527 
  528 static int
  529 bhnd_erom_iobus_map(struct bhnd_erom_io *eio, bhnd_addr_t addr,
  530     bhnd_size_t size)
  531 {
  532         struct bhnd_erom_iobus *iobus = (struct bhnd_erom_iobus *)eio;
  533 
  534         /* Sanity check the addr/size */
  535         if (size == 0)
  536                 return (EINVAL);
  537 
  538         /* addr+size must not overflow */
  539         if (BHND_ADDR_MAX - size < addr)
  540                 return (EINVAL);
  541 
  542         /* addr/size must fit within our bus tag's mapping */
  543         if (addr < iobus->addr || size > iobus->size)
  544                 return (ENXIO);
  545 
  546         if (iobus->size - (addr - iobus->addr) < size)
  547                 return (ENXIO);
  548 
  549         /* The new addr offset and size must be representible as a bus_size_t */
  550         if ((addr - iobus->addr) > BUS_SPACE_MAXSIZE)
  551                 return (ENXIO);
  552 
  553         if (size > BUS_SPACE_MAXSIZE)
  554                 return (ENXIO);
  555 
  556         iobus->offset = addr - iobus->addr;
  557         iobus->limit = size;
  558         iobus->mapped = true;
  559 
  560         return (0);
  561 }
  562 
  563 static int
  564 bhnd_erom_iobus_tell(struct bhnd_erom_io *eio, bhnd_addr_t *addr,
  565     bhnd_size_t *size)
  566 {
  567         struct bhnd_erom_iobus *iobus = (struct bhnd_erom_iobus *)eio;
  568 
  569         if (!iobus->mapped)
  570                 return (ENXIO);
  571 
  572         *addr = iobus->addr + iobus->offset;
  573         *size = iobus->limit;
  574 
  575         return (0);
  576 }
  577 
  578 static uint32_t
  579 bhnd_erom_iobus_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width)
  580 {
  581         struct bhnd_erom_iobus *iobus = (struct bhnd_erom_iobus *)eio;
  582 
  583         if (!iobus->mapped) 
  584                 panic("no active mapping");
  585 
  586         if (iobus->limit < width || iobus->limit - width < offset)
  587                 panic("invalid offset %#jx", offset);
  588 
  589         switch (width) {
  590         case 1:
  591                 return (bus_space_read_1(iobus->bst, iobus->bsh,
  592                     iobus->offset + offset));
  593         case 2:
  594                 return (bus_space_read_2(iobus->bst, iobus->bsh,
  595                     iobus->offset + offset));
  596         case 4:
  597                 return (bus_space_read_4(iobus->bst, iobus->bsh,
  598                     iobus->offset + offset));
  599         default:
  600                 panic("invalid width %u", width);
  601         }
  602 }

Cache object: 44c17e645a2ddc66554b9afb8d9bcf78


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