1 /* 2 * 3 * BRIEF MODULE DESCRIPTION 4 * PROM library initialisation code, supports YAMON and U-Boot. 5 * 6 * Copyright 2000-2001, 2006, 2008 MontaVista Software Inc. 7 * Author: MontaVista Software, Inc. <source@mvista.com> 8 * 9 * This file was derived from Carsten Langgaard's 10 * arch/mips/mips-boards/xx files. 11 * 12 * Carsten Langgaard, carstenl@mips.com 13 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. 14 * 15 * This program is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License as published by the 17 * Free Software Foundation; either version 2 of the License, or (at your 18 * option) any later version. 19 * 20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * You should have received a copy of the GNU General Public License along 32 * with this program; if not, write to the Free Software Foundation, Inc., 33 * 675 Mass Ave, Cambridge, MA 02139, USA. 34 */ 35 36 #include <linux/init.h> 37 #include <linux/kernel.h> 38 #include <linux/memblock.h> 39 #include <linux/sizes.h> 40 #include <linux/string.h> 41 42 #include <asm/bootinfo.h> 43 44 int prom_argc; 45 char **prom_argv; 46 char **prom_envp; 47 48 void __init prom_init_cmdline(void) 49 { 50 int i; 51 52 for (i = 1; i < prom_argc; i++) { 53 strlcat(arcs_cmdline, prom_argv[i], COMMAND_LINE_SIZE); 54 if (i < (prom_argc - 1)) 55 strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); 56 } 57 } 58 59 char *prom_getenv(char *envname) 60 { 61 /* 62 * Return a pointer to the given environment variable. 63 * YAMON uses "name", "value" pairs, while U-Boot uses "name=value". 64 */ 65 66 char **env = prom_envp; 67 int i = strlen(envname); 68 int yamon = (*env && strchr(*env, '=') == NULL); 69 70 while (*env) { 71 if (yamon) { 72 if (strcmp(envname, *env++) == 0) 73 return *env; 74 } else if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=') 75 return *env + i + 1; 76 env++; 77 } 78 79 return NULL; 80 } 81 82 void __init prom_init(void) 83 { 84 unsigned char *memsize_str; 85 unsigned long memsize; 86 87 prom_argc = (int)fw_arg0; 88 prom_argv = (char **)fw_arg1; 89 prom_envp = (char **)fw_arg2; 90 91 prom_init_cmdline(); 92 93 memsize_str = prom_getenv("memsize"); 94 if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) 95 memsize = SZ_64M; /* minimum memsize is 64MB RAM */ 96 97 memblock_add(0, memsize); 98 } 99 100 static inline unsigned char str2hexnum(unsigned char c) 101 { 102 if (c >= '0' && c <= '9') 103 return c - '0'; 104 if (c >= 'a' && c <= 'f') 105 return c - 'a' + 10; 106 if (c >= 'A' && c <= 'F') 107 return c - 'A' + 10; 108 109 return 0; /* foo */ 110 } 111 112 static inline void str2eaddr(unsigned char *ea, unsigned char *str) 113 { 114 int i; 115 116 for (i = 0; i < 6; i++) { 117 unsigned char num; 118 119 if ((*str == '.') || (*str == ':')) 120 str++; 121 num = str2hexnum(*str++) << 4; 122 num |= str2hexnum(*str++); 123 ea[i] = num; 124 } 125 } 126 127 int __init prom_get_ethernet_addr(char *ethernet_addr) 128 { 129 char *ethaddr_str; 130 131 /* Check the environment variables first */ 132 ethaddr_str = prom_getenv("ethaddr"); 133 if (!ethaddr_str) { 134 /* Check command line */ 135 ethaddr_str = strstr(arcs_cmdline, "ethaddr="); 136 if (!ethaddr_str) 137 return -1; 138 139 ethaddr_str += strlen("ethaddr="); 140 } 141 142 str2eaddr(ethernet_addr, ethaddr_str); 143 144 return 0; 145 } 146