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