[PATCH 07/16] LoongArch: lib: General routines
Jiaxun Yang
jiaxun.yang at flygoat.com
Wed May 22 17:34:50 CEST 2024
Add some common library routines for the architecture.
Signed-off-by: Jiaxun Yang <jiaxun.yang at flygoat.com>
---
arch/loongarch/lib/Makefile | 7 ++++
arch/loongarch/lib/asm-offsets.c | 66 ++++++++++++++++++++++++++++++++++++
arch/loongarch/lib/boot.c | 14 ++++++++
arch/loongarch/lib/cache.c | 73 ++++++++++++++++++++++++++++++++++++++++
arch/loongarch/lib/reset.c | 14 ++++++++
arch/loongarch/lib/setjmp.S | 52 ++++++++++++++++++++++++++++
6 files changed, 226 insertions(+)
diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
index 3dbed94cc624..3c17b9cd85af 100644
--- a/arch/loongarch/lib/Makefile
+++ b/arch/loongarch/lib/Makefile
@@ -3,3 +3,10 @@
# Copyright (C) 2024 Jiaxun yang <jiaxun.yang at flygoat.com>
#
+obj-$(CONFIG_CMD_GO) += boot.o
+obj-y += cache.o
+obj-y += interrupts.o
+ifeq ($(CONFIG_$(SPL_)SYSRESET),)
+obj-y += reset.o
+endif
+obj-y += setjmp.o
diff --git a/arch/loongarch/lib/asm-offsets.c b/arch/loongarch/lib/asm-offsets.c
new file mode 100644
index 000000000000..e3f4c629b63d
--- /dev/null
+++ b/arch/loongarch/lib/asm-offsets.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Jiaxun Yang <jiaxun.yang at flygoat.com>
+ *
+ * From arch/x86/lib/asm-offsets.c
+ *
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ */
+
+#include <asm/global_data.h>
+#include <asm/ptrace.h>
+#include <linux/kbuild.h>
+
+static void __used output_ptreg_defines(void)
+{
+ COMMENT("LoongArch pt_regs offsets.");
+ OFFSET(PT_R0, pt_regs, regs[0]);
+ OFFSET(PT_R1, pt_regs, regs[1]);
+ OFFSET(PT_R2, pt_regs, regs[2]);
+ OFFSET(PT_R3, pt_regs, regs[3]);
+ OFFSET(PT_R4, pt_regs, regs[4]);
+ OFFSET(PT_R5, pt_regs, regs[5]);
+ OFFSET(PT_R6, pt_regs, regs[6]);
+ OFFSET(PT_R7, pt_regs, regs[7]);
+ OFFSET(PT_R8, pt_regs, regs[8]);
+ OFFSET(PT_R9, pt_regs, regs[9]);
+ OFFSET(PT_R10, pt_regs, regs[10]);
+ OFFSET(PT_R11, pt_regs, regs[11]);
+ OFFSET(PT_R12, pt_regs, regs[12]);
+ OFFSET(PT_R13, pt_regs, regs[13]);
+ OFFSET(PT_R14, pt_regs, regs[14]);
+ OFFSET(PT_R15, pt_regs, regs[15]);
+ OFFSET(PT_R16, pt_regs, regs[16]);
+ OFFSET(PT_R17, pt_regs, regs[17]);
+ OFFSET(PT_R18, pt_regs, regs[18]);
+ OFFSET(PT_R19, pt_regs, regs[19]);
+ OFFSET(PT_R20, pt_regs, regs[20]);
+ OFFSET(PT_R21, pt_regs, regs[21]);
+ OFFSET(PT_R22, pt_regs, regs[22]);
+ OFFSET(PT_R23, pt_regs, regs[23]);
+ OFFSET(PT_R24, pt_regs, regs[24]);
+ OFFSET(PT_R25, pt_regs, regs[25]);
+ OFFSET(PT_R26, pt_regs, regs[26]);
+ OFFSET(PT_R27, pt_regs, regs[27]);
+ OFFSET(PT_R28, pt_regs, regs[28]);
+ OFFSET(PT_R29, pt_regs, regs[29]);
+ OFFSET(PT_R30, pt_regs, regs[30]);
+ OFFSET(PT_R31, pt_regs, regs[31]);
+ OFFSET(PT_CRMD, pt_regs, csr_crmd);
+ OFFSET(PT_PRMD, pt_regs, csr_prmd);
+ OFFSET(PT_EUEN, pt_regs, csr_euen);
+ OFFSET(PT_ECFG, pt_regs, csr_ecfg);
+ OFFSET(PT_ESTAT, pt_regs, csr_estat);
+ OFFSET(PT_ERA, pt_regs, csr_era);
+ OFFSET(PT_BVADDR, pt_regs, csr_badvaddr);
+ OFFSET(PT_ORIG_A0, pt_regs, orig_a0);
+ DEFINE(PT_SIZE, sizeof(struct pt_regs));
+ BLANK();
+}
+
+int main(void)
+{
+ output_ptreg_defines();
+ return 0;
+}
diff --git a/arch/loongarch/lib/boot.c b/arch/loongarch/lib/boot.c
new file mode 100644
index 000000000000..327be16bb59f
--- /dev/null
+++ b/arch/loongarch/lib/boot.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Jiaxun Yang <jiaxun.yang at flygoat.com>
+ */
+
+#include <asm/u-boot.h>
+
+unsigned long do_go_exec(ulong (*entry)(int, char * const []),
+ int argc, char *const argv[])
+{
+ cleanup_before_linux();
+
+ return entry(argc, argv);
+}
diff --git a/arch/loongarch/lib/cache.c b/arch/loongarch/lib/cache.c
new file mode 100644
index 000000000000..54566edef8a3
--- /dev/null
+++ b/arch/loongarch/lib/cache.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Jiaxun Yang <jiaxun.yang at flygoat.com>
+ */
+
+#include <cpu_func.h>
+#include <asm/cache.h>
+#include <asm/loongarch.h>
+
+void invalidate_icache_all(void)
+{
+ asm volatile ("\tibar 0\n"::);
+}
+
+__weak void flush_dcache_all(void)
+{
+ asm volatile ("\tdbar 0\n"::);
+}
+
+__weak void flush_dcache_range(unsigned long start, unsigned long end)
+{
+ /* Placeholder */
+ flush_dcache_all();
+}
+
+__weak void invalidate_icache_range(unsigned long start, unsigned long end)
+{
+ /* LoongArch mandatory hardware I-Cache coherence */
+ invalidate_icache_all();
+}
+
+__weak void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+ /* Placeholder */
+ flush_dcache_all();
+}
+
+__weak void cache_flush(void)
+{
+ /* Placeholder */
+ flush_dcache_all();
+}
+
+__weak void cache_invalidate(void)
+{
+ /* Placeholder */
+ flush_dcache_all();
+}
+
+__weak void flush_cache(unsigned long addr, unsigned long size)
+{
+ cache_flush();
+}
+
+__weak void dcache_enable(void)
+{
+}
+
+__weak void dcache_disable(void)
+{
+}
+
+__weak int dcache_status(void)
+{
+ return 0;
+}
+
+__weak void enable_caches(void)
+{
+ cache_invalidate();
+ /* Enable cache for direct address translation mode */
+ csr_xchg64(1 << CSR_CRMD_DACM_SHIFT, CSR_CRMD_DACM, LOONGARCH_CSR_CRMD);
+}
diff --git a/arch/loongarch/lib/reset.c b/arch/loongarch/lib/reset.c
new file mode 100644
index 000000000000..ddf29ee41d95
--- /dev/null
+++ b/arch/loongarch/lib/reset.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Jiaxun Yang <jiaxun.yang at flygoat.com>
+ */
+
+#include <command.h>
+#include <cpu_func.h>
+
+int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ reset_cpu();
+
+ return 0;
+}
diff --git a/arch/loongarch/lib/setjmp.S b/arch/loongarch/lib/setjmp.S
new file mode 100644
index 000000000000..12981d0013fa
--- /dev/null
+++ b/arch/loongarch/lib/setjmp.S
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2024 Jiaxun Yang <jiaxun.yang at flygoat.com>
+ */
+
+#include <config.h>
+#include <asm/asm.h>
+#include <linux/linkage.h>
+
+.pushsection .text.setjmp, "ax"
+ENTRY(setjmp)
+ LONG_S s0, a0, 0
+ LONG_S s1, a0, (1 * LONGSIZE)
+ LONG_S s2, a0, (2 * LONGSIZE)
+ LONG_S s3, a0, (3 * LONGSIZE)
+ LONG_S s4, a0, (4 * LONGSIZE)
+ LONG_S s5, a0, (5 * LONGSIZE)
+ LONG_S s6, a0, (6 * LONGSIZE)
+ LONG_S s7, a0, (7 * LONGSIZE)
+ LONG_S s8, a0, (8 * LONGSIZE)
+ LONG_S fp, a0, (9 * LONGSIZE)
+ LONG_S sp, a0, (10 * LONGSIZE)
+ LONG_S ra, a0, (11 * LONGSIZE)
+
+ move a0, zero
+ ret
+ENDPROC(setjmp)
+.popsection
+
+.pushsection .text.longjmp, "ax"
+ENTRY(longjmp)
+ LONG_L s0, a0, 0
+ LONG_L s1, a0, (1 * LONGSIZE)
+ LONG_L s2, a0, (2 * LONGSIZE)
+ LONG_L s3, a0, (3 * LONGSIZE)
+ LONG_L s4, a0, (4 * LONGSIZE)
+ LONG_L s5, a0, (5 * LONGSIZE)
+ LONG_L s6, a0, (6 * LONGSIZE)
+ LONG_L s7, a0, (7 * LONGSIZE)
+ LONG_L s8, a0, (8 * LONGSIZE)
+ LONG_L fp, a0, (9 * LONGSIZE)
+ LONG_L sp, a0, (10 * LONGSIZE)
+ LONG_L ra, a0, (11 * LONGSIZE)
+
+ /* Move the return value in place, but return 1 if passed 0. */
+ li.w a0, 1
+ beqz a1, 1f
+ move a0, a1
+1:
+ jr ra
+ENDPROC(longjmp)
+.popsection
--
2.43.0
More information about the U-Boot
mailing list