[klibc] ppc64 support for klibc The parts of klibc specific to the ppc64 architecture. Signed-off-by: H. Peter Anvin --- commit d8d455eefd19108268c7288e268275d69692394e tree 09ecb66cd5fe62b348d27086d4760d3a55f22f07 parent d48f204e0c71e08b3c2653079c52c09568313c93 author H. Peter Anvin Sun, 02 Jul 2006 12:25:45 -0700 committer H. Peter Anvin Sun, 02 Jul 2006 12:25:45 -0700 usr/include/arch/ppc64/klibc/archconfig.h | 12 ++++ usr/include/arch/ppc64/klibc/archsetjmp.h | 36 ++++++++++++ usr/include/arch/ppc64/klibc/archsignal.h | 14 +++++ usr/include/arch/ppc64/klibc/archstat.h | 27 +++++++++ usr/klibc/arch/ppc64/MCONFIG | 26 +++++++++ usr/klibc/arch/ppc64/Makefile.inc | 25 +++++++++ usr/klibc/arch/ppc64/crt0.S | 32 +++++++++++ usr/klibc/arch/ppc64/setjmp.S | 85 +++++++++++++++++++++++++++++ usr/klibc/arch/ppc64/syscall.c | 14 +++++ usr/klibc/arch/ppc64/sysstub.ph | 31 +++++++++++ 10 files changed, 302 insertions(+), 0 deletions(-) diff --git a/usr/include/arch/ppc64/klibc/archconfig.h b/usr/include/arch/ppc64/klibc/archconfig.h new file mode 100644 index 0000000..27c5630 --- /dev/null +++ b/usr/include/arch/ppc64/klibc/archconfig.h @@ -0,0 +1,12 @@ +/* + * include/arch/ppc64/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 + +#define _KLIBC_USE_RT_SIG 1 + +#endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/ppc64/klibc/archsetjmp.h b/usr/include/arch/ppc64/klibc/archsetjmp.h new file mode 100644 index 0000000..d227728 --- /dev/null +++ b/usr/include/arch/ppc64/klibc/archsetjmp.h @@ -0,0 +1,36 @@ +/* + * arch/ppc64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __r2; + unsigned long __sp; + unsigned long __lr; + unsigned long __cr; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __r16; + unsigned long __r17; + unsigned long __r18; + unsigned long __r19; + unsigned long __r20; + unsigned long __r21; + unsigned long __r22; + unsigned long __r23; + unsigned long __r24; + unsigned long __r25; + unsigned long __r26; + unsigned long __r27; + unsigned long __r28; + unsigned long __r29; + unsigned long __r30; + unsigned long __r31; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/usr/include/arch/ppc64/klibc/archsignal.h b/usr/include/arch/ppc64/klibc/archsignal.h new file mode 100644 index 0000000..2c4cef0 --- /dev/null +++ b/usr/include/arch/ppc64/klibc/archsignal.h @@ -0,0 +1,14 @@ +/* + * arch/ppc64/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/ppc64/klibc/archstat.h b/usr/include/arch/ppc64/klibc/archstat.h new file mode 100644 index 0000000..491316c --- /dev/null +++ b/usr/include/arch/ppc64/klibc/archstat.h @@ -0,0 +1,27 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#include + +#define _STATBUF_ST_NSEC + +struct stat { + __stdev64 (st_dev); + ino_t st_ino; + nlink_t st_nlink; + mode_t st_mode; + uid_t st_uid; + gid_t st_gid; + __stdev64 (st_rdev); + off_t st_size; + unsigned long st_blksize; + unsigned long st_blocks; + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ + unsigned long __unused4; + unsigned long __unused5; + unsigned long __unused6; +}; + +#endif diff --git a/usr/klibc/arch/ppc64/MCONFIG b/usr/klibc/arch/ppc64/MCONFIG new file mode 100644 index 0000000..6d8e136 --- /dev/null +++ b/usr/klibc/arch/ppc64/MCONFIG @@ -0,0 +1,26 @@ +# -*- makefile -*- +# +# arch/ppc64/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +KLIBCARCHREQFLAGS = -m64 -mcall-aixdesc +KLIBCOPTFLAGS = -Os +KLIBCBITSIZE = 64 +KLIBCLDFLAGS = -m elf64ppc + +# 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 +# 256-16 MB - normal binaries start at 256 MB, and jumps are limited +# to +/- 16 MB +KLIBCSHAREDFLAGS = -Ttext 0x0f000200 + +# The kernel so far has both asm-ppc* and asm-powerpc. +KLIBCARCHINCFLAGS = -I$(KLIBCKERNELOBJ)arch/$(KLIBCARCH)/include + +# The asm include files live in asm-powerpc +KLIBCASMARCH = powerpc diff --git a/usr/klibc/arch/ppc64/Makefile.inc b/usr/klibc/arch/ppc64/Makefile.inc new file mode 100644 index 0000000..80f6be5 --- /dev/null +++ b/usr/klibc/arch/ppc64/Makefile.inc @@ -0,0 +1,25 @@ +# -*- makefile -*- +# +# arch/ppc64/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 + +KLIBCARCHSOOBJS = $(patsubst %.o,%.lo,$(KLIBCARCHOBJS)) + +INTERP_O = interp1.o + +interp.o: interp1.o klibc.got + $(LD) $(KLIBCLDFLAGS) -r -o $@ interp1.o klibc.got + +klibc.got: $(SOHASH) + $(OBJCOPY) -j .got $< $@ + +archclean: + rm -f klibc.got diff --git a/usr/klibc/arch/ppc64/crt0.S b/usr/klibc/arch/ppc64/crt0.S new file mode 100644 index 0000000..a7776a1 --- /dev/null +++ b/usr/klibc/arch/ppc64/crt0.S @@ -0,0 +1,32 @@ +# +# arch/ppc64/crt0.S +# +# void _start(void) +# { +# /* Divine up argc, argv, and envp */ +# environ = envp; +# exit(main(argc, argv, envp)); +# } +# + + .section ".toc","aw" +.LC0: .tc environ[TC],environ + + .section ".opd","aw" + .align 3 + .globl _start +_start: + .quad ._start + .quad .TOC.@tocbase, 0 + + .text + .globl ._start + .type ._start,@function +._start: + stdu %r1,-32(%r1) + addi %r3,%r1,32 + li %r4,0 /* fini (unused) */ + b .__libc_init + nop + + .size _start,.-_start diff --git a/usr/klibc/arch/ppc64/setjmp.S b/usr/klibc/arch/ppc64/setjmp.S new file mode 100644 index 0000000..30db419 --- /dev/null +++ b/usr/klibc/arch/ppc64/setjmp.S @@ -0,0 +1,85 @@ +# +# arch/ppc64/setjmp.S +# +# Basic setjmp/longjmp implementation +# + + .text + .align 4 + + .section ".opd","aw" +setjmp: + .quad .setjmp,.TOC.@tocbase,0 + .previous + .size setjmp,24 + .type .setjmp,@function + .globl setjmp + .globl .setjmp +.setjmp: + mflr %r11 /* save return address */ + mfcr %r12 /* save condition register */ + std %r2,0(%r3) /* save TOC pointer (not needed) */ + stdu %r1,8(%r3) /* save stack pointer */ + stdu %r11,8(%r3) + stdu %r12,8(%r3) + stdu %r13,8(%r3) /* save caller saved regs */ + stdu %r14,8(%r3) + stdu %r15,8(%r3) + stdu %r16,8(%r3) + stdu %r17,8(%r3) + stdu %r18,8(%r3) + stdu %r19,8(%r3) + stdu %r20,8(%r3) + stdu %r21,8(%r3) + stdu %r22,8(%r3) + stdu %r23,8(%r3) + stdu %r24,8(%r3) + stdu %r25,8(%r3) + stdu %r26,8(%r3) + stdu %r27,8(%r3) + stdu %r28,8(%r3) + stdu %r29,8(%r3) + stdu %r30,8(%r3) + std %r31,8(%r3) + li %r3,0 /* indicate success */ + blr /* return */ + + .size .setjmp,.-.setjmp + .section ".opd","aw" +longjmp: + .quad .longjmp,.TOC.@tocbase,0 + .previous + .size longjmp,24 + .type .longjmp,@function + .globl longjmp + .globl .longjmp +.longjmp: + ld %r2,0(%r3) /* restore TOC pointer (not needed) */ + ldu %r1,8(%r3) /* restore stack */ + ldu %r11,8(%r3) + ldu %r12,8(%r3) + ldu %r13,8(%r3) /* restore caller saved regs */ + ldu %r14,8(%r3) + ldu %r15,8(%r3) + ldu %r16,8(%r3) + ldu %r17,8(%r3) + ldu %r18,8(%r3) + ldu %r19,8(%r3) + ldu %r20,8(%r3) + ldu %r21,8(%r3) + ldu %r22,8(%r3) + ldu %r23,8(%r3) + ldu %r24,8(%r3) + ldu %r25,8(%r3) + ldu %r26,8(%r3) + ldu %r27,8(%r3) + ldu %r28,8(%r3) + ldu %r29,8(%r3) + ldu %r30,8(%r3) + ld %r31,8(%r3) + mtlr %r11 /* restore LR */ + mtcr %r12 /* restore CR */ + mr %r3,%r4 /* get return value */ + blr /* return */ + + .size .longjmp,.-.longjmp diff --git a/usr/klibc/arch/ppc64/syscall.c b/usr/klibc/arch/ppc64/syscall.c new file mode 100644 index 0000000..a5895fe --- /dev/null +++ b/usr/klibc/arch/ppc64/syscall.c @@ -0,0 +1,14 @@ +/* + * arch/ppc64/syscall.c + * + * Common error-handling path for system calls. + * The return value from __syscall_error becomes the + * return value from the system call. + */ +#include + +long int __syscall_error(long int err) +{ + errno = err; + return -1; +} diff --git a/usr/klibc/arch/ppc64/sysstub.ph b/usr/klibc/arch/ppc64/sysstub.ph new file mode 100644 index 0000000..9ee9370 --- /dev/null +++ b/usr/klibc/arch/ppc64/sysstub.ph @@ -0,0 +1,31 @@ +# -*- perl -*- +# +# arch/ppc64/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.globl ${fname}\n"; + print OUT "\t.section \".opd\",\"aw\"\n"; + print OUT "\t.align 3\n"; + print OUT "${fname}:\n"; + print OUT "\t.quad .${fname},.TOC.\@tocbase,0\n"; + print OUT "\t.text\n"; + print OUT "\t.type .${fname},\@function\n"; + print OUT "\t.globl .${fname}\n"; + print OUT ".${fname}:\n"; + print OUT "\tli 0,__NR_${sname}\n"; + print OUT "\tsc\n"; + print OUT "\tbnslr\n"; + print OUT "\tb .__syscall_error\n"; + print OUT "\t.size .${fname},.-.${fname}\n"; + close(OUT); +} + +1;