/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>

#include <asm/addrspace.h>
#include <asm/fw/fw.h>

int fw_argc;
int *_fw_argv;
int *_fw_envp;

void __init fw_init_cmdline(void)
{
	int i;

	/* Validate command line parameters. */
	if ((fw_arg0 >= CKSEG0) || (fw_arg1 < CKSEG0)) {
		fw_argc = 0;
		_fw_argv = NULL;
	} else {
		fw_argc = (fw_arg0 & 0x0000ffff);
		_fw_argv = (int *)fw_arg1;
	}

	/* Validate environment pointer. */
	if (fw_arg2 < CKSEG0)
		_fw_envp = NULL;
	else
		_fw_envp = (int *)fw_arg2;

	for (i = 1; i < fw_argc; i++) {
		strlcat(arcs_cmdline, fw_argv(i), COMMAND_LINE_SIZE);
		if (i < (fw_argc - 1))
			strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
	}
}

char * __init fw_getcmdline(void)
{
	return &(arcs_cmdline[0]);
}

char *fw_getenv(char *envname)
{
	char *result = NULL;

	if (_fw_envp != NULL) {
		/*
		 * Return a pointer to the given environment variable.
		 * YAMON uses "name", "value" pairs, while U-Boot uses
		 * "name=value".
		 */
		int i, yamon, index = 0;

		yamon = (strchr(fw_envp(index), '=') == NULL);
		i = strlen(envname);

		while (fw_envp(index)) {
			if (strncmp(envname, fw_envp(index), i) == 0) {
				if (yamon) {
					result = fw_envp(index + 1);
					break;
				} else if (fw_envp(index)[i] == '=') {
					result = (fw_envp(index + 1) + i);
					break;
				}
			}

			/* Increment array index. */
			if (yamon)
				index += 2;
			else
				index += 1;
		}
	}

	return result;
}

unsigned long fw_getenvl(char *envname)
{
	unsigned long envl = 0UL;
	char *str;
	long val;
	int tmp;

	str = fw_getenv(envname);
	if (str) {
		tmp = kstrtol(str, 0, &val);
		envl = (unsigned long)val;
	}

	return envl;
}
