[klibc] sh support for klibc The parts of klibc specific to the sh architecture. Signed-off-by: H. Peter Anvin --- commit 2efdaebf673dd21d9f1bde0efa1ebce7e2752276 tree fe21f2232e25955226bf80c67ce59875f85a5c91 parent 743780a4bc0d8ee9945ff03333d71cbbad68af1d author H. Peter Anvin Sun, 02 Jul 2006 12:25:51 -0700 committer H. Peter Anvin Sun, 02 Jul 2006 12:25:51 -0700 usr/include/arch/sh/klibc/archconfig.h | 14 +++++++ usr/include/arch/sh/klibc/archsetjmp.h | 22 +++++++++++ usr/include/arch/sh/klibc/archsignal.h | 14 +++++++ usr/include/arch/sh/klibc/archstat.h | 38 +++++++++++++++++++ usr/klibc/arch/sh/MCONFIG | 18 +++++++++ usr/klibc/arch/sh/Makefile.inc | 15 ++++++++ usr/klibc/arch/sh/crt0.S | 27 ++++++++++++++ usr/klibc/arch/sh/setjmp.S | 64 ++++++++++++++++++++++++++++++++ usr/klibc/arch/sh/syscall.S | 35 ++++++++++++++++++ usr/klibc/arch/sh/sysstub.ph | 34 +++++++++++++++++ 10 files changed, 281 insertions(+), 0 deletions(-) diff --git a/usr/include/arch/sh/klibc/archconfig.h b/usr/include/arch/sh/klibc/archconfig.h new file mode 100644 index 0000000..9c9e3d8 --- /dev/null +++ b/usr/include/arch/sh/klibc/archconfig.h @@ -0,0 +1,14 @@ +/* + * include/arch/sh/klibc/archconfig.h + * + * See include/klibc/sysconfig.h for the options that can be set in + * this file. + * + */ + +#ifndef _KLIBC_ARCHCONFIG_H +#define _KLIBC_ARCHCONFIG_H + +/* All defaults */ + +#endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/sh/klibc/archsetjmp.h b/usr/include/arch/sh/klibc/archsetjmp.h new file mode 100644 index 0000000..bb97167 --- /dev/null +++ b/usr/include/arch/sh/klibc/archsetjmp.h @@ -0,0 +1,22 @@ +/* + * arch/sh/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __r8; + unsigned long __r9; + unsigned long __r10; + unsigned long __r11; + unsigned long __r12; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __pr; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/usr/include/arch/sh/klibc/archsignal.h b/usr/include/arch/sh/klibc/archsignal.h new file mode 100644 index 0000000..8e48e51 --- /dev/null +++ b/usr/include/arch/sh/klibc/archsignal.h @@ -0,0 +1,14 @@ +/* + * arch/sh/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +#include +/* No special stuff for this architecture */ + +#endif diff --git a/usr/include/arch/sh/klibc/archstat.h b/usr/include/arch/sh/klibc/archstat.h new file mode 100644 index 0000000..f4c65ea --- /dev/null +++ b/usr/include/arch/sh/klibc/archstat.h @@ -0,0 +1,38 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#include + +#define _STATBUF_ST_NSEC + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + __stdev64 (st_dev); + unsigned char __pad0[4]; + + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + __stdev64 (st_rdev); + unsigned char __pad3[4]; + + long long st_size; + unsigned long st_blksize; + + unsigned long long st_blocks; + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif diff --git a/usr/klibc/arch/sh/MCONFIG b/usr/klibc/arch/sh/MCONFIG new file mode 100644 index 0000000..f0106e1 --- /dev/null +++ b/usr/klibc/arch/sh/MCONFIG @@ -0,0 +1,18 @@ +# -*- makefile -*- +# +# arch/sh/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHREGFLAGS = -m4 -mno-implicit-fp +KLIBCOPTFLAGS = -Os -fomit-frame-pointer +KLIBCBITSIZE = 32 + +# 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 +# 2 MB -- the normal starting point for text is 4 MB. +KLIBCSHAREDFLAGS = -Ttext 0x00200200 diff --git a/usr/klibc/arch/sh/Makefile.inc b/usr/klibc/arch/sh/Makefile.inc new file mode 100644 index 0000000..ccabfa4 --- /dev/null +++ b/usr/klibc/arch/sh/Makefile.inc @@ -0,0 +1,15 @@ +# -*- makefile -*- +# +# arch/sh/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = arch/sh/setjmp.o \ + arch/sh/syscall.o + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + +archclean: diff --git a/usr/klibc/arch/sh/crt0.S b/usr/klibc/arch/sh/crt0.S new file mode 100644 index 0000000..7f0a649 --- /dev/null +++ b/usr/klibc/arch/sh/crt0.S @@ -0,0 +1,27 @@ +# +# arch/sh/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. +# + + .text + .align 2 + .type _start,#function + .globl _start + +_start: + mov r15, r4 + mov #0, r5 + mov.l 1f, r0 + + jsr @r0 + nop + + .align 2 +1: .long __libc_init + + .size _start,.-_start diff --git a/usr/klibc/arch/sh/setjmp.S b/usr/klibc/arch/sh/setjmp.S new file mode 100644 index 0000000..2552358 --- /dev/null +++ b/usr/klibc/arch/sh/setjmp.S @@ -0,0 +1,64 @@ +# +# arch/sh/setjmp.S +# +# setjmp/longjmp for the SuperH architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# +# r8 +# r9 +# r10 +# r11 +# r12 +# r13 +# r14 +# r15 +# pr +# + + .text + .align 2 + + .globl setjmp + .type setjmp, #function + +setjmp: + add #(9*4), r4 + sts.l pr, @-r4 + mov.l r15, @-r4 + mov.l r14, @-r4 + mov.l r13, @-r4 + mov.l r12, @-r4 + mov.l r11, @-r4 + mov.l r10, @-r4 + mov.l r9, @-r4 + mov.l r8, @-r4 + rts + mov #0, r0 + + .size setjmp,.-setjmp + + .align 2 + .globl longjmp + .type setjmp, #function + +longjmp: + mov.l @r4+, r8 + mov.l @r4+, r9 + mov.l @r4+, r10 + mov.l @r4+, r11 + mov.l @r4+, r12 + mov.l @r4+, r13 + mov.l @r4+, r14 + mov.l @r4+, r15 + lds.l @r4+, pr + mov r5, r0 + tst r0, r0 + bf 1f + mov #1, r0 ! in case val==0 +1: rts + nop + + .size longjmp,.-longjmp diff --git a/usr/klibc/arch/sh/syscall.S b/usr/klibc/arch/sh/syscall.S new file mode 100644 index 0000000..41a0486 --- /dev/null +++ b/usr/klibc/arch/sh/syscall.S @@ -0,0 +1,35 @@ +/* + * arch/sh/syscall.S + * + * On sh, r3 contains the syscall number (set by generated stub); + * r4..r7 contain arguments 0-3 per the standard calling convention, + * and arguments 4-5 are passed in r0 and r1. + * + * The return value is in r3 rather than standard r0. + */ + + .section ".text.syscall","ax" + .align 2 + .globl ___syscall_common + .type ___syscall_common,@function +___syscall_common: + mov.l @(sp),r0 + mov.l @(4,sp),r1 + trapa #0x15 + mov.l 1f,r0 + cmp/hs r0,r3 + bt/s 3f + neg r3,r4 + mov.l 2f,r5 + mov.l r4,@r5 + rts + mov #-1,r0 +3: + rts + mov r3,r0 + + .align 2 +1: .long -4096 /* Errno limit */ +2: .long errno + + .size ___syscall_common,.-___syscall_common diff --git a/usr/klibc/arch/sh/sysstub.ph b/usr/klibc/arch/sh/sysstub.ph new file mode 100644 index 0000000..ce04b73 --- /dev/null +++ b/usr/klibc/arch/sh/sysstub.ph @@ -0,0 +1,34 @@ +# -*- perl -*- +# +# arch/sh/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "${outputdir}/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.section\t\".text.syscall\",\"ax\"\n"; + print OUT "\t.type\t${fname},\#function\n"; + print OUT "\t.globl\t${fname}\n"; + print OUT "\t.align\t2\n"; + print OUT "${fname}:\n"; + print OUT "\tbra\t__syscall_common\n"; + print OUT "#if __NR_${sname} >= 128\n"; + print OUT "\t mov.l\t1f, r3\n"; + print OUT "#else\n"; + print OUT "\t mov\t# __NR_${sname}, r3\n"; + print OUT "#endif\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + print OUT "\n"; + print OUT "#if __NR_${sname} >= 128\n"; + print OUT "\t.align\t2\n"; + print OUT "1:\t.long\t__NR_${sname}\n"; + print OUT "#endif\n"; + close(OUT); +} + +1;