From 3b306f6f3a03c285a7044350d263cb9251def49d Mon Sep 17 00:00:00 2001
From: Palmer Dabbelt <palmer@sifive.com>
Date: Fri, 26 Oct 2018 12:37:43 -0700
Subject: [PATCH 1/4] Revert "RISC-V: Select GENERIC_LIB_UMODDI3 on RV32"

I'm removing the generic 64-bit divide support, which means this will no
longer work.

This reverts commit 757331db921428295948fed5e7377a436e66d34e.

Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
 arch/riscv/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index fe451348ae57..4198759f6798 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -109,7 +109,6 @@ config ARCH_RV32I
 	select GENERIC_LIB_ASHRDI3
 	select GENERIC_LIB_LSHRDI3
 	select GENERIC_LIB_UCMPDI2
-	select GENERIC_LIB_UMODDI3
 
 config ARCH_RV64I
 	bool "RV64I"

From 0ef08ca36a3aafbf0dcce7b3c2c4b6b664ce56bd Mon Sep 17 00:00:00 2001
From: Palmer Dabbelt <palmer@sifive.com>
Date: Fri, 26 Oct 2018 12:38:11 -0700
Subject: [PATCH 2/4] Revert "lib: Add umoddi3 and udivmoddi4 of GCC library
 routines"

We don't want 64-bit divide in the kernel.

This reverts commit 6315730e9eab7de5fa9864bb13a352713f48aef1.

Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
 lib/Kconfig      |   3 -
 lib/Makefile     |   1 -
 lib/udivmoddi4.c | 310 -----------------------------------------------
 lib/umoddi3.c    |  32 -----
 4 files changed, 346 deletions(-)
 delete mode 100644 lib/udivmoddi4.c
 delete mode 100644 lib/umoddi3.c

diff --git a/lib/Kconfig b/lib/Kconfig
index d82f20609939..a3928d4438b5 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -621,6 +621,3 @@ config GENERIC_LIB_CMPDI2
 
 config GENERIC_LIB_UCMPDI2
 	bool
-
-config GENERIC_LIB_UMODDI3
-	bool
diff --git a/lib/Makefile b/lib/Makefile
index 56a8d9c23ef3..423876446810 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -270,4 +270,3 @@ obj-$(CONFIG_GENERIC_LIB_LSHRDI3) += lshrdi3.o
 obj-$(CONFIG_GENERIC_LIB_MULDI3) += muldi3.o
 obj-$(CONFIG_GENERIC_LIB_CMPDI2) += cmpdi2.o
 obj-$(CONFIG_GENERIC_LIB_UCMPDI2) += ucmpdi2.o
