On 5/22/24 17:34, Jiaxun Yang wrote:
Add some common library routines for the architecture.

Signed-off-by: Jiaxun Yang <jiaxun.y...@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.y...@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.y...@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.y...@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.y...@flygoat.com>
+ */
+
+#include <cpu_func.h>
+#include <asm/cache.h>
+#include <asm/loongarch.h>
+
+void invalidate_icache_all(void)
+{
+       asm volatile ("\tibar 0\n"::);

According to
https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_dbar
this is not invalidating the instruction cache.

After loading an image into memory and before executing it we must
invalidate the instruction cache to ensure that the newly loaded code is
executed.

I guess you want to use CACOP here.

+}
+
+__weak void flush_dcache_all(void)

In cmd/cache.c we have another __weak implementation. How is the linke:w
meant to know which one to use?

I guess we need to fix cmd/cache.c. But that is beyond the scope of this
series.

+{
+       asm volatile ("\tdbar 0\n"::);

CACOP?

Best regards

Heinrich

+}
+
+__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.y...@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.y...@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


Reply via email to