diff options
Diffstat (limited to 'sysdeps/unix')
30 files changed, 1467 insertions, 72 deletions
diff --git a/sysdeps/unix/alarm.c b/sysdeps/unix/alarm.c index 7743256a09..e0dd3dbf57 100644 --- a/sysdeps/unix/alarm.c +++ b/sysdeps/unix/alarm.c @@ -31,6 +31,7 @@ unsigned int DEFUN(alarm, (seconds), unsigned int seconds) { struct itimerval old, new; + unsigned int retval; new.it_interval.tv_usec = 0; new.it_interval.tv_sec = 0; @@ -39,5 +40,8 @@ DEFUN(alarm, (seconds), unsigned int seconds) if (__setitimer(ITIMER_REAL, &new, &old) < 0) return 0; - return (old.it_value.tv_sec + (old.it_value.tv_usec + 999999) / 1000000); + retval = old.it_value.tv_sec; + if (old.it_value.tv_usec) + ++retval; + return retval; } diff --git a/sysdeps/unix/alpha/sysdep.h b/sysdeps/unix/alpha/sysdep.h new file mode 100644 index 0000000000..9eb9032270 --- /dev/null +++ b/sysdeps/unix/alpha/sysdep.h @@ -0,0 +1,86 @@ +/* Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#ifdef __STDC__ +#define ENTRY(name) \ + .globl name; \ + .align 3; \ + .ent name,0; \ + name##: \ + .frame sp,0,ra +#else +#define ENTRY(name) \ + .globl name; \ + .align 3; \ + .ent name,0; \ + name/**/: \ + .frame sp,0,ra +#endif + +/* Note that while it's better structurally, going back to set errno + can make things confusing if you're debugging---it looks like it's jumping + backwards into the previous fn. */ +#ifdef __STDC__ +#define PSEUDO(name, syscall_name, args) \ + .globl name; \ + .align 3; \ + .ent name,0; \ + \ +1: br gp,2f; \ +2: ldgp gp,0(gp); \ + lda pv,syscall_error; \ + jmp zero,(pv); \ + \ +name##: \ + ldi v0,SYS_ify(syscall_name); \ + .set noat; \ + call_pal PAL_callsys; \ + .set at; \ + bne a3,1b; \ +3: +#else +#define PSEUDO(name, syscall_name, args) \ + .globl name; \ + .align 3; \ + .ent name,0; \ + \ +1: br gp,2f; \ +2: ldgp gp,0(gp); \ + lda pv,syscall_error; \ + jmp zero,(pv); \ + \ +name/**/: \ + ldi v0,SYS_ify(syscall_name); \ + .set noat; \ + call_pal PAL_callsys; \ + .set at; \ + bne a3,1b; \ +3: +#endif + +#define ret ret zero,(ra),1 +#define r0 v0 +#define r1 a4 + +#define MOVE(x,y) mov x,y + +#endif diff --git a/sysdeps/unix/bsd/osf/alpha/sysdep.h b/sysdeps/unix/bsd/osf/alpha/sysdep.h index fc661a6b86..7bd7192c20 100644 --- a/sysdeps/unix/bsd/osf/alpha/sysdep.h +++ b/sysdeps/unix/bsd/osf/alpha/sysdep.h @@ -19,58 +19,11 @@ Cambridge, MA 02139, USA. */ /* OSF/1 does not precede the asm names of C symbols with a `_'. */ #define NO_UNDERSCORES -#include <sysdeps/unix/sysdep.h> +#include <sysdeps/unix/alpha/sysdep.h> -#ifdef ASSEMBLER +#ifdef ASSEMBLER #include <machine/pal.h> /* get PAL_callsys */ #include <regdef.h> -#ifdef __STDC__ -#define ENTRY(name) \ - .globl name; \ - .ent name,0; \ - name##:; \ - .frame sp,0,ra -#else -#define ENTRY(name) \ - .globl name; \ - .ent name,0; \ - name/**/:; \ - .frame sp,0,ra #endif - -#ifdef __STDC__ -#define PSEUDO(name, syscall_name, args) \ - ENTRY(name); \ - ldiq v0, SYS_##syscall_name; \ - .set noat; \ - call_pal PAL_callsys; \ - .set at; \ - beq a3, 10f; \ - br gp, 20f; \ -20:; \ - ldgp gp, 0(gp); \ - jmp zero, syscall_error; \ -10: -#else -#define PSEUDO(name, syscall_name, args) \ - ENTRY(name); \ - ldiq v0, SYS_/**/syscall_name; \ - .set noat; \ - call_pal PAL_callsys; \ - .set at; \ - beq a3, 10f; \ - br gp, 20f; \ -20:; \ - ldgp gp, 0(gp); \ - jmp zero, syscall_error; \ -10: -#endif - -#define ret ret zero,(ra),1 -#define r0 v0 -#define r1 a4 -#define MOVE(x,y) mov x, y - -#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/bsd/pause.c b/sysdeps/unix/common/pause.c index b2fafb958e..b2fafb958e 100644 --- a/sysdeps/unix/bsd/pause.c +++ b/sysdeps/unix/common/pause.c diff --git a/sysdeps/unix/common/syscalls.list b/sysdeps/unix/common/syscalls.list index 654f73afe2..e859dd2ec2 100644 --- a/sysdeps/unix/common/syscalls.list +++ b/sysdeps/unix/common/syscalls.list @@ -8,7 +8,7 @@ getpgid - getpgrp 1 __getpgid getpgid getrusage - getrusage 2 __getrusage getrusage gettimeofday - gettimeofday 2 __gettimeofday gettimeofday settimeofday - settimeofday 2 __settimeofday settimeofday -setpgid - setpgrp 2 __setpgid setpgid setpgrp +setpgid - setpgrp 2 __setpgid setpgid setregid - setregid 2 __setregid setregid setreuid - setreuid 2 __setreuid setreuid sigaction - sigaction 3 __sigaction sigaction diff --git a/sysdeps/unix/sysv/Makefile b/sysdeps/unix/sysv/Makefile index 6bd4240921..28542374f0 100644 --- a/sysdeps/unix/sysv/Makefile +++ b/sysdeps/unix/sysv/Makefile @@ -35,11 +35,5 @@ $(objpfx)termio.h: $(..)sysdeps/unix/sysv/sysv_termio.h endif -ifeq ($(subdir),dirent) - -sysdep_routines := $(sysdep_routines) s_getdents - -endif - # In SYSV style archives the symbol table member has an empty name. ar-symtab-name = diff --git a/sysdeps/unix/sysv/irix4/syscalls.list b/sysdeps/unix/sysv/irix4/syscalls.list index 47e1c48821..a57529e9ad 100644 --- a/sysdeps/unix/sysv/irix4/syscalls.list +++ b/sysdeps/unix/sysv/irix4/syscalls.list @@ -2,7 +2,7 @@ getpgid - bsdgetpgrp 1 __getpgid getpgid msync - msync 3 msync -setpgid - bsdsetpgrp 2 __setpgid setpgid setpgrp +setpgid - bsdsetpgrp 2 __setpgid setpgid signal - signal 3 __raw_signal sysmp - sysmp 4 __sysmp syssgi - syssgi 2 __syssgi diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 79334e6425..c33a1906bf 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -15,7 +15,7 @@ sysdep_routines += fxstat lxstat xstat endif ifeq ($(subdir), misc) -sysdep_routines += xmknod mount umount s_ptrace +sysdep_routines += xmknod s_ptrace headers += sys/mount.h endif diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c index c4b5002801..44a0cbbdb5 100644 --- a/sysdeps/unix/sysv/linux/adjtime.c +++ b/sysdeps/unix/sysv/linux/adjtime.c @@ -20,8 +20,8 @@ Boston, MA 02111-1307, USA. */ #include <sys/time.h> #include <sys/timex.h> -#define MAX_SEC (LONG_MAX / 1000000L - 2) -#define MIN_SEC (LONG_MIN / 1000000L + 2) +#define MAX_SEC (INT_MAX / 1000000L - 2) +#define MIN_SEC (INT_MIN / 1000000L + 2) #ifndef MOD_OFFSET #define modes mode diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile new file mode 100644 index 0000000000..9e12a0daa2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/Makefile @@ -0,0 +1,7 @@ +ifeq ($(subdir), misc) +headers += alpha/regdef.h + +sysdep_routines := $(sysdep_routines) \ + ieee_get_fp_control ieee_set_fp_control fpu_control setfpucw \ + sethae ioperm osf_sigprocmask fstatfs statfs +endif diff --git a/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h b/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h new file mode 100644 index 0000000000..142df9c4f8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h @@ -0,0 +1,44 @@ +#ifndef __alpha_regdef_h__ +#define __alpha_regdef_h__ + +#define v0 $0 /* function return value */ + +#define t0 $1 /* temporary registers (caller-saved) */ +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define t4 $5 +#define t5 $6 +#define t6 $7 +#define t7 $8 + +#define s0 $9 /* saved-registers (callee-saved registers) */ +#define s1 $10 +#define s2 $11 +#define s3 $12 +#define s4 $13 +#define s5 $14 +#define s6 $15 +#define fp s6 /* frame-pointer (s6 in frame-less procedures) */ + +#define a0 $16 /* argument registers (caller-saved) */ +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 + +#define t8 $22 /* more temps (caller-saved) */ +#define t9 $23 +#define t10 $24 +#define t11 $25 +#define ra $26 /* return address register */ +#define t12 $27 + +#define pv t12 /* procedure-variable register */ +#define AT $at /* assembler temporary */ +#define gp $29 /* global pointer */ +#define sp $30 /* stack pointer */ +#define zero $31 /* reads as zero, writes are noops */ + +#endif /* __alpha_regdef_h__ */ diff --git a/sysdeps/unix/sysv/linux/alpha/brk.S b/sysdeps/unix/sysv/linux/alpha/brk.S new file mode 100644 index 0000000000..afd2e3203c --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/brk.S @@ -0,0 +1,60 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* __brk is a special syscall under Linux since it never returns an +error. Instead, the error condition is indicated by returning the old +break value (instead of the new, requested one). */ + +#include <sysdep.h> +#include <errnos.h> + +#ifndef HAVE_GNU_LD +#define _end end +#endif + + .extern _end,8 + + .data + + .globl __curbrk +__curbrk: + .quad _end + + .text +ENTRY(__brk) + ldgp gp, 0(t12) + .prologue 1 + + ldi v0, __NR_brk + call_pal PAL_callsys + subq a0, v0, t0 + bne t0, error + + /* Update __curbrk and return cleanly. */ + stl a0, __curbrk + mov zero, v0 + ret + + /* What a horrible way to die. */ +error: ldi v0, ENOMEM + lda pv, syscall_error + jmp zero,(pv) + + .end __brk + +weak_alias (__brk, brk) diff --git a/sysdeps/unix/sysv/linux/setpgrp.c b/sysdeps/unix/sysv/linux/alpha/fpu_control.c index 4497e07018..20c032a03c 100644 --- a/sysdeps/unix/sysv/linux/setpgrp.c +++ b/sysdeps/unix/sysv/linux/alpha/fpu_control.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1995 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -16,10 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <unistd.h> +#include <fpu_control.h> -int -setpgrp () -{ - return setpgid (0, 0); -} +fpu_control_t __fpu_control = _FPU_DEFAULT; diff --git a/sysdeps/unix/sysv/linux/alpha/fpu_control.h b/sysdeps/unix/sysv/linux/alpha/fpu_control.h new file mode 100644 index 0000000000..782f33e040 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/fpu_control.h @@ -0,0 +1,105 @@ +/* Copyright (C) 1993 Olaf Flebbe +This file is part of the Linux C Library. + +The Linux C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The Linux C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. */ + +#ifndef _ALPHA_FPU_CONTROL_H +#define _ALPHA_FPU_CONTROL_H + +/* + * Since many programs seem to hardcode the values passed to __setfpucw() + * (rather than using the manifest constants) we emulate the x87 interface + * here (at least where this makes sense). + * + * 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0 + * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM + * + * IM: Invalid operation mask + * DM: Denormalized operand mask + * ZM: Zero-divide mask + * OM: Overflow mask + * UM: Underflow mask + * PM: Precision (inexact result) mask + * + * Mask bit is 1 means no interrupt. + * + * PC: Precision control + * 11 - round to extended precision + * 10 - round to double precision + * 00 - round to single precision + * + * RC: Rounding control + * 00 - rounding to nearest + * 01 - rounding down (toward - infinity) + * 10 - rounding up (toward + infinity) + * 11 - rounding toward zero + * + * IC: Infinity control + * That is for 8087 and 80287 only. + * + * The hardware default is 0x037f. I choose 0x1372. + */ + +#include <features.h> + +/* masking of interrupts */ +#define _FPU_MASK_IM 0x01 +#define _FPU_MASK_DM 0x02 +#define _FPU_MASK_ZM 0x04 +#define _FPU_MASK_OM 0x08 +#define _FPU_MASK_UM 0x10 +#define _FPU_MASK_PM 0x20 + +/* precision control */ +#define _FPU_EXTENDED 0x300 /* RECOMMENDED */ +#define _FPU_DOUBLE 0x200 +#define _FPU_SINGLE 0x0 /* DO NOT USE */ + +/* + * rounding control---notice that on the Alpha this affects only + * instructions with the dynamic rounding mode qualifier (/d). + */ +#define _FPU_RC_NEAREST 0x000 /* RECOMMENDED */ +#define _FPU_RC_DOWN 0x400 +#define _FPU_RC_UP 0x800 +#define _FPU_RC_ZERO 0xC00 + +#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */ + + +/* Now two recommended cw */ + +/* Linux default: + - extended precision + - rounding to positive infinity. There is no /p instruction + qualifier. By setting the dynamic rounding mode to +infinity, + one can use /d to get round to +infinity with no extra overhead + (so long as the default isn't changed, of course...) + - exceptions on overflow, zero divide and NaN */ +#define _FPU_DEFAULT 0x1f72 + +/* IEEE: same as above, but exceptions */ +#define _FPU_IEEE 0x1f7f + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +__BEGIN_DECLS + +/* called by start.o. It can be used to manipulate fpu control word. */ +extern void __setfpucw __P ((unsigned short)); + +__END_DECLS + +#endif /* _ALPHA_FPU_CONTROL */ diff --git a/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S b/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S new file mode 100644 index 0000000000..4c86e398d8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S @@ -0,0 +1,44 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#define GSI_IEEE_FP_CONTROL 45 + + .text +ENTRY(__ieee_get_fp_control) + lda sp, -8(sp) + .prologue 1 + + mov sp, a1 + ldi a0, GSI_IEEE_FP_CONTROL + ldi v0, __NR_osf_getsysinfo + call_pal PAL_callsys + bne a3, error + + ldq v0, 0(sp) + lda sp, 8(sp) + ret + +error: lda sp, 8(sp) + lda pv, syscall_error + jmp zero,(pv) + + .end __ieee_get_fp_control + +weak_alias (__ieee_get_fp_control, ieee_get_fp_control) diff --git a/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S b/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S new file mode 100644 index 0000000000..d10e9bc24c --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S @@ -0,0 +1,44 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#define SSI_IEEE_FP_CONTROL 14 + + .text +ENTRY(__ieee_set_fp_control) + lda sp, -8(sp) + .prologue 1 + + stq a0, 0(sp) + mov sp, a1 + ldi a0, SSI_IEEE_FP_CONTROL + ldi v0, __NR_osf_setsysinfo + call_pal PAL_callsys + + lda sp, 8(sp) + + bne a3, error + ret + +error: lda pv, syscall_error + jmp zero,(pv) + + .end __ieee_set_fp_control + +weak_alias (__ieee_set_fp_control, ieee_set_fp_control) diff --git a/sysdeps/unix/sysv/linux/alpha/ioperm.c b/sysdeps/unix/sysv/linux/alpha/ioperm.c new file mode 100644 index 0000000000..306c86b96a --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/ioperm.c @@ -0,0 +1,441 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by David Mosberger. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* I/O access is restricted to ISA port space (ports 0..65535). +Modern devices hopefully are sane enough not to put any performance +critical registers in i/o space. + +On the first call to ioperm() or _sethae(), the entire (E)ISA port +space is mapped into the virtual address space at address io.base. +mprotect() calls are then used to enable/disable access to ports. Per +page, there are PAGE_SIZE>>IO_SHIFT I/O ports (e.g., 256 ports on a +Low Cost Alpha based system using 8KB pages). + +Keep in mind that this code should be able to run in a 32bit address +space. It is therefore unreasonable to expect mmap'ing the entire +sparse address space would work (e.g., the Low Cost Alpha chip has an +I/O address space that's 512MB large!). */ + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/mman.h> + +#include <asm/io.h> +#include <asm/page.h> +#include <asm/system.h> + +#undef inb +#undef inw +#undef inl +#undef outb +#undef outw +#undef outl + +#define PATH_CPUINFO "/proc/cpuinfo" + +#define MAX_PORT 0x10000 +#define vuip volatile unsigned int * + +#define JENSEN_IO_BASE (IDENT_ADDR + 0x0300000000UL) +#define APECS_IO_BASE (IDENT_ADDR + 0x01c0000000UL) +#define ALCOR_IO_BASE (IDENT_ADDR + 0x8580000000UL) + +enum { + IOSYS_JENSEN = 0, IOSYS_APECS = 1, IOSYS_ALCOR = 2 +} iosys_t; + +struct ioswtch { + void (*sethae)(unsigned long addr); + void (*outb)(unsigned char b, unsigned long port); + void (*outw)(unsigned short b, unsigned long port); + void (*outl)(unsigned int b, unsigned long port); + unsigned int (*inb)(unsigned long port); + unsigned int (*inw)(unsigned long port); + unsigned int (*inl)(unsigned long port); +}; + +static struct platform { + const char *name; + int io_sys; +} platform[] = { + {"Alcor", IOSYS_ALCOR}, + {"Avanti", IOSYS_APECS}, + {"Cabriolet", IOSYS_APECS}, + {"EB64+", IOSYS_APECS}, + {"EB66", IOSYS_APECS}, + {"EB66P", IOSYS_APECS}, + {"Jensen", IOSYS_JENSEN}, + {"Mustang", IOSYS_APECS}, + {"Noname", IOSYS_APECS}, +}; + + +static struct { + struct hae hae; + unsigned long base; + struct ioswtch * swp; + int sys; +} io; + + +static inline unsigned long +port_to_cpu_addr (unsigned long port, int iosys, int size) +{ + if (iosys == IOSYS_JENSEN) { + return (port << 7) + ((size - 1) << 4) + io.base; + } else { + return (port << 5) + ((size - 1) << 3) + io.base; + } +} + + +static inline void +inline_sethae (unsigned long addr, int iosys) +{ + if (iosys == IOSYS_JENSEN) { + /* hae on the Jensen is bits 31:25 shifted right */ + addr >>= 25; + if (addr != io.hae.cache) { + __sethae (addr); + io.hae.cache = addr; + } + } else { + unsigned long msb; + + /* no need to set hae if msb is 0: */ + msb = addr & 0xf8000000; + if (msb && msb != io.hae.cache) { + __sethae (msb); + io.hae.cache = msb; + } + } +} + + +static inline void +inline_outb (unsigned char b, unsigned long port, int iosys) +{ + unsigned int w; + unsigned long addr = port_to_cpu_addr (port, iosys, 1); + + inline_sethae (0, iosys); + asm ("insbl %2,%1,%0" : "r=" (w) : "ri" (port & 0x3), "r" (b)); + *(vuip)addr = w; + mb (); +} + + +static inline void +inline_outw (unsigned short b, unsigned long port, int iosys) +{ + unsigned int w; + unsigned long addr = port_to_cpu_addr (port, iosys, 2); + + inline_sethae (0, iosys); + asm ("inswl %2,%1,%0" : "r=" (w) : "ri" (port & 0x3), "r" (b)); + *(vuip)addr = w; + mb (); +} + + +static inline void +inline_outl (unsigned int b, unsigned long port, int iosys) +{ + unsigned long addr = port_to_cpu_addr (port, iosys, 4); + + if (port >= MAX_PORT) + return; + + inline_sethae (0, iosys); + *(vuip)addr = b; + mb (); +} + + +static inline unsigned int +inline_inb (unsigned long port, int iosys) +{ + unsigned long result, addr = port_to_cpu_addr (port, iosys, 1); + + inline_sethae (0, iosys); + result = *(vuip) addr; + result >>= (port & 3) * 8; + return 0xffUL & result; +} + + +static inline unsigned int +inline_inw (unsigned long port, int iosys) +{ + unsigned long result, addr = port_to_cpu_addr (port, iosys, 2); + + inline_sethae (0, iosys); + result = *(vuip) addr; + result >>= (port & 3) * 8; + return 0xffffUL & result; +} + + +static inline unsigned int +inline_inl (unsigned long port, int iosys) +{ + unsigned long addr = port_to_cpu_addr (port, iosys, 4); + + inline_sethae (0, iosys); + return *(vuip) addr; +} + + +#define DCL_SETHAE(name, iosys) \ +static void \ +name##_sethae (unsigned long addr) \ +{ \ + inline_sethae (addr, IOSYS_##iosys); \ +} + +#define DCL_OUT(name, func, type, iosys) \ +static void \ +name##_##func (unsigned type b, unsigned long addr) \ +{ \ + inline_##func (b, addr, IOSYS_##iosys); \ +} + + +#define DCL_IN(name, func, iosys) \ +static unsigned int \ +name##_##func (unsigned long addr) \ +{ \ + return inline_##func (addr, IOSYS_##iosys); \ +} + + +DCL_SETHAE(jensen, JENSEN) +DCL_OUT(jensen, outb, char, JENSEN) +DCL_OUT(jensen, outw, short, JENSEN) +DCL_OUT(jensen, outl, int, JENSEN) +DCL_IN(jensen, inb, JENSEN) +DCL_IN(jensen, inw, JENSEN) +DCL_IN(jensen, inl, JENSEN) + +/* The APECS functions are also used for ALCOR since they are + identical. */ + +DCL_SETHAE(apecs, APECS) +DCL_OUT(apecs, outb, char, APECS) +DCL_OUT(apecs, outw, short, APECS) +DCL_OUT(apecs, outl, int, APECS) +DCL_IN(apecs, inb, APECS) +DCL_IN(apecs, inw, APECS) +DCL_IN(apecs, inl, APECS) + +struct ioswtch ioswtch[] = { + { + jensen_sethae, + jensen_outb, jensen_outw, jensen_outl, + jensen_inb, jensen_inw, jensen_inl + }, + { + apecs_sethae, + apecs_outb, apecs_outw, apecs_outl, + apecs_inb, apecs_inw, apecs_inl + } +}; + + +static int +init_iosys (void) +{ + char name[256], value[256]; + FILE * fp; + int i; + + fp = fopen (PATH_CPUINFO, "r"); + if (!fp) + return -1; + + while (fscanf (fp, "%256[^:]: %256[^\n]\n", name, value) == 2) { + if (strncmp (name, "system type", 11) == 0) { + for (i = 0; i < sizeof (platform) / sizeof (platform[0]); ++i) { + if (strcmp (platform[i].name, value) == 0) { + fclose (fp); + io.sys = platform[i].io_sys; + if (io.sys == IOSYS_JENSEN) + io.swp = &ioswtch[0]; + else + io.swp = &ioswtch[1]; + return 0; + } + } + } + } + fclose (fp); + errno = ENODEV; + return -1; +} + + +int +_ioperm (unsigned long from, unsigned long num, int turn_on) +{ + unsigned long addr, len; + int prot; + + if (!io.swp && init_iosys () < 0) + return -1; + + /* this test isn't as silly as it may look like; consider overflows! */ + if (from >= MAX_PORT || from + num > MAX_PORT) { + errno = EINVAL; + return -1; + } + + if (turn_on) { + if (!io.base) { + unsigned long base; + int fd; + + io.hae.reg = 0; /* not used in user-level */ + io.hae.cache = 0; + __sethae (io.hae.cache); /* synchronize with hw */ + + fd = open ("/dev/mem", O_RDWR); + if (fd < 0) + return fd; + + switch (io.sys) { + case IOSYS_JENSEN: base = JENSEN_IO_BASE; break; + case IOSYS_APECS: base = APECS_IO_BASE; break; + case IOSYS_ALCOR: base = ALCOR_IO_BASE; break; + default: + errno = ENODEV; + return -1; + } + addr = port_to_cpu_addr (from, io.sys, 1); + addr &= PAGE_MASK; + len = port_to_cpu_addr (MAX_PORT, io.sys, 1) - addr; + io.base = + (unsigned long) __mmap (0, len, PROT_NONE, MAP_SHARED, fd, base); + close (fd); + if ((long) io.base == -1) + return -1; + } + prot = PROT_READ | PROT_WRITE; + } else { + if (!io.base) + return 0; /* never was turned on... */ + + /* turnoff access to relevant pages: */ + prot = PROT_NONE; + } + addr = port_to_cpu_addr (from, io.sys, 1); + addr &= PAGE_MASK; + len = port_to_cpu_addr (from + num, io.sys, 1) - addr; + return mprotect ((void *) addr, len, prot); +} + + +int +_iopl (unsigned int level) +{ + if (level > 3) { + errno = EINVAL; + return -1; + } + if (level) { + return _ioperm (0, MAX_PORT, 1); + } + return 0; +} + + +void +_sethae (unsigned long addr) +{ + if (!io.swp && init_iosys () < 0) + return; + + io.swp->sethae (addr); +} + + +void +_outb (unsigned char b, unsigned long port) +{ + if (port >= MAX_PORT) + return; + + io.swp->outb (b, port); +} + + +void +_outw (unsigned short b, unsigned long port) +{ + if (port >= MAX_PORT) + return; + + io.swp->outw (b, port); +} + + +void +_outl (unsigned int b, unsigned long port) +{ + if (port >= MAX_PORT) + return; + + io.swp->outl (b, port); +} + + +unsigned int +_inb (unsigned long port) +{ + return io.swp->inb (port); +} + + +unsigned int +_inw (unsigned long port) +{ + return io.swp->inw (port); +} + + +unsigned int +_inl (unsigned long port) +{ + return io.swp->inl (port); +} + + +weak_alias (_sethae, sethae); +weak_alias (_ioperm, ioperm); +weak_alias (_iopl, iopl); +weak_alias (_inb, inb); +weak_alias (_inw, inw); +weak_alias (_inl, inl); +weak_alias (_outb, outb); +weak_alias (_outw, outw); +weak_alias (_outl, outl); diff --git a/sysdeps/unix/sysv/linux/alpha/pipe.S b/sysdeps/unix/sysv/linux/alpha/pipe.S new file mode 100644 index 0000000000..f613b08fe0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/pipe.S @@ -0,0 +1,43 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* __pipe is a special syscall since it returns two values. */ + +#include <sysdep.h> + + .text +ENTRY(__pipe) + .prologue 0 + + ldi v0, __NR_pipe + call_pal PAL_callsys + bne a3, error + + stl r0, 0(a0) + stl r1, 4(a0) + mov zero, v0 + ret + +error: br gp, 1f +1: ldgp gp, 0(gp) + lda pv, syscall_error + jmp zero, (pv) + + .end __pipe + +weak_alias (__pipe, pipe) diff --git a/sysdeps/unix/sysv/linux/alpha/profil-counter.h b/sysdeps/unix/sysv/linux/alpha/profil-counter.h new file mode 100644 index 0000000000..6ab5a88c49 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/profil-counter.h @@ -0,0 +1,28 @@ +/* Low-level statistical profiling support function. Mostly POSIX.1 version. +Copyright (C) 1996 Free Software Foundation, Inc. +Contributed by David Mosberger <davidm@azstarnet.com> +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <asm/sigcontext.h> + +void +profil_counter (int signal, long a1, long a2, long a3, long a4, long a5, + struct sigcontext_struct sc) +{ + profil_count((void *) sc.sc_pc); +} diff --git a/sysdeps/unix/sysv/linux/alpha/setfpucw.c b/sysdeps/unix/sysv/linux/alpha/setfpucw.c new file mode 100644 index 0000000000..43e8536b20 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/setfpucw.c @@ -0,0 +1,65 @@ +#include <fpu_control.h> + +#include <asm/fpu.h> + +extern void __ieee_set_fp_control (unsigned long); +extern unsigned long __ieee_get_fp_control (void); + + +static inline unsigned long +rdfpcr (void) +{ + unsigned long fpcr; + + asm ("trapb; mf_fpcr $f0; trapb; stt $f0,%0" : "m="(fpcr)); + return fpcr; +} + + +static inline void +wrfpcr (unsigned long fpcr) +{ + asm volatile ("ldt $f0,%0; trapb; mt_fpcr $f0; trapb" :: "m"(fpcr)); +} + + +void +__setfpucw (unsigned short fpu_control) +{ + unsigned long fpcr = 0, fpcw = 0; + + if (!fpu_control) + fpu_control = _FPU_DEFAULT; + + /* first, set dynamic rounding mode: */ + + fpcr = rdfpcr(); + fpcr &= ~FPCR_DYN_MASK; + switch (fpu_control & 0xc00) { + case _FPU_RC_NEAREST: fpcr |= FPCR_DYN_NORMAL; break; + case _FPU_RC_DOWN: fpcr |= FPCR_DYN_MINUS; break; + case _FPU_RC_UP: fpcr |= FPCR_DYN_PLUS; break; + case _FPU_RC_ZERO: fpcr |= FPCR_DYN_CHOPPED; break; + } + wrfpcr(fpcr); + + /* now tell kernel about traps that we like to hear about: */ + + fpcw = __ieee_get_fp_control(); + fpcw &= ~IEEE_TRAP_ENABLE_MASK; + + if (!(fpu_control & _FPU_MASK_IM)) + fpcw |= IEEE_TRAP_ENABLE_INV; + if (!(fpu_control & _FPU_MASK_DM)) + fpcw |= IEEE_TRAP_ENABLE_UNF; + if (!(fpu_control & _FPU_MASK_ZM)) + fpcw |= IEEE_TRAP_ENABLE_DZE; + if (!(fpu_control & _FPU_MASK_OM)) + fpcw |= IEEE_TRAP_ENABLE_OVF; + if (!(fpu_control & _FPU_MASK_PM)) + fpcw |= IEEE_TRAP_ENABLE_INE; + + __ieee_set_fp_control(fpcw); + + __fpu_control = fpu_control; /* update global copy */ +} diff --git a/sysdeps/unix/sysv/linux/alpha/sigprocmask.c b/sysdeps/unix/sysv/linux/alpha/sigprocmask.c new file mode 100644 index 0000000000..a1d5636fcb --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/sigprocmask.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#include <signal.h> + +extern unsigned long __osf_sigprocmask (int how, unsigned long newmask); + +int +__sigprocmask (int how, const sigset_t *set, sigset_t *oset) +{ + sigset_t setval; + long result; + + if (set) { + setval = *set; + } else { + sigemptyset(&setval); + how = SIG_BLOCK; /* ensure blocked mask doesn't get changed */ + } + result = __osf_sigprocmask(how, setval); + if (result == -1) { + /* if there are ever more than 63 signals, we need to recode this + in assembler since we wouldn't be able to distinguish a mask of + all 1s from -1, but for now, we're doing just fine... */ + return result; + } + if (oset) { + *oset = result; + } + return 0; +} + +weak_alias (__sigprocmask, sigprocmask); diff --git a/sysdeps/unix/sysv/linux/alpha/sigsuspend.S b/sysdeps/unix/sysv/linux/alpha/sigsuspend.S new file mode 100644 index 0000000000..29cba8d312 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/sigsuspend.S @@ -0,0 +1,39 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* sigsuspend is a special syscall since it needs to dereference the +sigset. */ + +#include <sysdep.h> + + .text +ENTRY(sigsuspend) + .prologue 0 + + ldq a0, 0(a0) + ldi v0, __NR_sigsuspend + call_pal PAL_callsys + bne a3, error + ret + +error: br gp, 1f +1: ldgp gp, 0(gp) + lda pv, syscall_error + jmp zero, (pv) + + .end sigsuspend diff --git a/sysdeps/unix/sysv/linux/alpha/speed.c b/sysdeps/unix/sysv/linux/alpha/speed.c new file mode 100644 index 0000000000..b61cfbbfe3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/speed.c @@ -0,0 +1,102 @@ +/* `struct termios' speed frobnication functions. Linux version. +Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stddef.h> +#include <errno.h> +#include <termios.h> + +static const speed_t speeds[] = + { + 0, + 50, + 75, + 110, + 134, + 150, + 200, + 300, + 600, + 1200, + 1800, + 2400, + 4800, + 9600, + 19200, + 38400, + 57600, + 115200, + 230400, + }; + + +/* Return the output baud rate stored in *TERMIOS_P. */ +speed_t +cfgetospeed (termios_p) + const struct termios *termios_p; +{ + speed_t retval = termios_p->c_cflag & (CBAUD | CBAUDEX); + + if (retval & CBAUDEX) + { + retval &= ~CBAUDEX; + retval |= CBAUD + 1; + } + + return retval; +} + +/* Return the input baud rate stored in *TERMIOS_P. + For Linux there is no difference between input and output speed. */ +strong_alias (cfgetospeed, cfgetispeed); + +/* Set the output baud rate stored in *TERMIOS_P to SPEED. */ +int +cfsetospeed (termios_p, speed) + struct termios *termios_p; + speed_t speed; +{ + register unsigned int i; + + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + + /* This allows either B1200 or 1200 to work. XXX + Do we really want to try to support this, given that + fetching the speed must return one or the other? */ + + for (i = 0; i < sizeof (speeds) / sizeof (speeds[0]); ++i) + if (i == speed || speeds[i] == speed) + { + termios_p->c_cflag &= ~(CBAUD | CBAUDEX); + termios_p->c_cflag |= (i & CBAUD); + if (i & ~CBAUD) + termios_p->c_cflag |= CBAUDEX; + return 0; + } + + errno = EINVAL; + return -1; +} + +/* Set the input baud rate stored in *TERMIOS_P to SPEED. + For Linux there is no difference between input and output speed. */ +strong_alias (cfsetospeed, cfsetispeed); diff --git a/sysdeps/unix/sysv/linux/alpha/start.S b/sysdeps/unix/sysv/linux/alpha/start.S new file mode 100644 index 0000000000..d1966a82ba --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/start.S @@ -0,0 +1,93 @@ +/* Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.comm errno, 4 + + .text +ENTRY(__start) + lda sp, -16(sp) + stq zero, 8(sp) /* terminate frame chain */ + + br t0, 1f +1: ldgp gp, 0(t0) + + mov zero, a0 /* establish __fpu_control w/kernel */ + jsr ra, __setfpucw + ldgp gp, 0(ra) + + /* clear out errno. */ + lda t0, errno + stl zero, 0(t0) + + ldl a0, 16(sp) /* get argc */ + lda a1, 24(sp) /* get argv */ + + /* initialize environ: */ + lda t0, environ + s8addq a0, a1, a2 + addq a2, 0x8, a2 + stq a2, 0(t0) + +#ifndef HAVE_INITFINI + mov a0, s0 + mov a1, s1 + mov a2, s2 + + jsr ra, __libc_init + ldgp gp, 0(ra) + + mov s0, a0 + mov s1, a1 + mov s2, a2 + + /* initialize constructors: */ + jsr ra, __main + ldgp gp, 0(ra) + + mov s0, a0 + mov s1, a1 + mov s2, a2 +#endif + + jsr ra, main + ldgp gp, 0(ra) + + mov v0, a0 + + lda pv, exit + jsr ra, (pv), 1 + ldgp gp, 0(ra) + + /* in case exit returns: */ + +1: ldi v0, __NR_exit + call_pal PAL_callsys + br 1b + + .end __start + + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + +weak_alias(__data_start, data_start) diff --git a/sysdeps/unix/sysv/linux/alpha/syscall.S b/sysdeps/unix/sysv/linux/alpha/syscall.S new file mode 100644 index 0000000000..54a8484c58 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/syscall.S @@ -0,0 +1,61 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* + * This is for COMPATIBILITY with Linux/x86 only. Linux/Alpha system + * calls return an error indication in a3. This allows to return + * arbitrary 64bit values in v0 (because negative values are not + * mistaken as error numbers). However, C allows to return only one + * value so the interface below folds the error indication passed in + * a3 back into v0: it sets v0 to -errno if an error occurs. Thus, + * no negative 64bit numbers can be returned. To avoid this problem, + * use assembly stubs wherever possible/convenient. + * + * Usage: + * + * long syscall(syscall_number, arg1, arg2, arg3, arg4, arg5) + * + * syscall_number = the index of the system call we're invoking + * arg1-arg5 = up to 5 integer arguments to the system call + * + * We need to do some arg shifting: the kernel expects the + * syscall number in v0 and the first five args in a0-a4. + * + */ + + +1: br gp,2f +2: ldgp gp,0(gp) + jmp zero,syscall_error + + +ENTRY (__syscall) + bis a0,a0,v0 # Syscall number -> v0 + bis a1,a1,a0 # arg1-arg5 -> a0-a4 + bis a2,a2,a1 + bis a3,a3,a2 + bis a4,a4,a3 + bis a5,a5,a4 + + call_pal PAL_callsys # Invoke system call + bne a3,1b + ret + +weak_alias(__syscall, syscall) diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list new file mode 100644 index 0000000000..a842908901 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list @@ -0,0 +1,45 @@ +# File name Caller Syscall name # args Strong name Weak names + +# used to implement inb()/outb() etc. +sethae - sethae 1 __sethae + +msgctl - msgctl 3 __msgctl msgctl +msgget - msgget 2 __msgget msgget +msgrcv - msgrcv 5 __msgrcv msgrcv +msgsnd - msgsnd 4 __msgsnd msgsnd +shmat - osf_shmat 3 __shmat shmat +shmctl - shmctl 3 __shmctl shmctl +shmdt - shmdt 1 __shmdt shmdt +shmget - shmget 3 __shmget shmget +semop - semop 3 __semop semop +semget - semget 3 __semget semget +semctl - semctl 4 __semctl semctl + +osf_sigprocmask - osf_sigprocmask 2 __osf_sigprocmask + +getdents - getdents 3 __getdirentries getdirentries +getpeername - getpeername 3 __getpeername getpeername +getpriority - getpriority 2 __getpriority getpriority +mmap - mmap 6 __mmap mmap + +# these are actually common with the x86: +fstatfs - fstatfs 2 __fstatfs fstatfs +statfs - statfs 2 __statfs statfs + +# override select.S in parent directory: +select - select 5 __select select +accept - accept 3 __accept accept +bind - bind 3 __bind bind +connect - connect 3 __connect connect +getpeername - getpeername 3 __getpeername getpeername +getsockname - getsockname 3 __getsockname getsockname +listen - listen 2 __listen listen +recv - recv 4 __recv recv +recvfrom - recvfrom 6 __recvfrom recvfrom +recvmsg - recvmsg 3 __recvmsg recvmsg +send - send 4 __send send +sendmsg - sendmsg 3 __sendmsg sendmsg +sendto - sendto 6 __sendto sendto +setsockopt - setsockopt 5 __setsockopt setsockopt +shutdown - shutdown 2 __shutdown shutdown +socketpair - socketpair 4 __socketpair socketpair diff --git a/sysdeps/unix/sysv/linux/alpha/sysdep.S b/sysdeps/unix/sysv/linux/alpha/sysdep.S new file mode 100644 index 0000000000..74b153e7b9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/sysdep.S @@ -0,0 +1,33 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#define _ERRNO_H +#include <errnos.h> + +ENTRY(syscall_error) + /* Store return value in errno... */ + ldgp gp, 0(t12) + lda t0, errno + stl v0, 0(t0) + + /* And just kick back a -1. */ + ldi v0, -1 + ret + + .end syscall_error diff --git a/sysdeps/unix/sysv/linux/alpha/sysdep.h b/sysdeps/unix/sysv/linux/alpha/sysdep.h new file mode 100644 index 0000000000..febfa3a4fb --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/sysdep.h @@ -0,0 +1,60 @@ +/* Copyright (C) 1992, 1993, 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* In the Linux ELF and ECOFF worlds, C symbols are asm symbols. */ +#define NO_UNDERSCORES + +#ifdef ASSEMBLER + +#include <asm/pal.h> +#include <alpha/regdef.h> + +#endif + +/* There is some commonality. */ +#include <sysdeps/unix/alpha/sysdep.h> + +/* For Linux we can use the system call table in the header file + /usr/include/asm/unistd.h + of the kernel. But these symbols do not follow the SYS_* syntax + so we have to redefine the `SYS_ify' macro here. */ +#undef SYS_ify +#ifdef __STDC__ +# define SYS_ify(syscall_name) __NR_##syscall_name +#else +# define SYS_ify(syscall_name) __NR_/**/syscall_name +#endif + +/* + * Define some aliases for syscalls that return two values (in r0 and r1): + */ +#define __NR_getpid __NR_getxpid +#define __NR_getppid __NR_getxpid +#define __NR_getuid __NR_getxuid +#define __NR_geteuid __NR_getxuid +#define __NR_getgid __NR_getxgid +#define __NR_getegid __NR_getxgid + +/* + * Some syscalls no Linux program should know about: + */ +#define __NR_osf_sigprocmask 48 +#define __NR_osf_shmat 209 +#define __NR_osf_getsysinfo 256 +#define __NR_osf_setsysinfo 257 diff --git a/sysdeps/unix/sysv/linux/sys/mman.h b/sysdeps/unix/sysv/linux/sys/mman.h index 007dbfd6d6..33361549f9 100644 --- a/sysdeps/unix/sysv/linux/sys/mman.h +++ b/sysdeps/unix/sysv/linux/sys/mman.h @@ -66,7 +66,7 @@ int mprotect __P ((__caddr_t __addr, size_t __len, int __prot)); /* Synchronize the region starting at ADDR and extending LEN bytes with the file it maps. Filesystem operations on a file being mapped are unpredictable before this is done. */ -int msync __P ((__caddr_t __addr, size_t __len)); +int msync __P ((__caddr_t __addr, size_t __len, int flags)); /* Advise the system about particular usage patterns the program follows for the region starting at ADDR and extending LEN bytes. */ diff --git a/sysdeps/unix/sysv/sysv4/setpgid.c b/sysdeps/unix/sysv/sysv4/setpgid.c index b9e06dc719..743b8ca374 100644 --- a/sysdeps/unix/sysv/sysv4/setpgid.c +++ b/sysdeps/unix/sysv/sysv4/setpgid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,4 +32,3 @@ DEFUN(__setpgid, (pid, pgid), int pid AND int pgid) } weak_alias (__setpgid, setpgid) -weak_alias (__setpgid, setpgrp) |