From: Dejan Latinovic <Dejan.Latinovic at imgtec.com>
---
usr/include/arch/mips64/klibc/archconfig.h | 3 +
usr/include/arch/mips64/klibc/archsetjmp.h | 39 ++++++
usr/include/arch/mips64/machine/asm.h | 76 ++++++++++
usr/include/fcntl.h | 2 +-
usr/include/sys/md.h | 1 +
usr/include/sys/resource.h | 4 +-
usr/klibc/arch/mips64/Kbuild | 13 +-
usr/klibc/arch/mips64/crt0.S | 25 ++++
usr/klibc/arch/mips64/klibc.ld | 214 +++++++++++++++++++++++++++++
usr/klibc/arch/mips64/pipe.S | 15 ++
usr/klibc/arch/mips64/setjmp.S | 80 +++++++++++
usr/klibc/arch/mips64/syscall.S | 15 ++
usr/klibc/arch/mips64/sysstub.ph | 29 ++++
usr/klibc/arch/mips64/vfork.S | 15 ++
14 files changed, 528 insertions(+), 3 deletions(-)
create mode 100644 usr/include/arch/mips64/klibc/archsetjmp.h
create mode 100644 usr/include/arch/mips64/machine/asm.h
create mode 100644 usr/klibc/arch/mips64/crt0.S
create mode 100644 usr/klibc/arch/mips64/klibc.ld
create mode 100644 usr/klibc/arch/mips64/pipe.S
create mode 100644 usr/klibc/arch/mips64/setjmp.S
create mode 100644 usr/klibc/arch/mips64/syscall.S
create mode 100644 usr/klibc/arch/mips64/sysstub.ph
create mode 100644 usr/klibc/arch/mips64/vfork.S
diff --git a/usr/include/arch/mips64/klibc/archconfig.h
b/usr/include/arch/mips64/klibc/archconfig.h
index 4d856a5..b403090 100644
--- a/usr/include/arch/mips64/klibc/archconfig.h
+++ b/usr/include/arch/mips64/klibc/archconfig.h
@@ -15,4 +15,7 @@
/* We can use RT signals on MIPS */
#define _KLIBC_USE_RT_SIG 1
+/* MIPS has architecture-specific code for vfork() */
+#define _KLIBC_REAL_VFORK 1
+
#endif /* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/mips64/klibc/archsetjmp.h
b/usr/include/arch/mips64/klibc/archsetjmp.h
new file mode 100644
index 0000000..1fbe83e
--- /dev/null
+++ b/usr/include/arch/mips64/klibc/archsetjmp.h
@@ -0,0 +1,39 @@
+/*
+ * arch/mips/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __s0;
+ unsigned long __s1;
+ unsigned long __s2;
+ unsigned long __s3;
+ unsigned long __s4;
+ unsigned long __s5;
+ unsigned long __s6;
+ unsigned long __s7;
+ unsigned long __gp;
+ unsigned long __sp;
+ unsigned long __s8;
+ unsigned long __ra;
+ unsigned long __f20;
+ unsigned long __f21;
+ unsigned long __f22;
+ unsigned long __f23;
+ unsigned long __f24;
+ unsigned long __f25;
+ unsigned long __f26;
+ unsigned long __f27;
+ unsigned long __f28;
+ unsigned long __f29;
+ unsigned long __f30;
+ unsigned long __f31;
+ unsigned long __fcr31;
+ unsigned long __unused;
+} __attribute__ ((aligned(8)));
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _KLIBC_ARCHSETJMP_H */
diff --git a/usr/include/arch/mips64/machine/asm.h
b/usr/include/arch/mips64/machine/asm.h
new file mode 100644
index 0000000..0b8cece
--- /dev/null
+++ b/usr/include/arch/mips64/machine/asm.h
@@ -0,0 +1,76 @@
+/*
+ * arch/mips/include/machine/asm.h
+ */
+
+#ifndef _MACHINE_ASM_H
+#define _MACHINE_ASM_H
+
+/*
+ * Symbolic register names for 32 bit ABI
+ */
+
+#define zero $0 /* wired zero */
+#define AT $1 /* assembler temp - uppercase because of ".set
at" */
+#define v0 $2 /* return value */
+#define v1 $3
+#define a0 $4 /* argument registers */
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8 /* caller saved */
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define s0 $16 /* callee saved */
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24 /* caller saved */
+#define t9 $25
+#define jp $25 /* PIC jump register */
+#define k0 $26 /* kernel scratch */
+#define k1 $27
+#define gp $28 /* global pointer */
+#define sp $29 /* stack pointer */
+#define fp $30 /* frame pointer */
+#define s8 $30 /* same like fp! */
+#define ra $31 /* return address */
+
+/*
+ * LEAF - declare leaf routine
+ */
+#define LEAF(symbol) \
+ .globl symbol; \
+ .align 2; \
+ .type symbol, at function; \
+ .ent symbol,0; \
+symbol: .frame sp,0,ra
+
+
+/*
+ * NESTED - declare nested routine entry point
+ */
+#define NESTED(symbol, framesize, rpc) \
+ .globl symbol; \
+ .align 2; \
+ .type symbol, at function; \
+ .ent symbol,0; \
+symbol: .frame sp, framesize, rpc
+
+/*
+ * END - mark end of function
+ */
+#define END(function) \
+ .end function; \
+ .size function,.-function
+
+
+#endif /* _MACHINE_ASM_H */
diff --git a/usr/include/fcntl.h b/usr/include/fcntl.h
index bbd6917..09ba2f2 100644
--- a/usr/include/fcntl.h
+++ b/usr/include/fcntl.h
@@ -9,7 +9,7 @@
#include <klibc/compiler.h>
#include <klibc/seek.h>
#include <sys/types.h>
-#if defined(__mips__) && !defined(__mips64__)
+#if defined(__mips__) && !defined(__mips64)
# include <klibc/archfcntl.h>
#endif
#include <linux/fcntl.h>
diff --git a/usr/include/sys/md.h b/usr/include/sys/md.h
index 184e4aa..7be8ead 100644
--- a/usr/include/sys/md.h
+++ b/usr/include/sys/md.h
@@ -26,6 +26,7 @@
#define LEVEL_FAULTY (-5)
#define MAX_MD_DEVS 256 /* Max number of md dev */
+#include <endian.h>
#include <linux/raid/md_u.h>
#include <linux/raid/md_p.h>
diff --git a/usr/include/sys/resource.h b/usr/include/sys/resource.h
index 5d8bd52..35398a7 100644
--- a/usr/include/sys/resource.h
+++ b/usr/include/sys/resource.h
@@ -12,6 +12,8 @@
__extern int getpriority(int, int);
__extern int setpriority(int, int, int);
-__extern int getrusage(int, struct rusage *);
+#if !defined(__mips64)
+ __extern int getrusage(int, struct rusage *);
+#endif
#endif /* _SYS_RESOURCE_H */
diff --git a/usr/klibc/arch/mips64/Kbuild b/usr/klibc/arch/mips64/Kbuild
index 970c0f8..972e450 100644
--- a/usr/klibc/arch/mips64/Kbuild
+++ b/usr/klibc/arch/mips64/Kbuild
@@ -1,3 +1,14 @@
#
-# klibc files for mips64
+# klibc files for mips
#
+
+klib-y := pipe.o vfork.o setjmp.o syscall.o
+
+klib-y += ../../libgcc/__clzsi2.o ../../libgcc/__ashldi3.o
+klib-y += ../../libgcc/__ashrdi3.o ../../libgcc/__lshrdi3.o
+klib-y += ../../libgcc/__divdi3.o ../../libgcc/__moddi3.o
+klib-y += ../../libgcc/__udivdi3.o ../../libgcc/__umoddi3.o
+klib-y += ../../libgcc/__udivmoddi4.o
+
+always := crt0.o
+targets := crt0.o
diff --git a/usr/klibc/arch/mips64/crt0.S b/usr/klibc/arch/mips64/crt0.S
new file mode 100644
index 0000000..142d9f2
--- /dev/null
+++ b/usr/klibc/arch/mips64/crt0.S
@@ -0,0 +1,25 @@
+#
+# arch/mips/crt0.S
+#
+# Does arch-specific initialization and invokes __libc_init
+# with the appropriate arguments.
+#
+# See __static_init.c or __shared_init.c for the expected
+# arguments.
+#
+
+#include <machine/asm.h>
+
+NESTED(__start, 32, sp)
+ subu sp, 32
+ sw zero, 16(sp)
+
+ lui gp, %hi(_gp) # Initialize gp
+ addiu gp, gp, _gp
+
+ addiu a0, sp, 32 # Pointer to ELF entry structure
+ move a1, v0 # Kernel-provided atexit() pointer
+
+ jal __libc_init
+
+ END(__start)
diff --git a/usr/klibc/arch/mips64/klibc.ld b/usr/klibc/arch/mips64/klibc.ld
new file mode 100644
index 0000000..5a2a7a6
--- /dev/null
+++ b/usr/klibc/arch/mips64/klibc.ld
@@ -0,0 +1,214 @@
+/* Linker script for klibc.so, needed because of the the damned
+ GNU ld script headers problem */
+
+ENTRY(__start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ /* This address needs to be reachable using normal inter-module
+ calls, and work on the memory models for this architecture */
+ /* 2 MB -- the normal starting point for text is 4 MB */
+ . = 0x00200400;
+ .interp : { *(.interp) }
+ .reginfo : { *(.reginfo) }
+ .dynamic : { *(.dynamic) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.dyn :
+ {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
+ *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
+ *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
+ *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ }
+ .rela.dyn :
+ {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
+ *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
+ *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
+ *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0
+ .plt : { *(.plt) }
+ .text :
+ {
+ _ftext = . ;
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.mips16.fn.*) *(.mips16.call.*)
+ } =0
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) }
+ .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN(8192);
+ /* Ensure the __preinit_array_start label is properly aligned. We
+ could instead move the label definition inside the section, but
+ the linker would then create the section even if it turns out to
+ be empty, which isn't pretty. */
+ . = ALIGN(32 / 8);
+ PROVIDE (__preinit_array_start = .);
+ .preinit_array : { *(.preinit_array) }
+ PROVIDE (__preinit_array_end = .);
+ PROVIDE (__init_array_start = .);
+ .init_array : { *(.init_array) }
+ PROVIDE (__init_array_end = .);
+ PROVIDE (__fini_array_start = .);
+ .fini_array : { *(.fini_array) }
+ PROVIDE (__fini_array_end = .);
+ .data :
+ {
+ _fdata = . ;
+ *(.data .data.* .gnu.linkonce.d.*)
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+ .eh_frame : { KEEP (*(.eh_frame)) }
+ .gcc_except_table : { *(.gcc_except_table) }
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin*.o(.ctors))
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin*.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .jcr : { KEEP (*(.jcr)) }
+ _gp = ALIGN(16) + 0x7ff0;
+ .got : { *(.got.plt) *(.got) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata :
+ {
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ }
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ _fbss = .;
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ PROVIDE (___sbss_start = .);
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ PROVIDE (__sbss_end = .);
+ PROVIDE (___sbss_end = .);
+ }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = .;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+ /DISCARD/ : { *(.note.GNU-stack) }
+}
diff --git a/usr/klibc/arch/mips64/pipe.S b/usr/klibc/arch/mips64/pipe.S
new file mode 100644
index 0000000..932fc08
--- /dev/null
+++ b/usr/klibc/arch/mips64/pipe.S
@@ -0,0 +1,15 @@
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+LEAF(pipe)
+ li v0, __NR_pipe
+ syscall
+ bnez a3, 1f
+ sw v0, (a0)
+ sw v1, 4(a0)
+ li v0, 0
+ b 2f
+1: sw v0, errno
+ li v0, -1
+2: jr ra
+ END(pipe)
diff --git a/usr/klibc/arch/mips64/setjmp.S b/usr/klibc/arch/mips64/setjmp.S
new file mode 100644
index 0000000..68eed19
--- /dev/null
+++ b/usr/klibc/arch/mips64/setjmp.S
@@ -0,0 +1,80 @@
+#
+# arch/mips/setjmp.S
+#
+# setjmp/longjmp for the MIPS architecture
+#
+# The jmp_buf is assumed to contain the following, in order:
+# s0..s7
+# gp
+# sp
+# s8
+# ra
+# f20..f31
+# fcr31
+#
+
+#include <machine/asm.h>
+
+LEAF(setjmp)
+ sw s0, 0(a0)
+ sw s1, 4(a0)
+ sw s2, 8(a0)
+ sw s3, 12(a0)
+ sw s4, 16(a0)
+ sw s5, 20(a0)
+ sw s6, 24(a0)
+ sw s7, 28(a0)
+ sw gp, 32(a0)
+ sw sp, 36(a0)
+ sw s8, 40(a0)
+ sw ra, 44(a0)
+ cfc1 t0,$31
+ swc1 $f20,48(a0)
+ swc1 $f21,52(a0)
+ swc1 $f22,56(a0)
+ swc1 $f23,60(a0)
+ swc1 $f24,64(a0)
+ swc1 $f25,68(a0)
+ swc1 $f26,72(a0)
+ swc1 $f27,76(a0)
+ swc1 $f28,80(a0)
+ swc1 $f29,84(a0)
+ swc1 $f30,88(a0)
+ swc1 $f31,92(a0)
+ sw t0,96(a0)
+ move v0,zero
+ jr ra
+
+ END(setjmp)
+
+LEAF(longjmp)
+ lw s0, 0(a0)
+ lw s1, 4(a0)
+ lw s2, 8(a0)
+ lw s3, 12(a0)
+ lw s4, 16(a0)
+ lw s5, 20(a0)
+ lw s6, 24(a0)
+ lw s7, 28(a0)
+ lw gp, 32(a0)
+ lw sp, 36(a0)
+ lw s8, 40(a0)
+ lw ra, 44(a0)
+ lw t0, 96(a0)
+ lwc1 $f20,48(a0)
+ lwc1 $f21,52(a0)
+ lwc1 $f22,56(a0)
+ lwc1 $f23,60(a0)
+ lwc1 $f24,64(a0)
+ lwc1 $f25,68(a0)
+ lwc1 $f26,72(a0)
+ lwc1 $f27,76(a0)
+ lwc1 $f28,80(a0)
+ lwc1 $f29,84(a0)
+ lwc1 $f30,88(a0)
+ lwc1 $f31,92(a0)
+ ctc1 t0,$31
+ move v0,a1
+ jr ra
+
+ END(longjmp)
diff --git a/usr/klibc/arch/mips64/syscall.S b/usr/klibc/arch/mips64/syscall.S
new file mode 100644
index 0000000..cca0db2
--- /dev/null
+++ b/usr/klibc/arch/mips64/syscall.S
@@ -0,0 +1,15 @@
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+ .set noreorder
+
+LEAF(__syscall_common)
+ syscall
+ beqz a3, 1f
+ # sw is actually two instructions; the first one goes
+ # in the branch delay slot
+ # XXX: Break this up manually; as it is now it generates warnings.
+ sw v0, errno
+ li v0, -1
+1: jr ra
+ END(__syscall_common)
diff --git a/usr/klibc/arch/mips64/sysstub.ph b/usr/klibc/arch/mips64/sysstub.ph
new file mode 100644
index 0000000..3689529
--- /dev/null
+++ b/usr/klibc/arch/mips64/sysstub.ph
@@ -0,0 +1,29 @@
+# -*- perl -*-
+#
+# arch/mips/sysstub.ph
+#
+# Script to generate system call stubs
+#
+
+# On MIPS, most system calls follow the standard convention, with the
+# system call number in r0 (v0), return an error value in r19 (a3) as
+# well as the return value in r0 (v0).
+
+sub make_sysstub($$$$$@) {
+ my($outputdir, $fname, $type, $sname, $stype, @args) = @_;
+
+ $stype = $stype || 'common';
+ open(OUT, '>', "${outputdir}/${fname}.S");
+ print OUT "#include <machine/asm.h>\n";
+ print OUT "#include <asm/unistd.h>\n";
+ print OUT "\n";
+ print OUT "\t.set noreorder\n";
+ print OUT "\n";
+ print OUT "LEAF(${fname})\n";
+ print OUT "\tj\t__syscall_${stype}\n";
+ print OUT "\t li\tv0, __NR_${sname}\n";
+ print OUT "\tEND(${fname})\n";
+ close(OUT);
+}
+
+1;
diff --git a/usr/klibc/arch/mips64/vfork.S b/usr/klibc/arch/mips64/vfork.S
new file mode 100644
index 0000000..9aa955a
--- /dev/null
+++ b/usr/klibc/arch/mips64/vfork.S
@@ -0,0 +1,15 @@
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+#define CLONE_VM 0x00000100
+#define CLONE_VFORK 0x00004000
+#define SIGCHLD 18
+
+ .set noreorder
+
+LEAF(vfork)
+ li a0, CLONE_VFORK | CLONE_VM | SIGCHLD
+ li a1, 0
+ j __syscall_common
+ li v0, __NR_clone
+ END(vfork)
--
1.8.3.4 (Apple Git-47)
thank you for the submission, below some question, as the patch description is a bit minimal. On Tue, Mar 11, 2014 at 02:21:32PM +0800, YunQiang Su wrote:> From: Dejan Latinovic <Dejan.Latinovic at imgtec.com> > > --- > usr/include/arch/mips64/klibc/archconfig.h | 3 + > usr/include/arch/mips64/klibc/archsetjmp.h | 39 ++++++ > usr/include/arch/mips64/machine/asm.h | 76 ++++++++++ > usr/include/fcntl.h | 2 +- > usr/include/sys/md.h | 1 + > usr/include/sys/resource.h | 4 +-touching any file outside the mips64 better has an explanation or needs to be a separate patch.> usr/klibc/arch/mips64/Kbuild | 13 +- > usr/klibc/arch/mips64/crt0.S | 25 ++++ > usr/klibc/arch/mips64/klibc.ld | 214 +++++++++++++++++++++++++++++this needs an explanation too, a bit more verbose than "the ld header problem" I have zero idea what you are referring to. It seems mips is the only other arch that does this too. Why was this copied over?> usr/klibc/arch/mips64/pipe.S | 15 ++ > usr/klibc/arch/mips64/setjmp.S | 80 +++++++++++ > usr/klibc/arch/mips64/syscall.S | 15 ++ > usr/klibc/arch/mips64/sysstub.ph | 29 ++++ > usr/klibc/arch/mips64/vfork.S | 15 ++ > 14 files changed, 528 insertions(+), 3 deletions(-) > create mode 100644 usr/include/arch/mips64/klibc/archsetjmp.h > create mode 100644 usr/include/arch/mips64/machine/asm.h > create mode 100644 usr/klibc/arch/mips64/crt0.S > create mode 100644 usr/klibc/arch/mips64/klibc.ld > create mode 100644 usr/klibc/arch/mips64/pipe.S > create mode 100644 usr/klibc/arch/mips64/setjmp.S > create mode 100644 usr/klibc/arch/mips64/syscall.S > create mode 100644 usr/klibc/arch/mips64/sysstub.ph > create mode 100644 usr/klibc/arch/mips64/vfork.S > > diff --git a/usr/include/arch/mips64/klibc/archconfig.h b/usr/include/arch/mips64/klibc/archconfig.h > index 4d856a5..b403090 100644 > --- a/usr/include/arch/mips64/klibc/archconfig.h > +++ b/usr/include/arch/mips64/klibc/archconfig.h > @@ -15,4 +15,7 @@ > /* We can use RT signals on MIPS */ > #define _KLIBC_USE_RT_SIG 1 > > +/* MIPS has architecture-specific code for vfork() */ > +#define _KLIBC_REAL_VFORK 1 > + > #endif /* _KLIBC_ARCHCONFIG_H */ > diff --git a/usr/include/arch/mips64/klibc/archsetjmp.h b/usr/include/arch/mips64/klibc/archsetjmp.h > new file mode 100644 > index 0000000..1fbe83e > --- /dev/null > +++ b/usr/include/arch/mips64/klibc/archsetjmp.h > @@ -0,0 +1,39 @@ > +/* > + * arch/mips/include/klibc/archsetjmp.h > + */ > + > +#ifndef _KLIBC_ARCHSETJMP_H > +#define _KLIBC_ARCHSETJMP_H > + > +struct __jmp_buf { > + unsigned long __s0; > + unsigned long __s1; > + unsigned long __s2; > + unsigned long __s3; > + unsigned long __s4; > + unsigned long __s5; > + unsigned long __s6; > + unsigned long __s7; > + unsigned long __gp; > + unsigned long __sp; > + unsigned long __s8; > + unsigned long __ra; > + unsigned long __f20; > + unsigned long __f21; > + unsigned long __f22; > + unsigned long __f23; > + unsigned long __f24; > + unsigned long __f25; > + unsigned long __f26; > + unsigned long __f27; > + unsigned long __f28; > + unsigned long __f29; > + unsigned long __f30; > + unsigned long __f31; > + unsigned long __fcr31; > + unsigned long __unused; > +} __attribute__ ((aligned(8))); > + > +typedef struct __jmp_buf jmp_buf[1]; > + > +#endif /* _KLIBC_ARCHSETJMP_H */ > diff --git a/usr/include/arch/mips64/machine/asm.h b/usr/include/arch/mips64/machine/asm.h > new file mode 100644 > index 0000000..0b8cece > --- /dev/null > +++ b/usr/include/arch/mips64/machine/asm.h > @@ -0,0 +1,76 @@ > +/* > + * arch/mips/include/machine/asm.h > + */ > + > +#ifndef _MACHINE_ASM_H > +#define _MACHINE_ASM_H > + > +/* > + * Symbolic register names for 32 bit ABI > + */ > + > +#define zero $0 /* wired zero */ > +#define AT $1 /* assembler temp - uppercase because of ".set at" */ > +#define v0 $2 /* return value */ > +#define v1 $3 > +#define a0 $4 /* argument registers */ > +#define a1 $5 > +#define a2 $6 > +#define a3 $7 > +#define t0 $8 /* caller saved */ > +#define t1 $9 > +#define t2 $10 > +#define t3 $11 > +#define t4 $12 > +#define t5 $13 > +#define t6 $14 > +#define t7 $15 > +#define s0 $16 /* callee saved */ > +#define s1 $17 > +#define s2 $18 > +#define s3 $19 > +#define s4 $20 > +#define s5 $21 > +#define s6 $22 > +#define s7 $23 > +#define t8 $24 /* caller saved */ > +#define t9 $25 > +#define jp $25 /* PIC jump register */ > +#define k0 $26 /* kernel scratch */ > +#define k1 $27 > +#define gp $28 /* global pointer */ > +#define sp $29 /* stack pointer */ > +#define fp $30 /* frame pointer */ > +#define s8 $30 /* same like fp! */ > +#define ra $31 /* return address */ > + > +/* > + * LEAF - declare leaf routine > + */ > +#define LEAF(symbol) \ > + .globl symbol; \ > + .align 2; \ > + .type symbol, at function; \ > + .ent symbol,0; \ > +symbol: .frame sp,0,ra > + > + > +/* > + * NESTED - declare nested routine entry point > + */ > +#define NESTED(symbol, framesize, rpc) \ > + .globl symbol; \ > + .align 2; \ > + .type symbol, at function; \ > + .ent symbol,0; \ > +symbol: .frame sp, framesize, rpc > + > +/* > + * END - mark end of function > + */ > +#define END(function) \ > + .end function; \ > + .size function,.-function > + > + > +#endif /* _MACHINE_ASM_H */ > diff --git a/usr/include/fcntl.h b/usr/include/fcntl.h > index bbd6917..09ba2f2 100644 > --- a/usr/include/fcntl.h > +++ b/usr/include/fcntl.h > @@ -9,7 +9,7 @@ > #include <klibc/compiler.h> > #include <klibc/seek.h> > #include <sys/types.h> > -#if defined(__mips__) && !defined(__mips64__) > +#if defined(__mips__) && !defined(__mips64)why is this needed?> # include <klibc/archfcntl.h> > #endif > #include <linux/fcntl.h> > diff --git a/usr/include/sys/md.h b/usr/include/sys/md.h > index 184e4aa..7be8ead 100644 > --- a/usr/include/sys/md.h > +++ b/usr/include/sys/md.h > @@ -26,6 +26,7 @@ > #define LEVEL_FAULTY (-5) > #define MAX_MD_DEVS 256 /* Max number of md dev */ > > +#include <endian.h> > #include <linux/raid/md_u.h> > #include <linux/raid/md_p.h> > > diff --git a/usr/include/sys/resource.h b/usr/include/sys/resource.h > index 5d8bd52..35398a7 100644 > --- a/usr/include/sys/resource.h > +++ b/usr/include/sys/resource.h > @@ -12,6 +12,8 @@ > __extern int getpriority(int, int); > __extern int setpriority(int, int, int); > > -__extern int getrusage(int, struct rusage *); > +#if !defined(__mips64) > + __extern int getrusage(int, struct rusage *); > +#endif > > #endif /* _SYS_RESOURCE_H */ > diff --git a/usr/klibc/arch/mips64/Kbuild b/usr/klibc/arch/mips64/Kbuild > index 970c0f8..972e450 100644 > --- a/usr/klibc/arch/mips64/Kbuild > +++ b/usr/klibc/arch/mips64/Kbuild > @@ -1,3 +1,14 @@ > # > -# klibc files for mips64 > +# klibc files for mips > # > + > +klib-y := pipe.o vfork.o setjmp.o syscall.o > + > +klib-y += ../../libgcc/__clzsi2.o ../../libgcc/__ashldi3.o > +klib-y += ../../libgcc/__ashrdi3.o ../../libgcc/__lshrdi3.o > +klib-y += ../../libgcc/__divdi3.o ../../libgcc/__moddi3.o > +klib-y += ../../libgcc/__udivdi3.o ../../libgcc/__umoddi3.o > +klib-y += ../../libgcc/__udivmoddi4.o > + > +always := crt0.o > +targets := crt0.o > diff --git a/usr/klibc/arch/mips64/crt0.S b/usr/klibc/arch/mips64/crt0.S > new file mode 100644 > index 0000000..142d9f2 > --- /dev/null > +++ b/usr/klibc/arch/mips64/crt0.S > @@ -0,0 +1,25 @@ > +# > +# arch/mips/crt0.S > +# > +# Does arch-specific initialization and invokes __libc_init > +# with the appropriate arguments. > +# > +# See __static_init.c or __shared_init.c for the expected > +# arguments. > +# > + > +#include <machine/asm.h> > + > +NESTED(__start, 32, sp) > + subu sp, 32 > + sw zero, 16(sp) > + > + lui gp, %hi(_gp) # Initialize gp > + addiu gp, gp, _gp > + > + addiu a0, sp, 32 # Pointer to ELF entry structure > + move a1, v0 # Kernel-provided atexit() pointer > + > + jal __libc_init > + > + END(__start) > diff --git a/usr/klibc/arch/mips64/klibc.ld b/usr/klibc/arch/mips64/klibc.ld > new file mode 100644 > index 0000000..5a2a7a6 > --- /dev/null > +++ b/usr/klibc/arch/mips64/klibc.ld > @@ -0,0 +1,214 @@ > +/* Linker script for klibc.so, needed because of the the damned > + GNU ld script headers problem */ > + > +ENTRY(__start) > +SECTIONS > +{ > + /* Read-only sections, merged into text segment: */ > + /* This address needs to be reachable using normal inter-module > + calls, and work on the memory models for this architecture */ > + /* 2 MB -- the normal starting point for text is 4 MB */ > + . = 0x00200400; > + .interp : { *(.interp) } > + .reginfo : { *(.reginfo) } > + .dynamic : { *(.dynamic) } > + .hash : { *(.hash) } > + .dynsym : { *(.dynsym) } > + .dynstr : { *(.dynstr) } > + .gnu.version : { *(.gnu.version) } > + .gnu.version_d : { *(.gnu.version_d) } > + .gnu.version_r : { *(.gnu.version_r) } > + .rel.dyn : > + { > + *(.rel.init) > + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) > + *(.rel.fini) > + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) > + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) > + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) > + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) > + *(.rel.ctors) > + *(.rel.dtors) > + *(.rel.got) > + *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) > + *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) > + *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) > + *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) > + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) > + } > + .rela.dyn : > + { > + *(.rela.init) > + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) > + *(.rela.fini) > + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) > + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) > + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) > + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) > + *(.rela.ctors) > + *(.rela.dtors) > + *(.rela.got) > + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) > + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) > + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) > + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) > + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) > + } > + .rel.plt : { *(.rel.plt) } > + .rela.plt : { *(.rela.plt) } > + .init : > + { > + KEEP (*(.init)) > + } =0 > + .plt : { *(.plt) } > + .text : > + { > + _ftext = . ; > + *(.text .stub .text.* .gnu.linkonce.t.*) > + /* .gnu.warning sections are handled specially by elf32.em. */ > + *(.gnu.warning) > + *(.mips16.fn.*) *(.mips16.call.*) > + } =0 > + .fini : > + { > + KEEP (*(.fini)) > + } =0 > + PROVIDE (__etext = .); > + PROVIDE (_etext = .); > + PROVIDE (etext = .); > + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } > + .rodata1 : { *(.rodata1) } > + .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } > + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } > + .eh_frame_hdr : { *(.eh_frame_hdr) } > + /* Adjust the address for the data segment. We want to adjust up to > + the same address within the page on the next page up. */ > + . = ALIGN(8192); > + /* Ensure the __preinit_array_start label is properly aligned. We > + could instead move the label definition inside the section, but > + the linker would then create the section even if it turns out to > + be empty, which isn't pretty. */ > + . = ALIGN(32 / 8); > + PROVIDE (__preinit_array_start = .); > + .preinit_array : { *(.preinit_array) } > + PROVIDE (__preinit_array_end = .); > + PROVIDE (__init_array_start = .); > + .init_array : { *(.init_array) } > + PROVIDE (__init_array_end = .); > + PROVIDE (__fini_array_start = .); > + .fini_array : { *(.fini_array) } > + PROVIDE (__fini_array_end = .); > + .data : > + { > + _fdata = . ; > + *(.data .data.* .gnu.linkonce.d.*) > + SORT(CONSTRUCTORS) > + } > + .data1 : { *(.data1) } > + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } > + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } > + .eh_frame : { KEEP (*(.eh_frame)) } > + .gcc_except_table : { *(.gcc_except_table) } > + .ctors : > + { > + /* gcc uses crtbegin.o to find the start of > + the constructors, so we make sure it is > + first. Because this is a wildcard, it > + doesn't matter if the user does not > + actually link against crtbegin.o; the > + linker won't look for a file to match a > + wildcard. The wildcard also means that it > + doesn't matter which directory crtbegin.o > + is in. */ > + KEEP (*crtbegin*.o(.ctors)) > + /* We don't want to include the .ctor section from > + from the crtend.o file until after the sorted ctors. > + The .ctor section from the crtend file contains the > + end of ctors marker and it must be last */ > + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) > + KEEP (*(SORT(.ctors.*))) > + KEEP (*(.ctors)) > + } > + .dtors : > + { > + KEEP (*crtbegin*.o(.dtors)) > + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) > + KEEP (*(SORT(.dtors.*))) > + KEEP (*(.dtors)) > + } > + .jcr : { KEEP (*(.jcr)) } > + _gp = ALIGN(16) + 0x7ff0; > + .got : { *(.got.plt) *(.got) } > + /* We want the small data sections together, so single-instruction offsets > + can access them all, and initialized data all before uninitialized, so > + we can shorten the on-disk segment size. */ > + .sdata : > + { > + *(.sdata .sdata.* .gnu.linkonce.s.*) > + } > + .lit8 : { *(.lit8) } > + .lit4 : { *(.lit4) } > + _edata = .; > + PROVIDE (edata = .); > + __bss_start = .; > + _fbss = .; > + .sbss : > + { > + PROVIDE (__sbss_start = .); > + PROVIDE (___sbss_start = .); > + *(.dynsbss) > + *(.sbss .sbss.* .gnu.linkonce.sb.*) > + *(.scommon) > + PROVIDE (__sbss_end = .); > + PROVIDE (___sbss_end = .); > + } > + .bss : > + { > + *(.dynbss) > + *(.bss .bss.* .gnu.linkonce.b.*) > + *(COMMON) > + /* Align here to ensure that the .bss section occupies space up to > + _end. Align after .bss to ensure correct alignment even if the > + .bss section disappears because there are no input sections. */ > + . = ALIGN(32 / 8); > + } > + . = ALIGN(32 / 8); > + _end = .; > + PROVIDE (end = .); > + /* Stabs debugging sections. */ > + .stab 0 : { *(.stab) } > + .stabstr 0 : { *(.stabstr) } > + .stab.excl 0 : { *(.stab.excl) } > + .stab.exclstr 0 : { *(.stab.exclstr) } > + .stab.index 0 : { *(.stab.index) } > + .stab.indexstr 0 : { *(.stab.indexstr) } > + .comment 0 : { *(.comment) } > + /* DWARF debug sections. > + Symbols in the DWARF debugging sections are relative to the beginning > + of the section so we begin them at 0. */ > + /* DWARF 1 */ > + .debug 0 : { *(.debug) } > + .line 0 : { *(.line) } > + /* GNU DWARF 1 extensions */ > + .debug_srcinfo 0 : { *(.debug_srcinfo) } > + .debug_sfnames 0 : { *(.debug_sfnames) } > + /* DWARF 1.1 and DWARF 2 */ > + .debug_aranges 0 : { *(.debug_aranges) } > + .debug_pubnames 0 : { *(.debug_pubnames) } > + /* DWARF 2 */ > + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } > + .debug_abbrev 0 : { *(.debug_abbrev) } > + .debug_line 0 : { *(.debug_line) } > + .debug_frame 0 : { *(.debug_frame) } > + .debug_str 0 : { *(.debug_str) } > + .debug_loc 0 : { *(.debug_loc) } > + .debug_macinfo 0 : { *(.debug_macinfo) } > + /* SGI/MIPS DWARF 2 extensions */ > + .debug_weaknames 0 : { *(.debug_weaknames) } > + .debug_funcnames 0 : { *(.debug_funcnames) } > + .debug_typenames 0 : { *(.debug_typenames) } > + .debug_varnames 0 : { *(.debug_varnames) } > + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } > + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } > + /DISCARD/ : { *(.note.GNU-stack) } > +} > diff --git a/usr/klibc/arch/mips64/pipe.S b/usr/klibc/arch/mips64/pipe.S > new file mode 100644 > index 0000000..932fc08 > --- /dev/null > +++ b/usr/klibc/arch/mips64/pipe.S > @@ -0,0 +1,15 @@ > +#include <machine/asm.h> > +#include <asm/unistd.h> > + > +LEAF(pipe) > + li v0, __NR_pipe > + syscall > + bnez a3, 1f > + sw v0, (a0) > + sw v1, 4(a0) > + li v0, 0 > + b 2f > +1: sw v0, errno > + li v0, -1 > +2: jr ra > + END(pipe) > diff --git a/usr/klibc/arch/mips64/setjmp.S b/usr/klibc/arch/mips64/setjmp.S > new file mode 100644 > index 0000000..68eed19 > --- /dev/null > +++ b/usr/klibc/arch/mips64/setjmp.S > @@ -0,0 +1,80 @@ > +# > +# arch/mips/setjmp.S > +# > +# setjmp/longjmp for the MIPS architecture > +# > +# The jmp_buf is assumed to contain the following, in order: > +# s0..s7 > +# gp > +# sp > +# s8 > +# ra > +# f20..f31 > +# fcr31 > +# > + > +#include <machine/asm.h> > + > +LEAF(setjmp) > + sw s0, 0(a0) > + sw s1, 4(a0) > + sw s2, 8(a0) > + sw s3, 12(a0) > + sw s4, 16(a0) > + sw s5, 20(a0) > + sw s6, 24(a0) > + sw s7, 28(a0) > + sw gp, 32(a0) > + sw sp, 36(a0) > + sw s8, 40(a0) > + sw ra, 44(a0) > + cfc1 t0,$31 > + swc1 $f20,48(a0) > + swc1 $f21,52(a0) > + swc1 $f22,56(a0) > + swc1 $f23,60(a0) > + swc1 $f24,64(a0) > + swc1 $f25,68(a0) > + swc1 $f26,72(a0) > + swc1 $f27,76(a0) > + swc1 $f28,80(a0) > + swc1 $f29,84(a0) > + swc1 $f30,88(a0) > + swc1 $f31,92(a0) > + sw t0,96(a0) > + move v0,zero > + jr ra > + > + END(setjmp) > + > +LEAF(longjmp) > + lw s0, 0(a0) > + lw s1, 4(a0) > + lw s2, 8(a0) > + lw s3, 12(a0) > + lw s4, 16(a0) > + lw s5, 20(a0) > + lw s6, 24(a0) > + lw s7, 28(a0) > + lw gp, 32(a0) > + lw sp, 36(a0) > + lw s8, 40(a0) > + lw ra, 44(a0) > + lw t0, 96(a0) > + lwc1 $f20,48(a0) > + lwc1 $f21,52(a0) > + lwc1 $f22,56(a0) > + lwc1 $f23,60(a0) > + lwc1 $f24,64(a0) > + lwc1 $f25,68(a0) > + lwc1 $f26,72(a0) > + lwc1 $f27,76(a0) > + lwc1 $f28,80(a0) > + lwc1 $f29,84(a0) > + lwc1 $f30,88(a0) > + lwc1 $f31,92(a0) > + ctc1 t0,$31 > + move v0,a1 > + jr ra > + > + END(longjmp) > diff --git a/usr/klibc/arch/mips64/syscall.S b/usr/klibc/arch/mips64/syscall.S > new file mode 100644 > index 0000000..cca0db2 > --- /dev/null > +++ b/usr/klibc/arch/mips64/syscall.S > @@ -0,0 +1,15 @@ > +#include <machine/asm.h> > +#include <asm/unistd.h> > + > + .set noreorder > + > +LEAF(__syscall_common) > + syscall > + beqz a3, 1f > + # sw is actually two instructions; the first one goes > + # in the branch delay slot > + # XXX: Break this up manually; as it is now it generates warnings. > + sw v0, errno > + li v0, -1 > +1: jr ra > + END(__syscall_common) > diff --git a/usr/klibc/arch/mips64/sysstub.ph b/usr/klibc/arch/mips64/sysstub.ph > new file mode 100644 > index 0000000..3689529 > --- /dev/null > +++ b/usr/klibc/arch/mips64/sysstub.ph > @@ -0,0 +1,29 @@ > +# -*- perl -*- > +# > +# arch/mips/sysstub.ph > +# > +# Script to generate system call stubs > +# > + > +# On MIPS, most system calls follow the standard convention, with the > +# system call number in r0 (v0), return an error value in r19 (a3) as > +# well as the return value in r0 (v0). > + > +sub make_sysstub($$$$$@) { > + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; > + > + $stype = $stype || 'common'; > + open(OUT, '>', "${outputdir}/${fname}.S"); > + print OUT "#include <machine/asm.h>\n"; > + print OUT "#include <asm/unistd.h>\n"; > + print OUT "\n"; > + print OUT "\t.set noreorder\n"; > + print OUT "\n"; > + print OUT "LEAF(${fname})\n"; > + print OUT "\tj\t__syscall_${stype}\n"; > + print OUT "\t li\tv0, __NR_${sname}\n"; > + print OUT "\tEND(${fname})\n"; > + close(OUT); > +} > + > +1; > diff --git a/usr/klibc/arch/mips64/vfork.S b/usr/klibc/arch/mips64/vfork.S > new file mode 100644 > index 0000000..9aa955a > --- /dev/null > +++ b/usr/klibc/arch/mips64/vfork.S > @@ -0,0 +1,15 @@ > +#include <machine/asm.h> > +#include <asm/unistd.h> > + > +#define CLONE_VM 0x00000100 > +#define CLONE_VFORK 0x00004000 > +#define SIGCHLD 18 > + > + .set noreorder > + > +LEAF(vfork) > + li a0, CLONE_VFORK | CLONE_VM | SIGCHLD > + li a1, 0 > + j __syscall_common > + li v0, __NR_clone > + END(vfork) > -- > 1.8.3.4 (Apple Git-47) > > _______________________________________________ > klibc mailing list > klibc at zytor.com > http://www.zytor.com/mailman/listinfo/klibc
On 03/10/2014 11:21 PM, YunQiang Su wrote:> From: Dejan Latinovic <Dejan.Latinovic at imgtec.com>Description goes here? I think it would be helpful to break this up into a few patches with descriptions.> + unsigned long __f20; > + unsigned long __f21; > + unsigned long __f22; > + unsigned long __f23; > + unsigned long __f24; > + unsigned long __f25; > + unsigned long __f26; > + unsigned long __f27; > + unsigned long __f28; > + unsigned long __f29; > + unsigned long __f30; > + unsigned long __f31; > + unsigned long __fcr31; > + unsigned long __unused;Does it make sense to save all the floating-point state even though klibc doesn't have any floating point support?> +/* > + * Symbolic register names for 32 bit ABI > + */64-bit?> diff --git a/usr/include/fcntl.h b/usr/include/fcntl.h > index bbd6917..09ba2f2 100644 > --- a/usr/include/fcntl.h > +++ b/usr/include/fcntl.h > @@ -9,7 +9,7 @@ > #include <klibc/compiler.h> > #include <klibc/seek.h> > #include <sys/types.h> > -#if defined(__mips__) && !defined(__mips64__) > +#if defined(__mips__) && !defined(__mips64) > # include <klibc/archfcntl.h> > #endif > #include <linux/fcntl.h> > diff --git a/usr/include/sys/md.h b/usr/include/sys/md.h > index 184e4aa..7be8ead 100644 > --- a/usr/include/sys/md.h > +++ b/usr/include/sys/md.h > @@ -26,6 +26,7 @@ > #define LEVEL_FAULTY (-5) > #define MAX_MD_DEVS 256 /* Max number of md dev */ > > +#include <endian.h> > #include <linux/raid/md_u.h> > #include <linux/raid/md_p.h> >These hunks definitely should be explained, and probably should be broken out as separate patches.> diff --git a/usr/include/sys/resource.h b/usr/include/sys/resource.h > index 5d8bd52..35398a7 100644 > --- a/usr/include/sys/resource.h > +++ b/usr/include/sys/resource.h > @@ -12,6 +12,8 @@ > __extern int getpriority(int, int); > __extern int setpriority(int, int, int); > > -__extern int getrusage(int, struct rusage *); > +#if !defined(__mips64) > + __extern int getrusage(int, struct rusage *); > +#endif >Say what?> diff --git a/usr/klibc/arch/mips64/crt0.S b/usr/klibc/arch/mips64/crt0.S > new file mode 100644 > index 0000000..142d9f2 > --- /dev/null > +++ b/usr/klibc/arch/mips64/crt0.S > @@ -0,0 +1,25 @@ > +# > +# arch/mips/crt0.Smips64?
On Tue, Mar 11, 2014 at 02:21:32PM +0800, YunQiang Su wrote:> From: Dejan Latinovic <Dejan.Latinovic at imgtec.com> > > ---any update? thank you. -- maks
On 03/11/2014 09:38 AM, H. Peter Anvin wrote:> On 03/10/2014 11:21 PM, YunQiang Su wrote: >> From: Dejan Latinovic <Dejan.Latinovic at imgtec.com> > > Description goes here? I think it would be helpful to break this up > into a few patches with descriptions. > >> + unsigned long __f20; >> + unsigned long __f21; >> + unsigned long __f22; >> + unsigned long __f23; >> + unsigned long __f24; >> + unsigned long __f25; >> + unsigned long __f26; >> + unsigned long __f27; >> + unsigned long __f28; >> + unsigned long __f29; >> + unsigned long __f30; >> + unsigned long __f31; >> + unsigned long __fcr31; >> + unsigned long __unused; > > Does it make sense to save all the floating-point state even though > klibc doesn't have any floating point support? > >> +/* >> + * Symbolic register names for 32 bit ABI >> + */ > > 64-bit? >I'm also wondering if it is possible to share some of this with the mips32 implementation... -hpa