162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
362306a36Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
462306a36Sopenharmony_ci * for more details.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#include <linux/init.h>
962306a36Sopenharmony_ci#include <linux/kernel.h>
1062306a36Sopenharmony_ci#include <linux/string.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <asm/addrspace.h>
1362306a36Sopenharmony_ci#include <asm/fw/fw.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ciint fw_argc;
1662306a36Sopenharmony_ciint *_fw_argv;
1762306a36Sopenharmony_ciint *_fw_envp;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#ifndef CONFIG_HAVE_PLAT_FW_INIT_CMDLINE
2062306a36Sopenharmony_civoid __init fw_init_cmdline(void)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	int i;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	/* Validate command line parameters. */
2562306a36Sopenharmony_ci	if ((fw_arg0 >= CKSEG0) || (fw_arg1 < CKSEG0)) {
2662306a36Sopenharmony_ci		fw_argc = 0;
2762306a36Sopenharmony_ci		_fw_argv = NULL;
2862306a36Sopenharmony_ci	} else {
2962306a36Sopenharmony_ci		fw_argc = (fw_arg0 & 0x0000ffff);
3062306a36Sopenharmony_ci		_fw_argv = (int *)fw_arg1;
3162306a36Sopenharmony_ci	}
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	/* Validate environment pointer. */
3462306a36Sopenharmony_ci	if (fw_arg2 < CKSEG0)
3562306a36Sopenharmony_ci		_fw_envp = NULL;
3662306a36Sopenharmony_ci	else
3762306a36Sopenharmony_ci		_fw_envp = (int *)fw_arg2;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	for (i = 1; i < fw_argc; i++) {
4062306a36Sopenharmony_ci		strlcat(arcs_cmdline, fw_argv(i), COMMAND_LINE_SIZE);
4162306a36Sopenharmony_ci		if (i < (fw_argc - 1))
4262306a36Sopenharmony_ci			strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
4362306a36Sopenharmony_ci	}
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci#endif
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cichar * __init fw_getcmdline(void)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	return &(arcs_cmdline[0]);
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cichar *fw_getenv(char *envname)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	char *result = NULL;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	if (_fw_envp != NULL && fw_envp(0) != NULL) {
5762306a36Sopenharmony_ci		/*
5862306a36Sopenharmony_ci		 * Return a pointer to the given environment variable.
5962306a36Sopenharmony_ci		 * YAMON uses "name", "value" pairs, while U-Boot uses
6062306a36Sopenharmony_ci		 * "name=value".
6162306a36Sopenharmony_ci		 */
6262306a36Sopenharmony_ci		int i, yamon, index = 0;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci		yamon = (strchr(fw_envp(index), '=') == NULL);
6562306a36Sopenharmony_ci		i = strlen(envname);
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci		while (fw_envp(index)) {
6862306a36Sopenharmony_ci			if (strncmp(envname, fw_envp(index), i) == 0) {
6962306a36Sopenharmony_ci				if (yamon) {
7062306a36Sopenharmony_ci					result = fw_envp(index + 1);
7162306a36Sopenharmony_ci					break;
7262306a36Sopenharmony_ci				} else if (fw_envp(index)[i] == '=') {
7362306a36Sopenharmony_ci					result = fw_envp(index) + i + 1;
7462306a36Sopenharmony_ci					break;
7562306a36Sopenharmony_ci				}
7662306a36Sopenharmony_ci			}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci			/* Increment array index. */
7962306a36Sopenharmony_ci			if (yamon)
8062306a36Sopenharmony_ci				index += 2;
8162306a36Sopenharmony_ci			else
8262306a36Sopenharmony_ci				index += 1;
8362306a36Sopenharmony_ci		}
8462306a36Sopenharmony_ci	}
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	return result;
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ciunsigned long fw_getenvl(char *envname)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	unsigned long envl = 0UL;
9262306a36Sopenharmony_ci	char *str;
9362306a36Sopenharmony_ci	int tmp;
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	str = fw_getenv(envname);
9662306a36Sopenharmony_ci	if (str) {
9762306a36Sopenharmony_ci		tmp = kstrtoul(str, 0, &envl);
9862306a36Sopenharmony_ci		if (tmp)
9962306a36Sopenharmony_ci			envl = 0;
10062306a36Sopenharmony_ci	}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	return envl;
10362306a36Sopenharmony_ci}
104