From ab2579d79529b8ed34f26a374a352f12ce24d5df Mon Sep 17 00:00:00 2001
From: Huacai Chen <chenhuacai@loongson.cn>
Date: Thu, 11 Aug 2022 20:52:12 +0800
Subject: [PATCH] LoongArch: Jump to the link address before enable PG

The kernel entry points of both boot CPU (i.e., kernel_entry) and non-
boot CPUs (i.e., smpboot_entry) may be physical address from BootLoader
(in DA mode or identity-mapping PG mode). So we should jump to the link
address before PG enabled (because DA is disabled at the same time) and
just after DMW configured.

Specifically: With some older firmwares, non-boot CPUs started with PG
enabled, but this need firmware cooperation in the form of a temporary
page table, which is deemed unnecessary. OTOH, latest firmware versions
configure the non-boot CPUs to start in DA mode, so kernel-side changes
are needed.

Reviewed-by: WANG Xuerui <git@xen0n.name>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/kernel/head.S | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index 7062cdf0e33e5..c60eb66793e35 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -21,6 +21,12 @@ SYM_CODE_START(kernel_entry)			# kernel entry point
 	csrwr		t0, LOONGARCH_CSR_DMWIN0
 	li.d		t0, CSR_DMW1_INIT	# CA, PLV0, 0x9000 xxxx xxxx xxxx
 	csrwr		t0, LOONGARCH_CSR_DMWIN1
+
+	/* We might not get launched at the address the kernel is linked to,
+	   so we jump there.  */
+	la.abs		t0, 0f
+	jr		t0
+0:
 	/* Enable PG */
 	li.w		t0, 0xb0		# PLV=0, IE=0, PG=1
 	csrwr		t0, LOONGARCH_CSR_CRMD
@@ -29,11 +35,6 @@ SYM_CODE_START(kernel_entry)			# kernel entry point
 	li.w		t0, 0x00		# FPE=0, SXE=0, ASXE=0, BTE=0
 	csrwr		t0, LOONGARCH_CSR_EUEN
 
-	/* We might not get launched at the address the kernel is linked to,
-	   so we jump there.  */
-	la.abs		t0, 0f
-	jr		t0
-0:
 	la		t0, __bss_start		# clear .bss
 	st.d		zero, t0, 0
 	la		t1, __bss_stop - LONGSIZE
@@ -74,6 +75,11 @@ SYM_CODE_START(smpboot_entry)
 	csrwr		t0, LOONGARCH_CSR_DMWIN0
 	li.d		t0, CSR_DMW1_INIT	# CA, PLV0
 	csrwr		t0, LOONGARCH_CSR_DMWIN1
+
+	la.abs		t0, 0f
+	jr		t0
+0:
+	/* Enable PG */
 	li.w		t0, 0xb0		# PLV=0, IE=0, PG=1
 	csrwr		t0, LOONGARCH_CSR_CRMD
 	li.w		t0, 0x04		# PLV=0, PIE=1, PWE=0
@@ -85,9 +91,6 @@ SYM_CODE_START(smpboot_entry)
 	ld.d		sp, t0, CPU_BOOT_STACK
 	ld.d		tp, t0, CPU_BOOT_TINFO
 
-	la.abs		t0, 0f
-	jr		t0
-0:
 	bl		start_secondary
 SYM_CODE_END(smpboot_entry)
 
-- 
GitLab