diff options
Diffstat (limited to 'boot')
-rw-r--r-- | boot/ux.c | 243 | ||||
-rw-r--r-- | boot/ux.h | 108 |
2 files changed, 351 insertions, 0 deletions
diff --git a/boot/ux.c b/boot/ux.c new file mode 100644 index 00000000..46e2f130 --- /dev/null +++ b/boot/ux.c @@ -0,0 +1,243 @@ +/* Hacks to make boot work under UX + + Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + The GNU Hurd 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <mach.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <cthreads.h> + +#include "ux.h" + +extern void __mach_init (); +void (*mach_init_routine)() = __mach_init; + +/* These will prevent the Hurd-ish versions from being used */ + +struct free_reply_port +{ + mach_port_t port; + struct free_reply_port *next; +}; +static struct free_reply_port *free_reply_ports = NULL; +static spin_lock_t free_reply_ports_lock = SPIN_LOCK_INITIALIZER; + +mach_port_t __mig_get_reply_port () +{ + spin_lock (&free_reply_ports_lock); + if (free_reply_ports == NULL) + { + spin_unlock (&free_reply_ports_lock); + return __mach_reply_port (); + } + else + { + struct free_reply_port *frp = free_reply_ports; + mach_port_t reply_port = frp->port; + free_reply_ports = free_reply_ports->next; + spin_unlock (&free_reply_ports_lock); + free (frp); + return reply_port; + } +} +mach_port_t mig_get_reply_port () +{ + return __mig_get_reply_port (); +} +void __mig_put_reply_port (mach_port_t port) +{ + struct free_reply_port *frp = malloc (sizeof (struct free_reply_port)); + frp->port = port; + spin_lock (&free_reply_ports_lock); + frp->next = free_reply_ports; + free_reply_ports = frp; + spin_unlock (&free_reply_ports_lock); +} +void mig_put_reply_port (mach_port_t port) +{ + __mig_put_reply_port (port); +} +void __mig_dealloc_reply_port (mach_port_t port) +{ + mach_port_mod_refs (__mach_task_self (), port, + MACH_PORT_RIGHT_RECEIVE, -1); +} +void mig_dealloc_reply_port (mach_port_t port) +{ + __mig_dealloc_reply_port (port); +} +void __mig_init (void *stack) {} +void mig_init (void *stack) {} + +int +task_by_pid (int pid) +{ + return syscall (-33, pid); +} + +int +write (int fd, + const void *buf, + int buflen) +{ + return syscall (4, fd, buf, buflen); +} + +int +read (int fd, + void *buf, + int buflen) +{ + return syscall (3, fd, buf, buflen); +} + +int +open (const char *name, + int flags, + int mode) +{ + return syscall (5, name, flags, mode); +} + +int +uxfstat (int fd, struct uxstat *buf) +{ + return syscall (62, fd, buf); +} + +int +close (int fd) +{ + return syscall (6, fd); +} + +int +lseek (int fd, + int off, + int whence) +{ + return syscall (19, fd, off, whence); +} + +int +uxexit (int code) +{ + return syscall (1, code); +} + +int +getpid () +{ + return syscall (20); +} + +int +ioctl (int fd, int code, void *buf) +{ + return syscall (54, fd, code, buf); +} + +int +sigblock (int mask) +{ + return syscall (109, mask); +} + +int +sigsetmask (int mask) +{ + return syscall (110, mask); +} + +int +sigpause (int mask) +{ + return syscall (111, mask); +} + + +#if 0 +void +sigreturn () +{ + asm volatile ("movl $0x67,%eax\n" + "lcall $0x7, $0x0\n" + "ret"); +} + +void +_sigreturn () +{ + asm volatile ("addl $0xc, %%esp\n" + "call %0\n" + "ret"::"m" (sigreturn)); +} + +int +sigvec (int sig, struct sigvec *vec, struct sigvec *ovec) +{ + asm volatile ("movl $0x6c,%%eax\n" + "movl %0, %%edx\n" + "orl $0x80000000, %%edx\n" + "lcall $0x7,$0x0\n" + "ret"::"g" (_sigreturn)); +} +#else +int sigvec (); +#endif + +void get_privileged_ports (mach_port_t *host_port, mach_port_t *device_port) +{ + *host_port = task_by_pid (-1); + *device_port = task_by_pid (-2); +} + +/* A *really* stupid printf that only understands %s. */ +int +printf (const char *fmt, ...) +{ + va_list ap; + const char *p = fmt, *q = p; + + void flush (const char *new) + { + if (p > q) + write (1, q, p - q); + q = p = new; + } + + va_start (ap, fmt); + while (*p) + if (*p == '%' && p[1] == 's') + { + char *str = va_arg (ap, char *); + flush (p + 2); + write (1, str, strlen (str)); + } + else + p++; + va_end (ap); + + flush (0); + + return 0; +} diff --git a/boot/ux.h b/boot/ux.h new file mode 100644 index 00000000..e9c87ed0 --- /dev/null +++ b/boot/ux.h @@ -0,0 +1,108 @@ +/* Hacks to make boot work under UX + + Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + The GNU Hurd 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define sigmask(m) (1 << ((m)-1)) + +#define IOCPARM_MASK 0x7f +#define IOC_OUT 0x40000000 +#define IOC_IN 0x80000000 +#define _IOR(x,y,t) (IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y) +#define _IOW(x,y,t) (IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y) +#define FIONREAD _IOR('f', 127, int) +#define FIOASYNC _IOW('f', 125, int) +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCLGET _IOR('t', 124, int) +#define TIOCLSET _IOW('t', 125, int) +#define TIOCSETN _IOW('t', 10, struct sgttyb) +#define LDECCTQ 0x4000 +#define LLITOUT 0x0020 +#define LPASS8 0x0800 +#define LNOFLSH 0x8000 +#define RAW 0x0020 +#define ANYP 0x00c0 +#define ECHO 8 + + +struct sgttyb +{ + char unused[4]; + short sg_flags; +}; + +#define SIGIO 23 + +struct sigvec +{ + void (*sv_handler)(); + int sv_mask; + int sv_flags; +}; + +struct uxstat + { + short int st_dev; /* Device containing the file. */ + __ino_t st_ino; /* File serial number. */ + unsigned short int st_mode; /* File mode. */ + __nlink_t st_nlink; /* Link count. */ + unsigned short int st_uid; /* User ID of the file's owner. */ + unsigned short int st_gid; /* Group ID of the file's group.*/ + short int st_rdev; /* Device number, if device. */ + __off_t st_size; /* Size of file, in bytes. */ + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atime_usec; + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtime_usec; + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctime_usec; + unsigned long int st_blksize; /* Optimal block size for I/O. */ + unsigned long int st_blocks; /* Number of 512-byte blocks allocated. */ + long int st_spare[2]; + }; + +void get_privileged_ports (mach_port_t *host_port, mach_port_t *device_port); + +/* We can't include <unistd.h> for this, because that will fight witho + our definitions of syscalls below. */ +int syscall (int, ...); + +int open (const char *name, int flags, int mode); +int write (int fd, const void *buf, int len); +int read (int fd, void *buf, int len); +int uxfstat (int fd, struct uxstat *buf); +int close (int fd); +int lseek (int fd, int off, int whence); +int uxexit (int code); +int getpid (); +int ioctl (int fd, int code, void *buf); +int sigblock (int mask); +int sigsetmask (int mask); +int sigpause (int mask); +int sigvec (int sig, struct sigvec *vec, struct sigvec *ovec); + + +#define host_exit(c) uxexit(c) + +typedef struct uxstat host_stat_t; +#define host_fstat(fd, st) uxfstat (fd, st) + +void init_stdio (); + +#undef errno +int errno; |