#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/memblock.h>
#include <linux/sizes.h>
#include <linux/string.h>
#include <asm/bootinfo.h>
#include <prom.h>
int prom_argc;
char **prom_argv;
char **prom_envp;
void __init prom_init_cmdline(void)
{
int i;
for (i = 1; i < prom_argc; i++) {
strlcat(arcs_cmdline, prom_argv[i], COMMAND_LINE_SIZE);
if (i < (prom_argc - 1))
strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
}
}
char *prom_getenv(char *envname)
{
char **env = prom_envp;
int i = strlen(envname);
int yamon = (*env && strchr(*env, '=') == NULL);
while (*env) {
if (yamon) {
if (strcmp(envname, *env++) == 0)
return *env;
} else if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
return *env + i + 1;
env++;
}
return NULL;
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = (int)fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str || kstrtoul(memsize_str, 0, &memsize))
memsize = SZ_64M;
memblock_add(0, memsize);
}
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;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return 0;
}
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 __init prom_get_ethernet_addr(char *ethernet_addr)
{
char *ethaddr_str;
ethaddr_str = prom_getenv("ethaddr");
if (!ethaddr_str) {
ethaddr_str = strstr(arcs_cmdline, "ethaddr=");
if (!ethaddr_str)
return -1;
ethaddr_str += strlen("ethaddr=");
}
str2eaddr(ethernet_addr, ethaddr_str);
return 0;
}