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 * cmdline.c: Kernel command line creation using ARCS argc/argv.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci#include <linux/bug.h>
1162306a36Sopenharmony_ci#include <linux/init.h>
1262306a36Sopenharmony_ci#include <linux/kernel.h>
1362306a36Sopenharmony_ci#include <linux/string.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <asm/sgialib.h>
1662306a36Sopenharmony_ci#include <asm/bootinfo.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#undef DEBUG_CMDLINE
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/*
2162306a36Sopenharmony_ci * A 32-bit ARC PROM pass arguments and environment as 32-bit pointer.
2262306a36Sopenharmony_ci * These macro take care of sign extension.
2362306a36Sopenharmony_ci */
2462306a36Sopenharmony_ci#define prom_argv(index) ((char *) (long)argv[(index)])
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistatic char *ignored[] = {
2762306a36Sopenharmony_ci	"ConsoleIn=",
2862306a36Sopenharmony_ci	"ConsoleOut=",
2962306a36Sopenharmony_ci	"SystemPartition=",
3062306a36Sopenharmony_ci	"OSLoader=",
3162306a36Sopenharmony_ci	"OSLoadPartition=",
3262306a36Sopenharmony_ci	"OSLoadFilename=",
3362306a36Sopenharmony_ci	"OSLoadOptions="
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistatic char *used_arc[][2] = {
3762306a36Sopenharmony_ci	{ "OSLoadPartition=", "root=" },
3862306a36Sopenharmony_ci	{ "OSLoadOptions=", "" }
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic char __init *move_firmware_args(int argc, LONG *argv, char *cp)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	char *s;
4462306a36Sopenharmony_ci	int actr, i;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	actr = 1; /* Always ignore argv[0] */
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	while (actr < argc) {
4962306a36Sopenharmony_ci		for(i = 0; i < ARRAY_SIZE(used_arc); i++) {
5062306a36Sopenharmony_ci			int len = strlen(used_arc[i][0]);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci			if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
5362306a36Sopenharmony_ci			/* Ok, we want it. First append the replacement... */
5462306a36Sopenharmony_ci				strcat(cp, used_arc[i][1]);
5562306a36Sopenharmony_ci				cp += strlen(used_arc[i][1]);
5662306a36Sopenharmony_ci				/* ... and now the argument */
5762306a36Sopenharmony_ci				s = strchr(prom_argv(actr), '=');
5862306a36Sopenharmony_ci				if (s) {
5962306a36Sopenharmony_ci					s++;
6062306a36Sopenharmony_ci					strcpy(cp, s);
6162306a36Sopenharmony_ci					cp += strlen(s);
6262306a36Sopenharmony_ci				}
6362306a36Sopenharmony_ci				*cp++ = ' ';
6462306a36Sopenharmony_ci				break;
6562306a36Sopenharmony_ci			}
6662306a36Sopenharmony_ci		}
6762306a36Sopenharmony_ci		actr++;
6862306a36Sopenharmony_ci	}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	return cp;
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_civoid __init prom_init_cmdline(int argc, LONG *argv)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	char *cp;
7662306a36Sopenharmony_ci	int actr, i;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	actr = 1; /* Always ignore argv[0] */
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	cp = arcs_cmdline;
8162306a36Sopenharmony_ci	/*
8262306a36Sopenharmony_ci	 * Move ARC variables to the beginning to make sure they can be
8362306a36Sopenharmony_ci	 * overridden by later arguments.
8462306a36Sopenharmony_ci	 */
8562306a36Sopenharmony_ci	cp = move_firmware_args(argc, argv, cp);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	while (actr < argc) {
8862306a36Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(ignored); i++) {
8962306a36Sopenharmony_ci			int len = strlen(ignored[i]);
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci			if (!strncmp(prom_argv(actr), ignored[i], len))
9262306a36Sopenharmony_ci				goto pic_cont;
9362306a36Sopenharmony_ci		}
9462306a36Sopenharmony_ci		/* Ok, we want it. */
9562306a36Sopenharmony_ci		strcpy(cp, prom_argv(actr));
9662306a36Sopenharmony_ci		cp += strlen(prom_argv(actr));
9762306a36Sopenharmony_ci		*cp++ = ' ';
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	pic_cont:
10062306a36Sopenharmony_ci		actr++;
10162306a36Sopenharmony_ci	}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	if (cp != arcs_cmdline)		/* get rid of trailing space */
10462306a36Sopenharmony_ci		--cp;
10562306a36Sopenharmony_ci	*cp = '\0';
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci#ifdef DEBUG_CMDLINE
10862306a36Sopenharmony_ci	printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline);
10962306a36Sopenharmony_ci#endif
11062306a36Sopenharmony_ci}
111