[klibc] parisc support for klibc The parts of klibc specific to the parisc architecture. Signed-off-by: H. Peter Anvin --- commit 92b4904630cbe1a048d7739f3323048de1392051 tree 93affd7ccf2396499b4de4f83608ec3af4a50f6e parent 3f3506170a1beaba2524338156de9f7e4494c604 author H. Peter Anvin Sun, 02 Jul 2006 12:25:38 -0700 committer H. Peter Anvin Sun, 02 Jul 2006 12:25:38 -0700 usr/include/arch/parisc/klibc/archconfig.h | 14 ++++ usr/include/arch/parisc/klibc/archsetjmp.h | 14 ++++ usr/include/arch/parisc/klibc/archsignal.h | 25 ++++++++ usr/include/arch/parisc/klibc/archstat.h | 29 +++++++++ usr/klibc/arch/parisc/MCONFIG | 12 ++++ usr/klibc/arch/parisc/Makefile.inc | 16 +++++ usr/klibc/arch/parisc/crt0.S | 37 ++++++++++++ usr/klibc/arch/parisc/setjmp.S | 88 ++++++++++++++++++++++++++++ usr/klibc/arch/parisc/syscall.S | 36 +++++++++++ usr/klibc/arch/parisc/sysstub.ph | 28 +++++++++ 10 files changed, 299 insertions(+), 0 deletions(-) diff --git a/usr/include/arch/parisc/klibc/archconfig.h b/usr/include/arch/parisc/klibc/archconfig.h new file mode 100644 index 0000000..f8ba9e2 --- /dev/null +++ b/usr/include/arch/parisc/klibc/archconfig.h @@ -0,0 +1,14 @@ +/* + * include/arch/parisc/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/parisc/klibc/archsetjmp.h b/usr/include/arch/parisc/klibc/archsetjmp.h new file mode 100644 index 0000000..05e943e --- /dev/null +++ b/usr/include/arch/parisc/klibc/archsetjmp.h @@ -0,0 +1,14 @@ +/* + * arch/parisc/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + double regs[21]; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/usr/include/arch/parisc/klibc/archsignal.h b/usr/include/arch/parisc/klibc/archsignal.h new file mode 100644 index 0000000..256aeea --- /dev/null +++ b/usr/include/arch/parisc/klibc/archsignal.h @@ -0,0 +1,25 @@ +/* + * arch/parisc/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +#include +#define _NSIG 64 +#define _NSIG_SZ (_NSIG / LONG_BIT) + +typedef struct { + unsigned long sig[_NSIG_SZ]; +} sigset_t; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; +}; + +#endif diff --git a/usr/include/arch/parisc/klibc/archstat.h b/usr/include/arch/parisc/klibc/archstat.h new file mode 100644 index 0000000..0b8ef8d --- /dev/null +++ b/usr/include/arch/parisc/klibc/archstat.h @@ -0,0 +1,29 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#include + +#define _STATBUF_ST_NSEC + +struct stat { + __stdev64 (st_dev); + unsigned int __pad1; + + unsigned int __st_ino; /* Not actually filled in */ + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + __stdev64 (st_rdev); + unsigned int __pad2; + signed long long st_size; + signed int st_blksize; + + signed long long st_blocks; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + unsigned long long st_ino; +}; + +#endif diff --git a/usr/klibc/arch/parisc/MCONFIG b/usr/klibc/arch/parisc/MCONFIG new file mode 100644 index 0000000..83c2e9e --- /dev/null +++ b/usr/klibc/arch/parisc/MCONFIG @@ -0,0 +1,12 @@ +# -*- makefile -*- +# +# arch/parisc/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +KLIBCOPTFLAGS = -Os -fomit-frame-pointer +KLIBCBITSIZE = 32 +KLIBCSHAREDFLAGS = -Ttext 0x40001000 diff --git a/usr/klibc/arch/parisc/Makefile.inc b/usr/klibc/arch/parisc/Makefile.inc new file mode 100644 index 0000000..f479a6c --- /dev/null +++ b/usr/klibc/arch/parisc/Makefile.inc @@ -0,0 +1,16 @@ +# -*- makefile -*- +# +# arch/parisc/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +KLIBCARCHOBJS = \ + arch/$(KLIBCARCH)/setjmp.o \ + arch/$(KLIBCARCH)/syscall.o + +KLIBCARCHOOBJS = $(patsubst %o,%.lo,%(KLIBCARCHOBJS)) + +archclean: diff --git a/usr/klibc/arch/parisc/crt0.S b/usr/klibc/arch/parisc/crt0.S new file mode 100644 index 0000000..0922446 --- /dev/null +++ b/usr/klibc/arch/parisc/crt0.S @@ -0,0 +1,37 @@ + .align 4 + + .import $global$, data + .import __libc_init, code + + .global _start + .export _start, ENTRY + .type _start,@function + + .proc + .callinfo + +_start: +/* extend the stack by 64-bytes */ + ldo 64(%sp), %sp + +/* %r25 = argc + * %r24 = argv + * envp = argv + (argc + 1) + * elfdata = (argv - 4) + */ + ldo -4(%r24), %r26 + +/* load global data */ + ldil L%$global$, %dp + ldo R%$global$(%dp), %dp + +/* parisc abi puts the atexit pointer in %r23, see ELF_PLAT_INIT() */ + copy %r23, %r25 + +/* branch to __libc_init */ + bl __libc_init,%r2 + nop +/* break miserably if we ever return */ + iitlbp %r0,(%sr0,%r0) /* illegal instruction */ + nop + .procend diff --git a/usr/klibc/arch/parisc/setjmp.S b/usr/klibc/arch/parisc/setjmp.S new file mode 100644 index 0000000..c8d766c --- /dev/null +++ b/usr/klibc/arch/parisc/setjmp.S @@ -0,0 +1,88 @@ +/* + * parisc specific setjmp/longjmp routines + * + */ + + .text + .align 4 + .global setjmp + .export setjmp, code + .proc + .callinfo +setjmp: + stw %r3,0(%r26) + stw %r4,8(%r26) + stw %r5,12(%r26) + stw %r6,16(%r26) + stw %r7,20(%r26) + stw %r8,24(%r26) + stw %r9,28(%r26) + stw %r10,32(%r26) + stw %r11,36(%r26) + stw %r12,40(%r26) + stw %r13,44(%r26) + stw %r14,48(%r26) + stw %r15,52(%r26) + stw %r16,56(%r26) + stw %r17,60(%r26) + stw %r18,64(%r26) + stw %r19,68(%r26) + stw %r27,72(%r26) + stw %r30,76(%r26) + stw %rp,80(%r26) + ldo 88(%r26),%r19 + fstd,ma %fr12,8(%r19) + fstd,ma %fr13,8(%r19) + fstd,ma %fr14,8(%r19) + fstd,ma %fr15,8(%r19) + fstd,ma %fr16,8(%r19) + fstd,ma %fr17,8(%r19) + fstd,ma %fr18,8(%r19) + fstd,ma %fr19,8(%r19) + fstd,ma %fr20,8(%r19) + fstd %fr21,0(%r19) + bv %r0(%rp) + copy %r0,%r28 + .procend + + .text + .align 4 + .global longjmp + .export longjmp, code + .proc + .callinfo +longjmp: + ldw 0(%r26),%r3 + ldw 8(%r26),%r4 + ldw 12(%r26),%r5 + ldw 16(%r26),%r6 + ldw 20(%r26),%r7 + ldw 24(%r26),%r8 + ldw 28(%r26),%r9 + ldw 32(%r26),%r10 + ldw 36(%r26),%r11 + ldw 40(%r26),%r12 + ldw 44(%r26),%r13 + ldw 48(%r26),%r14 + ldw 52(%r26),%r15 + ldw 56(%r26),%r16 + ldw 60(%r26),%r17 + ldw 64(%r26),%r18 + ldw 68(%r26),%r19 + ldw 72(%r26),%r27 + ldw 76(%r26),%r30 + ldw 80(%r26),%rp + ldo 88(%r26),%r20 + fldd,ma 8(%r20),%fr12 + fldd,ma 8(%r20),%fr13 + fldd,ma 8(%r20),%fr14 + fldd,ma 8(%r20),%fr15 + fldd,ma 8(%r20),%fr16 + fldd,ma 8(%r20),%fr17 + fldd,ma 8(%r20),%fr18 + fldd,ma 8(%r20),%fr19 + fldd,ma 8(%r20),%fr20 + fldd 0(%r20),%fr21 + bv %r0(%rp) + copy %r25,%r28 + .procend diff --git a/usr/klibc/arch/parisc/syscall.S b/usr/klibc/arch/parisc/syscall.S new file mode 100644 index 0000000..0ff2a65 --- /dev/null +++ b/usr/klibc/arch/parisc/syscall.S @@ -0,0 +1,36 @@ +/* + * arch/parisc/syscall.S + * + * %r20 contains the system call number, %r2 contains whence we came + * + */ + + .text + .align 64 ; cache-width aligned + .globl __syscall_common + .type __syscall_common,@function +__syscall_common: + ldo 0x40(%sp),%sp + stw %rp,-0x54(%sp) ; save return pointer + + ldw -0x74(%sp),%r22 ; %arg4 + ldw -0x78(%sp),%r21 ; %arg5 + + ble 0x100(%sr2, %r0) ; jump to gateway page + nop ; can we move a load here? + + ldi -0x1000,%r19 ; %r19 = -4096 + sub %r0,%ret0,%r22 ; %r22 = -%ret0 + cmpb,>>=,n %r19,%ret0,1f ; if %ret0 >= -4096UL + ldi -1,%ret0 ; nullified on taken forward + + /* store %r22 to errno... */ + ldil L%errno,%r1 + ldo R%errno(%r1),%r1 + stw %r22,0(%r1) +1: + ldw -0x54(%sp),%rp ; restore return pointer + bv %r0(%rp) ; jump back + ldo -0x40(%sp),%sp + + .size __syscall_common,.-__syscall_common diff --git a/usr/klibc/arch/parisc/sysstub.ph b/usr/klibc/arch/parisc/sysstub.ph new file mode 100644 index 0000000..e2196ac --- /dev/null +++ b/usr/klibc/arch/parisc/sysstub.ph @@ -0,0 +1,28 @@ +# -*- perl -*- +# +# arch/parisc/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.text\n"; + print OUT "\t.align 4\n"; + print OUT "\t.import __syscall_common, code\n"; + print OUT "\t.global ${fname}\n"; + print OUT "\t.export ${fname}, code\n"; + print OUT "\t.proc\n"; + print OUT "\.callinfo\n"; + print OUT "${fname}:\n"; + print OUT "\tb\t__syscall_common\n"; + print OUT "\t ldo\t__NR_${sname}(%r0),%r20\n"; + print OUT "\t.procend\n"; + close(OUT); +} + +1;