[klibc] [klibc:master] Add LoongArch64 port

klibc-bot for Feiyang Chen chenfeiyang at loongson.cn
Sat Mar 4 16:30:06 PST 2023


Commit-ID:  53ce949578446360c4b636a46eadfdb7aed2779d
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=53ce949578446360c4b636a46eadfdb7aed2779d
Author:     Feiyang Chen <chenfeiyang at loongson.cn>
AuthorDate: Mon, 20 Feb 2023 10:46:02 +0800
Committer:  Ben Hutchings <ben at decadent.org.uk>
CommitDate: Fri, 3 Mar 2023 21:13:27 +0100

[klibc] Add LoongArch64 port

Add LoongArch64 support. I've cribbed most of this from the
RISC-V and MIPS ports.

Signed-off-by: Feiyang Chen <chenfeiyang at loongson.cn>
Signed-off-by: Ben Hutchings <ben at decadent.org.uk>

---
 .../{riscv64 => loongarch64}/klibc/archconfig.h    |  2 +-
 .../{riscv64 => loongarch64}/klibc/archsetjmp.h    | 11 +++--
 .../arch/{ppc => loongarch64}/klibc/archsignal.h   |  2 +-
 .../arch/{riscv64 => loongarch64}/machine/asm.h    |  4 +-
 usr/klibc/SYSCALLS.def                             |  2 +-
 usr/klibc/arch/loongarch64/Kbuild                  |  7 +++
 usr/klibc/arch/{sparc64 => loongarch64}/MCONFIG    | 17 ++++----
 usr/klibc/arch/{riscv64 => loongarch64}/crt0.S     | 14 +++---
 usr/klibc/arch/loongarch64/setjmp.S                | 50 ++++++++++++++++++++++
 usr/klibc/arch/loongarch64/syscall.S               | 13 ++++++
 usr/klibc/arch/{riscv64 => loongarch64}/sysstub.ph | 10 ++---
 11 files changed, 97 insertions(+), 35 deletions(-)

