/* * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * PROM library initialisation code. */ #include #include #include #include #include #include #include #include #include #ifdef CONFIG_MIPS_AVALANCHE_PSPBOOT #include #endif int prom_argc; char **prom_argv, **prom_envp; int init_debug = 0; /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #include typedef struct _avm_urlader_env { char *Name; char *Value; } t_avm_urlader_env; static t_avm_urlader_env local_envp[MAX_ENV_ENTRY]; /* */ extern int avalanche_mtd_ready; /*------------------------------------------------------------------------------------------*\ get an environment variable from the flash region \*------------------------------------------------------------------------------------------*/ char *prom_getenv(char *search_name) { unsigned int count = 0; t_avm_urlader_env *E = (t_avm_urlader_env *)local_envp; int i; i = strlen(search_name); while(E->Name) { if(strncmp(search_name, E->Name, i) == 0) { return(E->Value); } E++, count++; } return(NULL); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static inline unsigned char str2hexnum(unsigned char c) { if(c >= '0' && c <= '9') return c - '0'; if(c >= 'a' && c <= 'f') return c - 'a' + 10; return 0; /* foo */ } static inline void str2eaddr(unsigned char *ea, unsigned char *str) { int i; for(i = 0; i < 6; i++) { unsigned char num; if((*str == '.') || (*str == ':')) str++; num = str2hexnum(*str++) << 4; num |= (str2hexnum(*str++)); ea[i] = num; } } int get_ethernet_addr(char *ethernet_addr) { char *ethaddr_str; ethaddr_str = prom_getenv("ethaddr"); if (!ethaddr_str) { printk("ethaddr not set in boot prom\n"); return -1; } str2eaddr(ethernet_addr, ethaddr_str); if (init_debug > 1) { int i; printk("get_ethernet_addr: "); for (i=0; i<5; i++) printk("%02x:", (unsigned char)*(ethernet_addr+i)); printk("%02x\n", *(ethernet_addr+i)); } return 0; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int __init prom_init(int argc, char **argv, char **envp) { int i; t_avm_urlader_env *E = (t_avm_urlader_env *)envp; static char local_env_buffer[2 * 1024]; char *p; /* TODO: Do we need to save the args locally also? */ prom_argc = argc; prom_argv = argv; /* Copy what we need locally so we are not dependent on * bootloader RAM. In Adam2, the environment paramters * are in flash but the table that references them is in * RAM. */ /*--- printk("prom_init: max %u entries\n", MAX_ENV_ENTRY); ---*/ for(i = 0, p = local_env_buffer ; i < MAX_ENV_ENTRY ; i++, E++) { if( E->Name ) { int name_len; int val_len; name_len = strlen(E->Name) + 1; val_len = strlen(E->Value) + 1; if(p + name_len + val_len > local_env_buffer + sizeof(local_env_buffer)) { printk("prom_init: local_env_buffer too small for (%s = %s)\n", E->Name, E->Value); local_envp[i].Name = NULL; local_envp[i].Value = NULL; continue; } local_envp[i].Name = p; memcpy(p, E->Name, name_len); p += name_len; local_envp[i].Value = p; memcpy(p, E->Value, val_len); p += val_len; /*--- local_envp[i].name=E->Name; ---*/ /*--- local_envp[i].val = E->Value; ---*/ /*--- printk("prom_init[%u]: %s = %s\n", i, local_envp[i].name, local_envp[i].val); ---*/ } else { local_envp[i].Name = NULL; local_envp[i].Value = NULL; } } /*--- printk("prom_init: done\n"); ---*/ printk("prom_init: local_env_buffer %u used (max %u)\n", (unsigned int)p - (unsigned int)local_env_buffer, sizeof(local_env_buffer)); mips_display_message("LINUX"); /* * Setup the North bridge to do Master byte-lane swapping when * running in bigendian. */ #if defined(CONFIG_MIPS_AVALANCHE_SOC) /*nothing*/ #else #if defined(__MIPSEL__) GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | GT_PCI0_CMD_SBYTESWAP_BIT); #else GT_WRITE(GT_PCI0_CMD_OFS, 0); #endif /* __MIPSEL__ */ #if defined(CONFIG_MIPS_MALTA) set_io_port_base(MALTA_PORT_BASE); #else set_io_port_base(KSEG1); #endif /* CONFIG_MIPS_MALTA */ #endif /* CONFIG_MIPS_AVALANCHE_SOC */ #if defined(CONFIG_MIPS_AVALANCHE_SOC) set_io_port_base(0); #endif /* CONFIG_MIPS_AVALANCHE_SOC */ setup_prom_printf(0); prom_printf("\nLINUX started...\n"); prom_init_cmdline(); prom_meminit(); return 0; }