MIPS: FW: Add environment variable processing.
authorSteven J. Hill <Steven.Hill@imgtec.com>
Mon, 25 Mar 2013 19:32:15 +0000 (14:32 -0500)
committerRalf Baechle <ralf@linux-mips.org>
Wed, 8 May 2013 10:30:09 +0000 (12:30 +0200)
Add parsing of the environment and command line variables passed to
the kernel to the firmware library.

Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
arch/mips/fw/lib/Makefile
arch/mips/fw/lib/cmdline.c [new file with mode: 0644]
arch/mips/include/asm/fw/fw.h [new file with mode: 0644]

index 84befc9..5291505 100644 (file)
@@ -2,4 +2,6 @@
 # Makefile for generic prom monitor library routines under Linux.
 #
 
+lib-y                  += cmdline.o
+
 lib-$(CONFIG_64BIT)    += call_o32.o
diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c
new file mode 100644 (file)
index 0000000..ffd0345
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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;
+}
diff --git a/arch/mips/include/asm/fw/fw.h b/arch/mips/include/asm/fw/fw.h
new file mode 100644 (file)
index 0000000..d6c50a7
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+#ifndef __ASM_FW_H_
+#define __ASM_FW_H_
+
+#include <asm/bootinfo.h>      /* For cleaner code... */
+
+enum fw_memtypes {
+       fw_dontuse,
+       fw_code,
+       fw_free,
+};
+
+typedef struct {
+       unsigned long base;     /* Within KSEG0 */
+       unsigned int size;      /* bytes */
+       enum fw_memtypes type;  /* fw_memtypes */
+} fw_memblock_t;
+
+/* Maximum number of memory block descriptors. */
+#define FW_MAX_MEMBLOCKS       32
+
+extern int fw_argc;
+extern int *_fw_argv;
+extern int *_fw_envp;
+
+/*
+ * Most firmware like YAMON, PMON, etc. pass arguments and environment
+ * variables as 32-bit pointers. These take care of sign extension.
+ */
+#define fw_argv(index)         ((char *)(long)_fw_argv[(index)])
+#define fw_envp(index)         ((char *)(long)_fw_envp[(index)])
+
+extern void fw_init_cmdline(void);
+extern char *fw_getcmdline(void);
+extern fw_memblock_t *fw_getmdesc(void);
+extern void fw_meminit(void);
+extern char *fw_getenv(char *name);
+extern unsigned long fw_getenvl(char *name);
+extern void fw_init_early_console(char port);
+
+#endif /* __ASM_FW_H_ */