Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *
0003  * BRIEF MODULE DESCRIPTION
0004  *    PROM library initialisation code, supports YAMON and U-Boot.
0005  *
0006  * Copyright 2000-2001, 2006, 2008 MontaVista Software Inc.
0007  * Author: MontaVista Software, Inc. <source@mvista.com>
0008  *
0009  * This file was derived from Carsten Langgaard's
0010  * arch/mips/mips-boards/xx files.
0011  *
0012  * Carsten Langgaard, carstenl@mips.com
0013  * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
0014  *
0015  *  This program is free software; you can redistribute  it and/or modify it
0016  *  under  the terms of  the GNU General  Public License as published by the
0017  *  Free Software Foundation;  either version 2 of the  License, or (at your
0018  *  option) any later version.
0019  *
0020  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
0021  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
0022  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
0023  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
0024  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0025  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
0026  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
0027  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
0028  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0029  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0030  *
0031  *  You should have received a copy of the  GNU General Public License along
0032  *  with this program; if not, write  to the Free Software Foundation, Inc.,
0033  *  675 Mass Ave, Cambridge, MA 02139, USA.
0034  */
0035 
0036 #include <linux/init.h>
0037 #include <linux/kernel.h>
0038 #include <linux/memblock.h>
0039 #include <linux/sizes.h>
0040 #include <linux/string.h>
0041 
0042 #include <asm/bootinfo.h>
0043 
0044 int prom_argc;
0045 char **prom_argv;
0046 char **prom_envp;
0047 
0048 void __init prom_init_cmdline(void)
0049 {
0050     int i;
0051 
0052     for (i = 1; i < prom_argc; i++) {
0053         strlcat(arcs_cmdline, prom_argv[i], COMMAND_LINE_SIZE);
0054         if (i < (prom_argc - 1))
0055             strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
0056     }
0057 }
0058 
0059 char *prom_getenv(char *envname)
0060 {
0061     /*
0062      * Return a pointer to the given environment variable.
0063      * YAMON uses "name", "value" pairs, while U-Boot uses "name=value".
0064      */
0065 
0066     char **env = prom_envp;
0067     int i = strlen(envname);
0068     int yamon = (*env && strchr(*env, '=') == NULL);
0069 
0070     while (*env) {
0071         if (yamon) {
0072             if (strcmp(envname, *env++) == 0)
0073                 return *env;
0074         } else if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
0075             return *env + i + 1;
0076         env++;
0077     }
0078 
0079     return NULL;
0080 }
0081 
0082 void __init prom_init(void)
0083 {
0084     unsigned char *memsize_str;
0085     unsigned long memsize;
0086 
0087     prom_argc = (int)fw_arg0;
0088     prom_argv = (char **)fw_arg1;
0089     prom_envp = (char **)fw_arg2;
0090 
0091     prom_init_cmdline();
0092 
0093     memsize_str = prom_getenv("memsize");
0094     if (!memsize_str || kstrtoul(memsize_str, 0, &memsize))
0095         memsize = SZ_64M; /* minimum memsize is 64MB RAM */
0096 
0097     memblock_add(0, memsize);
0098 }
0099 
0100 static inline unsigned char str2hexnum(unsigned char c)
0101 {
0102     if (c >= '0' && c <= '9')
0103         return c - '0';
0104     if (c >= 'a' && c <= 'f')
0105         return c - 'a' + 10;
0106     if (c >= 'A' && c <= 'F')
0107         return c - 'A' + 10;
0108 
0109     return 0; /* foo */
0110 }
0111 
0112 static inline void str2eaddr(unsigned char *ea, unsigned char *str)
0113 {
0114     int i;
0115 
0116     for (i = 0; i < 6; i++) {
0117         unsigned char num;
0118 
0119         if ((*str == '.') || (*str == ':'))
0120             str++;
0121         num  = str2hexnum(*str++) << 4;
0122         num |= str2hexnum(*str++);
0123         ea[i] = num;
0124     }
0125 }
0126 
0127 int __init prom_get_ethernet_addr(char *ethernet_addr)
0128 {
0129     char *ethaddr_str;
0130 
0131     /* Check the environment variables first */
0132     ethaddr_str = prom_getenv("ethaddr");
0133     if (!ethaddr_str) {
0134         /* Check command line */
0135         ethaddr_str = strstr(arcs_cmdline, "ethaddr=");
0136         if (!ethaddr_str)
0137             return -1;
0138 
0139         ethaddr_str += strlen("ethaddr=");
0140     }
0141 
0142     str2eaddr(ethernet_addr, ethaddr_str);
0143 
0144     return 0;
0145 }