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