1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * cmdline.c: Kernel command line creation using ARCS argc/argv.
7 *
8 * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
9 */
10#include <linux/bug.h>
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/string.h>
14
15#include <asm/sgialib.h>
16#include <asm/bootinfo.h>
17
18#undef DEBUG_CMDLINE
19
20/*
21 * A 32-bit ARC PROM pass arguments and environment as 32-bit pointer.
22 * These macro take care of sign extension.
23 */
24#define prom_argv(index) ((char *) (long)argv[(index)])
25
26static char *ignored[] = {
27	"ConsoleIn=",
28	"ConsoleOut=",
29	"SystemPartition=",
30	"OSLoader=",
31	"OSLoadPartition=",
32	"OSLoadFilename=",
33	"OSLoadOptions="
34};
35
36static char *used_arc[][2] = {
37	{ "OSLoadPartition=", "root=" },
38	{ "OSLoadOptions=", "" }
39};
40
41static char __init *move_firmware_args(int argc, LONG *argv, char *cp)
42{
43	char *s;
44	int actr, i;
45
46	actr = 1; /* Always ignore argv[0] */
47
48	while (actr < argc) {
49		for(i = 0; i < ARRAY_SIZE(used_arc); i++) {
50			int len = strlen(used_arc[i][0]);
51
52			if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
53			/* Ok, we want it. First append the replacement... */
54				strcat(cp, used_arc[i][1]);
55				cp += strlen(used_arc[i][1]);
56				/* ... and now the argument */
57				s = strchr(prom_argv(actr), '=');
58				if (s) {
59					s++;
60					strcpy(cp, s);
61					cp += strlen(s);
62				}
63				*cp++ = ' ';
64				break;
65			}
66		}
67		actr++;
68	}
69
70	return cp;
71}
72
73void __init prom_init_cmdline(int argc, LONG *argv)
74{
75	char *cp;
76	int actr, i;
77
78	actr = 1; /* Always ignore argv[0] */
79
80	cp = arcs_cmdline;
81	/*
82	 * Move ARC variables to the beginning to make sure they can be
83	 * overridden by later arguments.
84	 */
85	cp = move_firmware_args(argc, argv, cp);
86
87	while (actr < argc) {
88		for (i = 0; i < ARRAY_SIZE(ignored); i++) {
89			int len = strlen(ignored[i]);
90
91			if (!strncmp(prom_argv(actr), ignored[i], len))
92				goto pic_cont;
93		}
94		/* Ok, we want it. */
95		strcpy(cp, prom_argv(actr));
96		cp += strlen(prom_argv(actr));
97		*cp++ = ' ';
98
99	pic_cont:
100		actr++;
101	}
102
103	if (cp != arcs_cmdline)		/* get rid of trailing space */
104		--cp;
105	*cp = '\0';
106
107#ifdef DEBUG_CMDLINE
108	printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline);
109#endif
110}
111