-obj-$(CONFIG_GENERIC_LIB_UMODDI3) += umoddi3.o udivmoddi4.o
diff --git a/lib/udivmoddi4.c b/lib/udivmoddi4.c
deleted file mode 100644
index c08bc8a5f1cf..000000000000
--- a/lib/udivmoddi4.c
+++ /dev/null
@@ -1,310 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/*
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.
- */
-
-#include <linux/libgcc.h>
-
-#define count_leading_zeros(COUNT, X)   ((COUNT) = __builtin_clz(X))
-
-#define W_TYPE_SIZE 32
-
-#define __ll_B ((unsigned long) 1 << (W_TYPE_SIZE / 2))
-#define __ll_lowpart(t) ((unsigned long) (t) & (__ll_B - 1))
-#define __ll_highpart(t) ((unsigned long) (t) >> (W_TYPE_SIZE / 2))
-
-/* If we still don't have umul_ppmm, define it using plain C. */
-#if !defined(umul_ppmm)
-#define umul_ppmm(w1, w0, u, v)						\
-	do {								\
-		unsigned long __x0, __x1, __x2, __x3;			\
-		unsigned short __ul, __vl, __uh, __vh;			\
-									\
-		__ul = __ll_lowpart(u);					\
-		__uh = __ll_highpart(u);				\
-		__vl = __ll_lowpart(v);					\
-		__vh = __ll_highpart(v);				\
-									\
-		__x0 = (unsigned long) __ul * __vl;			\
-		__x1 = (unsigned long) __ul * __vh;			\
-		__x2 = (unsigned long) __uh * __vl;			\
-		__x3 = (unsigned long) __uh * __vh;			\
-									\
-		__x1 += __ll_highpart(__x0);				\
-		__x1 += __x2;						\
-		if (__x1 < __x2)					\
-			__x3 += __ll_B;					\
-									\
-		(w1) = __x3 + __ll_highpart(__x1);			\
-		(w0) = __ll_lowpart(__x1) * __ll_B + __ll_lowpart(__x0);\
-	} while (0)
-#endif
-
-#if !defined(sub_ddmmss)
-#define sub_ddmmss(sh, sl, ah, al, bh, bl)				\
-	do {								\
-		unsigned long __x;					\
-		__x = (al) - (bl);					\
-		(sh) = (ah) - (bh) - (__x > (al));			\
-		(sl) = __x;						\
-	} while (0)
-#endif
-
-/* Define this unconditionally, so it can be used for debugging. */
-#define __udiv_qrnnd_c(q, r, n1, n0, d)					\
-	do {								\
-		unsigned long __d1, __d0, __q1, __q0;			\
-		unsigned long __r1, __r0, __m;				\
-		__d1 = __ll_highpart(d);				\
-		__d0 = __ll_lowpart(d);				\
-									\
-		__r1 = (n1) % __d1;					\
-		__q1 = (n1) / __d1;					\
-		__m = (unsigned long) __q1 * __d0;			\
-		__r1 = __r1 * __ll_B | __ll_highpart(n0);		\
-		if (__r1 < __m) {					\
-			__q1--, __r1 += (d);				\
-			if (__r1 >= (d))				\
-				if (__r1 < __m)				\
-					__q1--, __r1 += (d);		\
-		}							\
-		__r1 -= __m;						\
-									\
-		__r0 = __r1 % __d1;					\
-		__q0 = __r1 / __d1;					\
-		__m = (unsigned long) __q0 * __d0;			\
-		__r0 = __r0 * __ll_B | __ll_lowpart(n0);		\
-		if (__r0 < __m) {					\
-			__q0--, __r0 += (d);				\
-			if (__r0 >= (d))				\
-				if (__r0 < __m)				\
-					__q0--, __r0 += (d);		\
-		}							\
-		__r0 -= __m;						\
-									\
-		(q) = (unsigned long) __q1 * __ll_B | __q0;		\
-		(r) = __r0;						\
-	} while (0)
-
-/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
-#if !defined(udiv_qrnnd)
-#define UDIV_NEEDS_NORMALIZATION 1
-#define udiv_qrnnd __udiv_qrnnd_c
-#endif
-
-unsigned long long __udivmoddi4(unsigned long long u, unsigned long long v,
-				unsigned long long *rp)
-{
-	const DWunion nn = {.ll = u };
-	const DWunion dd = {.ll = v };
-	DWunion rr, ww;
-	unsigned long d0, d1, n0, n1, n2;
-	unsigned long q0 = 0, q1 = 0;
-	unsigned long b, bm;
-
-	d0 = dd.s.low;
-	d1 = dd.s.high;
-	n0 = nn.s.low;
-	n1 = nn.s.high;
-
-#if !UDIV_NEEDS_NORMALIZATION
-
-	if (d1 == 0) {
-		if (d0 > n1) {
-			/* 0q = nn / 0D */
-
-			udiv_qrnnd(q0, n0, n1, n0, d0);
-			q1 = 0;
-
-			/* Remainder in n0. */
-		} else {
-			/* qq = NN / 0d */
-
-			if (d0 == 0)
-				/* Divide intentionally by zero. */
-				d0 = 1 / d0;
-
-			udiv_qrnnd(q1, n1, 0, n1, d0);
-			udiv_qrnnd(q0, n0, n1, n0, d0);
-
-			/* Remainder in n0. */
-		}
-
-		if (rp != 0) {
-			rr.s.low = n0;
-			rr.s.high = 0;
-			*rp = rr.ll;
-		}
-
-#else /* UDIV_NEEDS_NORMALIZATION */
-
-	if (d1 == 0) {
-		if (d0 > n1) {
-			/* 0q = nn / 0D */
-
-			count_leading_zeros(bm, d0);
-
-			if (bm != 0) {
-				/*
-				 * Normalize, i.e. make the most significant bit
-				 * of the denominator set.
-				 */
-
-				d0 = d0 << bm;
-				n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
-				n0 = n0 << bm;
-			}
-
-			udiv_qrnnd(q0, n0, n1, n0, d0);
-			q1 = 0;
-
-			/* Remainder in n0 >> bm. */
-		} else {
-			/* qq = NN / 0d */
-
-			if (d0 == 0)
-				/* Divide intentionally by zero. */
-				d0 = 1 / d0;
-
-			count_leading_zeros(bm, d0);
-
-			if (bm == 0) {
-				/*
-				 * From (n1 >= d0) /\ (the most significant bit
-				 * of d0 is set), conclude (the most significant
-				 * bit of n1 is set) /\ (theleading quotient
-				 * digit q1 = 1).
-				 *
-				 * This special case is necessary, not an
-				 * optimization. (Shifts counts of W_TYPE_SIZE
-				 * are undefined.)
-				 */
-
-				n1 -= d0;
-				q1 = 1;
-			} else {
-				/* Normalize. */
-
-				b = W_TYPE_SIZE - bm;
-
-				d0 = d0 << bm;
-				n2 = n1 >> b;
-				n1 = (n1 << bm) | (n0 >> b);
-				n0 = n0 << bm;
-
-				udiv_qrnnd(q1, n1, n2, n1, d0);
-			}
-
-			/* n1 != d0... */
-
-			udiv_qrnnd(q0, n0, n1, n0, d0);
-
-			/* Remainder in n0 >> bm. */
-		}
-
-		if (rp != 0) {
-			rr.s.low = n0 >> bm;
-			rr.s.high = 0;
-			*rp = rr.ll;
-		}
-
-#endif /* UDIV_NEEDS_NORMALIZATION */
-
-	} else {
-		if (d1 > n1) {
-			/* 00 = nn / DD */
-
-			q0 = 0;
-			q1 = 0;
-
-			/* Remainder in n1n0. */
-			if (rp != 0) {
-				rr.s.low = n0;
-				rr.s.high = n1;
-				*rp = rr.ll;
-			}
-		} else {
-			/* 0q = NN / dd */
-
-			count_leading_zeros(bm, d1);
-			if (bm == 0) {
-				/*
-				 * From (n1 >= d1) /\ (the most significant bit
-				 * of d1 is set), conclude (the most significant
-				 * bit of n1 is set) /\ (the quotient digit q0 =
-				 * 0 or 1).
-				 *
-				 * This special case is necessary, not an
-				 * optimization.
-				 */
-
-				/*
-				 * The condition on the next line takes
-				 * advantage of that n1 >= d1 (true due to
-				 * program flow).
-				 */
-				if (n1 > d1 || n0 >= d0) {
-					q0 = 1;
-					sub_ddmmss(n1, n0, n1, n0, d1, d0);
-				} else {
-					q0 = 0;
-				}
-
-				q1 = 0;
-
-				if (rp != 0) {
-					rr.s.low = n0;
-					rr.s.high = n1;
-					*rp = rr.ll;
-				}
-			} else {
-				unsigned long m1, m0;
-				/* Normalize. */
-
-				b = W_TYPE_SIZE - bm;
-
-				d1 = (d1 << bm) | (d0 >> b);
-				d0 = d0 << bm;
-				n2 = n1 >> b;
-				n1 = (n1 << bm) | (n0 >> b);
-				n0 = n0 << bm;
-
-				udiv_qrnnd(q0, n1, n2, n1, d1);
-				umul_ppmm(m1, m0, q0, d0);
-
-				if (m1 > n1 || (m1 == n1 && m0 > n0)) {
-					q0--;
-					sub_ddmmss(m1, m0, m1, m0, d1, d0);
-				}
-
-				q1 = 0;
-
-				/* Remainder in (n1n0 - m1m0) >> bm. */
-				if (rp != 0) {
-					sub_ddmmss(n1, n0, n1, n0, m1, m0);
-					rr.s.low = (n1 << b) | (n0 >> bm);
-					rr.s.high = n1 >> bm;
-					*rp = rr.ll;
-				}
-			}
-		}
-	}
-
-	ww.s.low = q0;
-	ww.s.high = q1;
-
-	return ww.ll;
-}
diff --git a/lib/umoddi3.c b/lib/umoddi3.c
deleted file mode 100644
index d7bbf0f85197..000000000000
--- a/lib/umoddi3.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/*
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.
- */
-
-#include <linux/module.h>
-#include <linux/libgcc.h>
-
-extern unsigned long long __udivmoddi4(unsigned long long u,
-				       unsigned long long v,
-				       unsigned long long *rp);
-
-unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
-{
-	unsigned long long w;
-	(void)__udivmoddi4(u, v, &w);
-	return w;
-}
-EXPORT_SYMBOL(__umoddi3);

From 732e8e4130ffccb618390e0f80a884543e61fd61 Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@suse.de>
Date: Tue, 23 Oct 2018 09:33:47 +0200
Subject: [PATCH 3/4] RISC-V: properly determine hardware caps

On the Hifive-U platform, cpu 0 is a masked cpu with less capabilities
than the other cpus.  Ignore it for the purpose of determining the
hardware capabilities of the system.

Signed-off-by: Andreas Schwab <schwab@suse.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
 arch/riscv/kernel/cpufeature.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 5493f3228704..0339087aa652 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -28,7 +28,7 @@ bool has_fpu __read_mostly;
 
 void riscv_fill_hwcap(void)
 {
-	struct device_node *node;
+	struct device_node *node = NULL;
 	const char *isa;
 	size_t i;
 	static unsigned long isa2hwcap[256] = {0};
@@ -44,9 +44,11 @@ void riscv_fill_hwcap(void)
 
 	/*
 	 * We don't support running Linux on hertergenous ISA systems.  For
-	 * now, we just check the ISA of the first processor.
+	 * now, we just check the ISA of the first "okay" processor.
 	 */
-	node = of_find_node_by_type(NULL, "cpu");
+	while ((node = of_find_node_by_type(node, "cpu")))
+		if (riscv_of_processor_hartid(node) >= 0)
+			break;
 	if (!node) {
 		pr_warning("Unable to find \"cpu\" devicetree entry");
 		return;

From 9b4789eacb654b7bbc806c831bcebd799ae0e2f5 Mon Sep 17 00:00:00 2001
From: Palmer Dabbelt <palmer@sifive.com>
Date: Mon, 25 Jun 2018 13:23:12 -0700
Subject: [PATCH 4/4] Move EM_RISCV into elf-em.h

This should never have been inside our arch port to begin with, it's
just a relic from when we were maintaining out of tree patches.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Paul Walmsley <paul.walmsley@sifive.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Tested-by: David Abdurachmanov <david.abdurachmanov@gmail.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
 arch/riscv/include/asm/elf.h | 3 ---
 include/uapi/linux/elf-em.h  | 1 +
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index a1ef503d616e..697fc23b0d5a 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -16,9 +16,6 @@
 #include <asm/auxvec.h>
 #include <asm/byteorder.h>
 
-/* TODO: Move definition into include/uapi/linux/elf-em.h */
-#define EM_RISCV	0xF3
-
 /*
  * These are used to set parameters in the core dumps.
  */
diff --git a/include/uapi/linux/elf-em.h b/include/uapi/linux/elf-em.h
index 31aa10178335..93722e60204c 100644
--- a/include/uapi/linux/elf-em.h
+++ b/include/uapi/linux/elf-em.h
@@ -41,6 +41,7 @@
 #define EM_TILEPRO	188	/* Tilera TILEPro */
 #define EM_MICROBLAZE	189	/* Xilinx MicroBlaze */
 #define EM_TILEGX	191	/* Tilera TILE-Gx */
+#define EM_RISCV	243	/* RISC-V */
 #define EM_BPF		247	/* Linux BPF - in-kernel virtual machine */
 #define EM_FRV		0x5441	/* Fujitsu FR-V */