diff --git a/usr/include/arch/riscv64/klibc/archconfig.h b/usr/include/arch/loongarch64/klibc/archconfig.h
similarity index 84%
copy from usr/include/arch/riscv64/klibc/archconfig.h
copy to usr/include/arch/loongarch64/klibc/archconfig.h
index e85a69c0..7a47b915 100644
--- a/usr/include/arch/riscv64/klibc/archconfig.h
+++ b/usr/include/arch/loongarch64/klibc/archconfig.h
@@ -1,5 +1,5 @@
 /*
- * include/arch/riscv64/klibc/archconfig.h
+ * include/arch/loongarch64/klibc/archconfig.h
  *
  * See include/klibc/sysconfig.h for the options that can be set in
  * this file.
diff --git a/usr/include/arch/riscv64/klibc/archsetjmp.h b/usr/include/arch/loongarch64/klibc/archsetjmp.h
similarity index 73%
copy from usr/include/arch/riscv64/klibc/archsetjmp.h
copy to usr/include/arch/loongarch64/klibc/archsetjmp.h
index 97d6b6be..939c0f5f 100644
--- a/usr/include/arch/riscv64/klibc/archsetjmp.h
+++ b/usr/include/arch/loongarch64/klibc/archsetjmp.h
@@ -1,12 +1,15 @@
 /*
- * arch/riscv64/include/klibc/archsetjmp.h
+ * include/arch/loongarch64/klibc/archsetjmp.h
  */
 
 #ifndef _KLIBC_ARCHSETJMP_H
 #define _KLIBC_ARCHSETJMP_H
 
 struct __jmp_buf {
-	unsigned long __pc;
+	unsigned long __ra;
+	unsigned long __sp;
+	unsigned long __r21;
+	unsigned long __fp;
 	unsigned long __s0;
 	unsigned long __s1;
 	unsigned long __s2;
@@ -16,10 +19,6 @@ struct __jmp_buf {
 	unsigned long __s6;
 	unsigned long __s7;
 	unsigned long __s8;
-	unsigned long __s9;
-	unsigned long __s10;
-	unsigned long __s11;
-	unsigned long __sp;
 };
 
 typedef struct __jmp_buf jmp_buf[1];
diff --git a/usr/include/arch/ppc/klibc/archsignal.h b/usr/include/arch/loongarch64/klibc/archsignal.h
similarity index 80%
copy from usr/include/arch/ppc/klibc/archsignal.h
copy to usr/include/arch/loongarch64/klibc/archsignal.h
index 9c3ac927..c22a5d7c 100644
--- a/usr/include/arch/ppc/klibc/archsignal.h
+++ b/usr/include/arch/loongarch64/klibc/archsignal.h
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/include/klibc/archsignal.h
+ * include/arch/loongarch64/klibc/archsignal.h
  *
  * Architecture-specific signal definitions
  *
diff --git a/usr/include/arch/riscv64/machine/asm.h b/usr/include/arch/loongarch64/machine/asm.h
similarity index 86%
copy from usr/include/arch/riscv64/machine/asm.h
copy to usr/include/arch/loongarch64/machine/asm.h
index 9effc935..6fe5dba2 100644
--- a/usr/include/arch/riscv64/machine/asm.h
+++ b/usr/include/arch/loongarch64/machine/asm.h
@@ -1,7 +1,5 @@
 /*
- * arch/riscv64/include/machine/asm.h
- *
- * Mostly cribbed from mips.
+ * include/arch/loongarch64/machine/asm.h
  */
 
 #ifndef _MACHINE_ASM_H
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index 660efc66..9b6b1127 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -21,7 +21,7 @@ void _exit,exit::_exit(int);
 <?!ia64> pid_t clone::__clone(unsigned long, void *);
 <?ia64> pid_t clone::__clone2(unsigned long, void *, void *);
 # if ! _KLIBC_NO_MMU
-<!sparc,sparc64,ia64,arm64,riscv64> pid_t fork();
+<!sparc,sparc64,ia64,arm64,riscv64,loongarch64> pid_t fork();
 <sparc,sparc64> pid_t fork at forkish();
 #endif
 #if _KLIBC_REAL_VFORK
diff --git a/usr/klibc/arch/loongarch64/Kbuild b/usr/klibc/arch/loongarch64/Kbuild
new file mode 100644
index 00000000..60c7660c
--- /dev/null
+++ b/usr/klibc/arch/loongarch64/Kbuild
@@ -0,0 +1,7 @@
+#
+# klibc files for LoongArch64
+#
+
+klib-y  := setjmp.o syscall.o
+always  := crt0.o
+targets := crt0.o
diff --git a/usr/klibc/arch/sparc64/MCONFIG b/usr/klibc/arch/loongarch64/MCONFIG
similarity index 51%
copy from usr/klibc/arch/sparc64/MCONFIG
copy to usr/klibc/arch/loongarch64/MCONFIG
index d8c878aa..0ef5eae8 100644
--- a/usr/klibc/arch/sparc64/MCONFIG
+++ b/usr/klibc/arch/loongarch64/MCONFIG
@@ -1,24 +1,23 @@
 # -*- makefile -*-
 #
-# arch/sparc64/MCONFIG
+# arch/loongarch64/MCONFIG
 #
 # Special rules for this architecture.  Note that this is actually
 # included from the main Makefile, and that pathnames should be
 # accordingly.
 #
 
-KLIBCARCHREQFLAGS = -m64 -D__sparc64__
-KLIBCOPTFLAGS     += -Os
+KLIBCOPTFLAGS	  += -Os -fomit-frame-pointer
 KLIBCBITSIZE      = 64
 
-KLIBCLDFLAGS      = -m elf64_sparc
-
 # Extra linkflags when building the shared version of the library
 # This address needs to be reachable using normal inter-module
 # calls, and work on the memory models for this architecture
-# Normal binaries start at 1 MB; the linker wants 1 MB alignment,
-# and call instructions have a 30-bit signed offset, << 2.
-KLIBCSHAREDFLAGS	= $(LD_IMAGE_BASE_OPT) 0x80000000
+# 4862 MB - normal binaries start at 4608 MB. Non-PIC jumps usually
+# use the BL instruction which requires a destination between -128M
+# to 128M. Since we can't put ourselves below the normal load
+# address, use the very top of the 128M region (minus 2MB)
+KLIBCSHAREDFLAGS  = $(LD_IMAGE_BASE_OPT) 0x127E00000
 
 # Kernel has never used stack trampolines
-KLIBCEXECSTACK := n
+KLIBCEXECSTACK    := n
diff --git a/usr/klibc/arch/riscv64/crt0.S b/usr/klibc/arch/loongarch64/crt0.S
similarity index 54%
copy from usr/klibc/arch/riscv64/crt0.S
copy to usr/klibc/arch/loongarch64/crt0.S
index 76fa3c28..cb3da669 100644
--- a/usr/klibc/arch/riscv64/crt0.S
+++ b/usr/klibc/arch/loongarch64/crt0.S
@@ -1,5 +1,5 @@
 #
-# arch/riscv64/crt0.S
+# arch/loongarch64/crt0.S
 #
 # Does arch-specific initialization and invokes __libc_init
 # with the appropriate arguments.
@@ -11,12 +11,8 @@
 #include <machine/asm.h>
 
 ENTRY(_start)
-	.option push
-	.option norelax
-	lla	gp, __global_pointer$
-	.option pop
-
-	mv	a0, sp			# Pointer to ELF entry structure
-	mv	a1, zero		# No onexit pointer
-	jal	__libc_init
+	move		$a0, $sp		# Pointer to ELF entry structure
+	move		$a1, $zero		# No onexit pointer
+	bstrins.d	$sp, $zero, 3, 0	# Align stack to 16 bytes
+	bl		__libc_init
 END(_start)
diff --git a/usr/klibc/arch/loongarch64/setjmp.S b/usr/klibc/arch/loongarch64/setjmp.S
new file mode 100644
index 00000000..11779885
--- /dev/null
+++ b/usr/klibc/arch/loongarch64/setjmp.S
@@ -0,0 +1,50 @@
+/*
+ * arch/loongarch64/setjmp.S
+ *
+ * setjmp/longjmp for the LoongArch64 architecture
+ *
+ * The jmp_buf is assumed to contain the following, in order:
+ *	pc (ra)
+ *	sp
+ *	r21
+ *	fp
+ *	s0..s8
+ */
+
+#include <machine/asm.h>
+
+ENTRY(setjmp)
+	st.d	$ra,  $a0, 0
+	st.d	$sp,  $a0, 8
+	st.d	$r21, $a0, 16
+	st.d	$fp,  $a0, 24
+	st.d	$s0,  $a0, 32
+	st.d	$s1,  $a0, 40
+	st.d	$s2,  $a0, 48
+	st.d	$s3,  $a0, 56
+	st.d	$s4,  $a0, 64
+	st.d	$s5,  $a0, 72
+	st.d	$s6,  $a0, 80
+	st.d	$s7,  $a0, 88
+	st.d	$s8,  $a0, 96
+	move	$a0,  $zero
+	jr	$ra
+END(setjmp)
+
+ENTRY(longjmp)
+	ld.d	$ra,  $a0, 0
+	ld.d	$sp,  $a0, 8
+	ld.d	$r21, $a0, 16
+	ld.d	$fp,  $a0, 24
+	ld.d	$s0,  $a0, 32
+	ld.d	$s1,  $a0, 40
+	ld.d	$s2,  $a0, 48
+	ld.d	$s3,  $a0, 56
+	ld.d	$s4,  $a0, 64
+	ld.d	$s5,  $a0, 72
+	ld.d	$s6,  $a0, 80
+	ld.d	$s7,  $a0, 88
+	ld.d	$s8,  $a0, 96
+	move	$a0,  $a1
+	jr	$ra
+END(longjmp)
diff --git a/usr/klibc/arch/loongarch64/syscall.S b/usr/klibc/arch/loongarch64/syscall.S
new file mode 100644
index 00000000..9a2ed469
--- /dev/null
+++ b/usr/klibc/arch/loongarch64/syscall.S
@@ -0,0 +1,13 @@
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+ENTRY(__syscall_common)
+	syscall 0
+	li.w	$t0, -4096
+	bleu	$a0, $t0, 1f
+	sub.d	$a0, $zero, $a0
+	la	$t0, errno
+	st.d	$a0, $t0, 0
+	li.w	$a0, -1
+1:	jr	$ra
+END(__syscall_common)
diff --git a/usr/klibc/arch/riscv64/sysstub.ph b/usr/klibc/arch/loongarch64/sysstub.ph
similarity index 63%
copy from usr/klibc/arch/riscv64/sysstub.ph
copy to usr/klibc/arch/loongarch64/sysstub.ph
index 85c1beb8..699bdc2f 100644
--- a/usr/klibc/arch/riscv64/sysstub.ph
+++ b/usr/klibc/arch/loongarch64/sysstub.ph
@@ -1,12 +1,12 @@
 # -*- perl -*-
 #
-# arch/riscv/sysstub.ph
+# arch/loongarch64/sysstub.ph
 #
 # Script to generate system call stubs
 #
 
-# On RISC-V, most system calls follow the standard convention, with the
-# system call number in x17 (a7) and the return value in x10 (a0).
+# On LoongArch64, most system calls follow the standard convention, with
+# the system call number in a7 and the return value in a0.
 
 sub make_sysstub($$$$$@) {
     my($outputdir, $fname, $type, $sname, $stype, @args) = @_;
@@ -17,8 +17,8 @@ sub make_sysstub($$$$$@) {
     print OUT "#include <asm/unistd.h>\n";
     print OUT "\n";
     print OUT "ENTRY(${fname})\n";
-    print OUT "\tli\ta7, __NR_${sname}\n";
-    print OUT "\tj\t__syscall_${stype}\n";
+    print OUT "\tli.w\t\$a7, __NR_${sname}\n";
+    print OUT "\tb\t__syscall_${stype}\n";
     print OUT "END(${fname})\n";
     close(OUT);
 }


More information about the klibc mailing list