v4.19.13 snapshot.
diff --git a/arch/mips/fw/lib/Makefile b/arch/mips/fw/lib/Makefile
new file mode 100644
index 0000000..5291505
--- /dev/null
+++ b/arch/mips/fw/lib/Makefile
@@ -0,0 +1,7 @@
+#
+# 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/call_o32.S b/arch/mips/fw/lib/call_o32.S
new file mode 100644
index 0000000..4703fe4
--- /dev/null
+++ b/arch/mips/fw/lib/call_o32.S
@@ -0,0 +1,108 @@
+/*
+ *	O32 interface for the 64 (or N32) ABI.
+ *
+ *	Copyright (C) 2002, 2014  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+/* O32 register size.  */
+#define O32_SZREG	4
+/* Maximum number of arguments supported.  Must be even!  */
+#define O32_ARGC	32
+/* Number of static registers we save.  */
+#define O32_STATC	11
+/* Argument area frame size.  */
+#define O32_ARGSZ	(O32_SZREG * O32_ARGC)
+/* Static register save area frame size.  */
+#define O32_STATSZ	(SZREG * O32_STATC)
+/* Stack pointer register save area frame size.  */
+#define O32_SPSZ	SZREG
+/* Combined area frame size.  */
+#define O32_FRAMESZ	(O32_ARGSZ + O32_SPSZ + O32_STATSZ)
+/* Switched stack frame size.  */
+#define O32_NFRAMESZ	(O32_ARGSZ + O32_SPSZ)
+
+		.text
+
+/*
+ * O32 function call dispatcher, for interfacing 32-bit ROM routines.
+ *
+ * The standard 64 (N32) calling sequence is supported, with a0 holding
+ * a function pointer, a1 a pointer to the new stack to call the
+ * function with or 0 if no stack switching is requested, a2-a7 -- the
+ * function call's first six arguments, and the stack -- the remaining
+ * arguments (up to O32_ARGC, including a2-a7).  Static registers, gp
+ * and fp are preserved, v0 holds the result.  This code relies on the
+ * called o32 function for sp and ra restoration and this dispatcher has
+ * to be placed in a KSEGx (or KUSEG) address space.  Any pointers
+ * passed have to point to addresses within one of these spaces as well.
+ */
+NESTED(call_o32, O32_FRAMESZ, ra)
+		REG_SUBU	sp,O32_FRAMESZ
+
+		REG_S		ra,O32_FRAMESZ-1*SZREG(sp)
+		REG_S		fp,O32_FRAMESZ-2*SZREG(sp)
+		REG_S		gp,O32_FRAMESZ-3*SZREG(sp)
+		REG_S		s7,O32_FRAMESZ-4*SZREG(sp)
+		REG_S		s6,O32_FRAMESZ-5*SZREG(sp)
+		REG_S		s5,O32_FRAMESZ-6*SZREG(sp)
+		REG_S		s4,O32_FRAMESZ-7*SZREG(sp)
+		REG_S		s3,O32_FRAMESZ-8*SZREG(sp)
+		REG_S		s2,O32_FRAMESZ-9*SZREG(sp)
+		REG_S		s1,O32_FRAMESZ-10*SZREG(sp)
+		REG_S		s0,O32_FRAMESZ-11*SZREG(sp)
+
+		move		jp,a0
+
+		move		fp,sp
+		beqz		a1,0f
+		REG_SUBU	fp,a1,O32_NFRAMESZ
+0:
+		REG_S		sp,O32_NFRAMESZ-1*SZREG(fp)
+
+		sll		a0,a2,zero
+		sll		a1,a3,zero
+		sll		a2,a4,zero
+		sll		a3,a5,zero
+		sw		a6,4*O32_SZREG(fp)
+		sw		a7,5*O32_SZREG(fp)
+
+		PTR_LA		t0,O32_FRAMESZ(sp)
+		PTR_LA		t1,6*O32_SZREG(fp)
+		li		t2,O32_ARGC-6
+1:
+		lw		t3,(t0)
+		REG_ADDU	t0,SZREG
+		sw		t3,(t1)
+		REG_SUBU	t2,1
+		REG_ADDU	t1,O32_SZREG
+		bnez		t2,1b
+
+		move		sp,fp
+
+		jalr		jp
+
+		REG_L		sp,O32_NFRAMESZ-1*SZREG(sp)
+
+		REG_L		s0,O32_FRAMESZ-11*SZREG(sp)
+		REG_L		s1,O32_FRAMESZ-10*SZREG(sp)
+		REG_L		s2,O32_FRAMESZ-9*SZREG(sp)
+		REG_L		s3,O32_FRAMESZ-8*SZREG(sp)
+		REG_L		s4,O32_FRAMESZ-7*SZREG(sp)
+		REG_L		s5,O32_FRAMESZ-6*SZREG(sp)
+		REG_L		s6,O32_FRAMESZ-5*SZREG(sp)
+		REG_L		s7,O32_FRAMESZ-4*SZREG(sp)
+		REG_L		gp,O32_FRAMESZ-3*SZREG(sp)
+		REG_L		fp,O32_FRAMESZ-2*SZREG(sp)
+		REG_L		ra,O32_FRAMESZ-1*SZREG(sp)
+
+		REG_ADDU	sp,O32_FRAMESZ
+		jr		ra
+END(call_o32)
diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c
new file mode 100644
index 0000000..6ecda64
--- /dev/null
+++ b/arch/mips/fw/lib/cmdline.c
@@ -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) + i + 1;
+					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;
+	int tmp;
+
+	str = fw_getenv(envname);
+	if (str) {
+		tmp = kstrtoul(str, 0, &envl);
+		if (tmp)
+			envl = 0;
+	}
+
+	return envl;
+}