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/nvram2env/nvram2env.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) 2010 Aleksandr Rybalko.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 /*
   30  * Pseudo driver to copy the NVRAM settings from various sources
   31  * into the kernel environment.
   32  *
   33  * Drivers (such as ethernet devices) can then use environment
   34  * variables to set default parameters.
   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/endian.h>
   44 #include <sys/kernel.h>
   45 #include <sys/module.h>
   46 #include <sys/rman.h>
   47 #include <sys/malloc.h>
   48 
   49 #include <machine/bus.h>
   50 
   51 #include "nvram2env.h"
   52 
   53 static void
   54 nvram2env_identify(driver_t * drv, device_t parent)
   55 {
   56         int i, ivar;
   57 
   58         for (i = 0; !resource_int_value("nvram", i, "base", &ivar); i++)
   59                 BUS_ADD_CHILD(parent, 0, "nvram2env", i);
   60 }
   61 
   62 int
   63 nvram2env_probe(device_t dev)
   64 {
   65         uint32_t i, ivar, sig;
   66         struct nvram2env_softc * sc = device_get_softc(dev);
   67 
   68         /*
   69          * Please ensure that your implementation of NVRAM->ENV specifies
   70          * bus tag
   71          */
   72         if (sc->bst == NULL)
   73                 return (ENXIO);
   74 
   75         if (sc->sig == 0)
   76                 if (resource_int_value("nvram", device_get_unit(dev), "sig",
   77                     &sc->sig) != 0 || sc->sig == 0)
   78                         sc->sig = CFE_NVRAM_SIGNATURE;
   79 
   80         if (sc->maxsize == 0)
   81                 if (resource_int_value("nvram", device_get_unit(dev), "maxsize",
   82                     &sc->maxsize) != 0 || sc->maxsize == 0)
   83                         sc->maxsize = NVRAM_MAX_SIZE;
   84 
   85         if (sc->flags == 0)
   86                 if (resource_int_value("nvram", device_get_unit(dev), "flags",
   87                     &sc->flags) != 0 || sc->flags == 0)
   88                         sc->flags = NVRAM_FLAGS_GENERIC;
   89 
   90         for (i = 0; i < 2; i ++)
   91         {
   92                 switch (i) {
   93                 case 0:
   94                         break;
   95                 case 1:
   96                 case 2:
   97                         if (resource_int_value("nvram", device_get_unit(dev),
   98                             (i == 1) ? "base" : "fallbackbase", &ivar) != 0 ||
   99                             ivar == 0)
  100                                 continue;
  101 
  102                         sc->addr = ivar;
  103                         break;
  104                 default:
  105                         break;
  106                 }
  107 
  108                 if (sc->addr == 0)
  109                         continue;
  110 
  111                 if (bootverbose)
  112                         device_printf(dev, "base=0x%08x sig=0x%08x "
  113                             "maxsize=0x%08x flags=0x%08x\n",
  114                             sc->addr, sc->sig, sc->maxsize, sc->flags);
  115 
  116                 if (bus_space_map(sc->bst, sc->addr, sc->maxsize, 0,
  117                     &sc->bsh) != 0)
  118                         continue;
  119 
  120                 sig = bus_space_read_4(sc->bst, sc->bsh, 0);
  121                 if ( sig == sc->sig /*FLSH*/)
  122                 {
  123                         device_printf(dev, "Found NVRAM at %#x\n", 
  124                             (uint32_t)ivar);
  125                         sc->need_swap = 0;
  126                         goto unmap_done;
  127                 }
  128                 else if ( htole32(sig) == sc->sig /*HSLF*/)
  129                 {
  130                         device_printf(dev, "Found NVRAM at %#x\n", 
  131                             (uint32_t)ivar);
  132                         sc->need_swap = 1;
  133                         goto unmap_done;
  134                 } else if (sc->flags & NVRAM_FLAGS_UBOOT) {
  135                         device_printf(dev, "Use NVRAM at %#x\n", 
  136                             (uint32_t)ivar);
  137                         sc->crc = sig;
  138                         goto unmap_done;
  139                 }
  140                 bus_space_unmap(sc->bst, sc->bsh, NVRAM_MAX_SIZE);
  141         }
  142         sc->bst = 0;
  143         sc->bsh = 0;
  144         sc->addr = 0;
  145         return (ENXIO);
  146 
  147 unmap_done:
  148         bus_space_unmap(sc->bst, sc->bsh, NVRAM_MAX_SIZE);
  149         device_set_desc(dev, "NVRAM to ENV pseudo-device");
  150         return (BUS_PROBE_SPECIFIC);
  151 
  152 }
  153 
  154 static uint32_t read_4(struct nvram2env_softc * sc, int offset) 
  155 {
  156         if (sc->need_swap) 
  157                 return (bswap32(bus_space_read_4(sc->bst, sc->bsh, offset)));
  158         else
  159                 return (bus_space_read_4(sc->bst, sc->bsh, offset));
  160 }
  161 
  162 int
  163 nvram2env_attach(device_t dev)
  164 {
  165         struct nvram2env_softc  *sc;
  166         struct nvram            *nv;
  167         char *pair, *value, *assign;
  168         uint32_t sig, size, i, *tmp;
  169 
  170         sc = device_get_softc(dev);
  171 
  172         if (sc->bst == 0 || sc->addr == 0)
  173                 return (ENXIO);
  174 
  175         if (bus_space_map(sc->bst, sc->addr, NVRAM_MAX_SIZE, 0,
  176                 &sc->bsh) != 0)
  177                 return (ENXIO);
  178 
  179         sig  = read_4(sc, 0);
  180         size = read_4(sc, 4);
  181 
  182         if (bootverbose)
  183                 device_printf(dev, " size=0x%05x maxsize=0x%05x\n", size,
  184                                 sc->maxsize);
  185 
  186         size = (size > sc->maxsize)?sc->maxsize:size;
  187 
  188         if (sig == sc->sig || (sc->flags & NVRAM_FLAGS_UBOOT))
  189         {
  190                 /* align size to 32bit size*/
  191                 size += 3;
  192                 size &= ~3;
  193 
  194                 nv = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
  195                 if (!nv)
  196                         return (ENOMEM);
  197                 /* set tmp pointer to begin of NVRAM */
  198                 tmp = (uint32_t *) nv;
  199 
  200                 /* use read_4 to swap bytes if it's required */
  201                 for (i = 0; i < size; i += 4) {
  202                         *tmp = read_4(sc, i);
  203                         tmp++;
  204                 }
  205                 /* now tmp pointer is end of NVRAM */
  206 
  207                 if (sc->flags & NVRAM_FLAGS_BROADCOM) {
  208                         device_printf(dev, "sig = %#x\n",  nv->sig);
  209                         device_printf(dev, "size = %#x\n", nv->size);
  210                 }
  211 
  212                 if (!(sc->flags & NVRAM_FLAGS_NOCHECK)) {
  213                         /* TODO: need checksum verification */
  214                 }
  215 
  216                 if (sc->flags & NVRAM_FLAGS_GENERIC)
  217                         pair = (char*)nv+4;
  218                 if (sc->flags & NVRAM_FLAGS_UBOOT)
  219                         pair = (char*)nv+4;
  220                 else if (sc->flags & NVRAM_FLAGS_BROADCOM)
  221                         pair = (char*)nv+20;
  222                 else
  223                         pair = (char*)nv+4;
  224 
  225                 /* iterate over buffer till end. tmp points to end of NVRAM */
  226                 for ( ; pair < (char*)tmp; 
  227                     pair += strlen(pair) + strlen(value) + 2 ) {
  228                         if (!pair || (strlen(pair) == 0))
  229                                 break;
  230 
  231                         /* hint.nvram.0. */
  232                         assign = strchr(pair,'=');
  233                         assign[0] = '\0';
  234                         value = assign+1;
  235 
  236                         if (bootverbose)
  237                                 printf("ENV[%p]: %s=%s\n",
  238                                     (void*)((char*)pair - (char*)nv),
  239                                     pair, value);
  240 
  241                         kern_setenv(pair, value);
  242 
  243                         if (strcasecmp(pair, "WAN_MAC_ADDR") == 0) {
  244                                 /* Alias for MAC address of eth0 */
  245                                 if (bootverbose)
  246                                         printf("ENV: aliasing "
  247                                             "WAN_MAC_ADDR to ethaddr"
  248                                             " = %s\n",  value);
  249                                 kern_setenv("ethaddr", value);
  250                         }
  251                         else if (strcasecmp(pair, "LAN_MAC_ADDR") == 0){
  252                                 /* Alias for MAC address of eth1 */
  253                                 if (bootverbose)
  254                                         printf("ENV: aliasing "
  255                                             "LAN_MAC_ADDR to eth1addr"
  256                                             " = %s\n",  value);
  257                                 kern_setenv("eth1addr", value);
  258                         }
  259 
  260                         if (strcmp(pair, "bootverbose") == 0)
  261                                 bootverbose = strtoul(value, 0, 0);
  262                         if (strcmp(pair, "boothowto"  ) == 0)
  263                                 boothowto   = strtoul(value, 0, 0);
  264                 }
  265                 free(nv, M_DEVBUF);
  266         }
  267 
  268         bus_space_unmap(sc->bst, sc->bsh, NVRAM_MAX_SIZE);
  269 
  270         return (0);
  271 }
  272 
  273 static device_method_t nvram2env_methods[] = {
  274         /* Device interface */
  275         DEVMETHOD(device_identify,      nvram2env_identify),
  276         DEVMETHOD(device_probe,         nvram2env_probe),
  277         DEVMETHOD(device_attach,        nvram2env_attach),
  278 
  279         DEVMETHOD_END
  280 };
  281 
  282 driver_t nvram2env_driver = {
  283         "nvram2env",
  284         nvram2env_methods,
  285         sizeof(struct nvram2env_softc),
  286 };

Cache object: 02864d59d926d41b2bd5a6e9c27ec5b1


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