--- /dev/null
+.include <bsd.own.mk>
+.PATH: ${.CURDIR} ${.CURDIR}/${MACHINE}
+INCSDIR= /usr/netbsd/include
+LIB= minlib
+
+CPPFLAGS.fslib.c+= -I${MINIXSRCDIR}/servers
+CPPFLAGS.fsversion.c+= -I${MINIXSRCDIR}/servers
+SRCS+= fslib.c fsversion.c
+
+# DHCP get/set tags.
+SRCS+= dhcp_gettag.c dhcp_settag.c
+
+# Gcov support.
+SRCS+= gcov.c gcov_flush.c
+
+# Various utils
+SRCS+= itoa.c u64util.c
+
+# svrctl
+SRCS+= svrctl.c
+
+# servxcheck
+SRCS+= servxcheck.c
+
+# queryparam
+SRCS+= paramvalue.c
+
+# Minix servers/drivers syscall.
+SRCS+= adddma.c getdma.c deldma.c getngid.c getnpid.c \
+ getnprocnr.c getnucred.c getnuid.c getprocnr.c \
+ mapdriver.c vm_dmacalls.c vm_memctl.c \
+ vm_set_priv.c vm_query_exit.c vm_update.c
+
+INCS+= tools.h
+
+.include "${MACHINE}/Makefile.inc"
+
+.include <bsd.lib.mk>
--- /dev/null
+/* adddma.c
+ */
+
+#include <lib.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+int adddma(proc_e, start, size)
+endpoint_t proc_e;
+phys_bytes start;
+phys_bytes size;
+{
+ message m;
+
+ m.m2_i1= proc_e;
+ m.m2_l1= start;
+ m.m2_l2= size;
+
+ return _syscall(PM_PROC_NR, ADDDMA, &m);
+}
--- /dev/null
+/* deldma.c
+ */
+
+#include <lib.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+int deldma(proc_e, start, size)
+endpoint_t proc_e;
+phys_bytes start;
+phys_bytes size;
+{
+ message m;
+
+ m.m2_i1= proc_e;
+ m.m2_l1= start;
+ m.m2_l2= size;
+
+ return _syscall(PM_PROC_NR, DELDMA, &m);
+}
--- /dev/null
+/* dhcp_gettag() Author: Kees J. Bot
+ * 1 Dec 2000
+ */
+#define nil ((void*)0)
+#include <stddef.h>
+#include <string.h>
+#include <sys/types.h>
+#include <net/hton.h>
+#include <net/gen/in.h>
+#include <net/gen/dhcp.h>
+
+#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
+
+int dhcp_gettag(dhcp_t *dp, int searchtag, u8_t **pdata, size_t *plen)
+{
+ /* Find a tag in the options field, or possibly in the file or sname
+ * fields. Return true iff found, and return the data and/or length if
+ * their pointers are non-null.
+ */
+ u8_t *p;
+ u8_t *optfield[3];
+ size_t optlen[3];
+ int i, tag, len;
+
+ /* The DHCP magic number must be correct, or no tags. */
+ if (dp->magic != DHCP_MAGIC) return 0;
+
+ optfield[0]= dp->options;
+ optlen[0]= arraysize(dp->options);
+ optfield[1]= dp->file;
+ optlen[1]= 0; /* Unknown if used for options yet. */
+ optfield[2]= dp->sname;
+ optlen[2]= 0;
+
+ for (i= 0; i < 3; i++) {
+ p= optfield[i];
+ while (p < optfield[i] + optlen[i]) {
+ tag= *p++;
+ if (tag == 255) break;
+ len= tag == 0 ? 0 : *p++;
+ if (tag == searchtag) {
+ if (pdata != nil) *pdata= p;
+ if (plen != nil) *plen= len;
+ return 1;
+ }
+ if (tag == DHCP_TAG_OVERLOAD) {
+ /* There are also options in the file or sname field. */
+ if (*p & 1) optlen[1]= arraysize(dp->file);
+ if (*p & 2) optlen[1]= arraysize(dp->sname);
+ }
+ p += len;
+ }
+ }
+ return 0;
+}
--- /dev/null
+/* dhcp_init(), dhcp_settag() Author: Kees J. Bot
+ * 1 Dec 2000
+ */
+#define nil ((void*)0)
+#include <stddef.h>
+#include <string.h>
+#include <sys/types.h>
+#include <net/hton.h>
+#include <net/gen/in.h>
+#include <net/gen/dhcp.h>
+
+#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
+#define arraylimit(a) ((a) + arraysize(a))
+
+void dhcp_init(dhcp_t *dp)
+{
+ /* Initialize a DHCP packet. */
+ memset(dp, 0, offsetof(dhcp_t, magic));
+ dp->magic= DHCP_MAGIC;
+ memset(dp->options, 255, sizeof(dp->options));
+}
+
+int dhcp_settag(dhcp_t *dp, int tag, void *data, size_t len)
+{
+ /* Add a tag to a DHCP packet. No padding. Only do the options field.
+ * (This is Minix, we don't need megabytes of silly bits of data.)
+ * The length may be zero to delete a tag.
+ */
+ u8_t *p;
+ int n;
+
+ if (tag <= 0 || tag >= 255) return 0;
+
+ for (p= dp->options; p < arraylimit(dp->options) && *p != 255; p += n) {
+ n= 1 + 1 + p[1];
+ if (*p == tag) {
+ /* The tag is already there, remove it so it gets replaced. */
+ memmove(p, p + n, arraylimit(dp->options) - (p + n));
+ memset(arraylimit(dp->options) - n, 255, n);
+ n= 0;
+ }
+ }
+
+ /* Add tag. */
+ if (len == 0) {
+ /* We're merely deleting a tag. */
+ } else
+ if (p + 1 + 1 + len <= arraylimit(dp->options)) {
+ *p++ = tag;
+ *p++ = len;
+ memcpy(p, data, len);
+ } else {
+ /* Oops, it didn't fit? Is this really Minix??? */
+ return 0;
+ }
+ return 1;
+}
--- /dev/null
+/* fslib.c - routines needed by fs and fs utilities */
+
+#include <minix/config.h> /* for unused stuff in <minix/type.h> :-( */
+#include <minix/ansi.h>
+#include <limits.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <minix/const.h>
+#include <minix/type.h> /* for unshort :-( */
+#include "mfs/const.h" /* depends of -I flag in Makefile */
+#include "mfs/type.h" /* ditto */
+#include "mfs/inode.h" /* ditto */
+#include "mfs/super.h"
+#include <minix/fslib.h>
+
+/* The next routine is copied from fsck.c and mkfs.c... (Re)define some
+ * things for consistency. Some things should be done better.
+ */
+
+/* Convert from bit count to a block count. The usual expression
+ *
+ * (nr_bits + (1 << BITMAPSHIFT) - 1) >> BITMAPSHIFT
+ *
+ * doesn't work because of overflow.
+ *
+ * Other overflow bugs, such as the expression for N_ILIST overflowing when
+ * s_inodes is just over V*_INODES_PER_BLOCK less than the maximum+1, are not
+ * fixed yet, because that number of inodes is silly.
+ */
+/* The above comment doesn't all apply now bit_t is long. Overflow is now
+ * unlikely, but negative bit counts are now possible (though unlikely)
+ * and give silly results.
+ */
+PUBLIC int bitmapsize(nr_bits, block_size)
+bit_t nr_bits;
+int block_size;
+{
+ int nr_blocks;
+
+ nr_blocks = (int) (nr_bits / FS_BITS_PER_BLOCK(block_size));
+ if (((bit_t) nr_blocks * FS_BITS_PER_BLOCK(block_size)) < nr_bits) ++nr_blocks;
+ return(nr_blocks);
+}
+
+
+/*===========================================================================*
+ * conv2 *
+ *===========================================================================*/
+PUBLIC unsigned conv2(norm, w)
+int norm; /* TRUE if no swap, FALSE for byte swap */
+int w; /* promotion of 16-bit word to be swapped */
+{
+/* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
+
+ if (norm) return( (unsigned) w & 0xFFFF);
+ return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
+}
+
+
+/*===========================================================================*
+ * conv4 *
+ *===========================================================================*/
+PUBLIC long conv4(norm, x)
+int norm; /* TRUE if no swap, FALSE for byte swap */
+long x; /* 32-bit long to be byte swapped */
+{
+/* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
+
+ unsigned lo, hi;
+ long l;
+
+ if (norm) return(x); /* byte order was already ok */
+ lo = conv2(FALSE, (int) x & 0xFFFF); /* low-order half, byte swapped */
+ hi = conv2(FALSE, (int) (x>>16) & 0xFFFF); /* high-order half, swapped */
+ l = ( (long) lo <<16) | hi;
+ return(l);
+}
+
+
+/*===========================================================================*
+ * conv_inode *
+ *===========================================================================*/
+PUBLIC void conv_inode(rip, dip, dip2, rw_flag, magic)
+register struct inode *rip; /* pointer to the in-core inode struct */
+register d1_inode *dip; /* pointer to the V1 on-disk inode struct */
+register d2_inode *dip2; /* pointer to the V2 on-disk inode struct */
+int rw_flag; /* READING or WRITING */
+int magic; /* magic number of file system */
+{
+/* Copy the inode from the disk block to the in-core table or vice versa.
+ * If the fourth parameter below is FALSE, the bytes are swapped.
+ */
+ switch (magic) {
+ case SUPER_MAGIC: old_icopy(rip, dip, rw_flag, TRUE); break;
+ case SUPER_REV: old_icopy(rip, dip, rw_flag, FALSE); break;
+ case SUPER_V3:
+ case SUPER_V2: new_icopy(rip, dip2, rw_flag, TRUE); break;
+ case SUPER_V2_REV: new_icopy(rip, dip2, rw_flag, FALSE); break;
+ }
+}
+
+
+/*===========================================================================*
+ * old_icopy *
+ *===========================================================================*/
+PUBLIC void old_icopy(rip, dip, direction, norm)
+register struct inode *rip; /* pointer to the in-core inode struct */
+register d1_inode *dip; /* pointer to the d1_inode inode struct */
+int direction; /* READING (from disk) or WRITING (to disk) */
+int norm; /* TRUE = do not swap bytes; FALSE = swap */
+
+{
+/* 4 different on-disk inode layouts are supported, one for each combination
+ * of V1.x/V2.x * bytes-swapped/not-swapped. When an inode is read or written
+ * this routine handles the conversions so that the information in the inode
+ * table is independent of the disk structure from which the inode came.
+ * The old_icopy routine copies to and from V1 disks.
+ */
+
+ int i;
+
+ if (direction == READING) {
+ /* Copy V1.x inode to the in-core table, swapping bytes if need be. */
+ rip->i_mode = conv2(norm, dip->d1_mode);
+ rip->i_uid = conv2(norm,dip->d1_uid );
+ rip->i_size = conv4(norm,dip->d1_size);
+ rip->i_mtime = conv4(norm,dip->d1_mtime);
+ rip->i_atime = 0;
+ rip->i_ctime = 0;
+ rip->i_nlinks = (nlink_t) dip->d1_nlinks; /* 1 char */
+ rip->i_gid = (gid_t) dip->d1_gid; /* 1 char */
+ rip->i_ndzones = V1_NR_DZONES;
+ rip->i_nindirs = V1_INDIRECTS;
+ for (i = 0; i < V1_NR_TZONES; i++)
+ rip->i_zone[i] = conv2(norm, (int) dip->d1_zone[i]);
+ } else {
+ /* Copying V1.x inode to disk from the in-core table. */
+ dip->d1_mode = conv2(norm,rip->i_mode);
+ dip->d1_uid = conv2(norm,rip->i_uid );
+ dip->d1_size = conv4(norm,rip->i_size);
+ dip->d1_mtime = conv4(norm,rip->i_mtime);
+ dip->d1_nlinks = (nlink_t) rip->i_nlinks; /* 1 char */
+ dip->d1_gid = (gid_t) rip->i_gid; /* 1 char */
+ for (i = 0; i < V1_NR_TZONES; i++)
+ dip->d1_zone[i] = conv2(norm, (int) rip->i_zone[i]);
+ }
+}
+
+
+/*===========================================================================*
+ * new_icopy *
+ *===========================================================================*/
+PUBLIC void new_icopy(rip, dip, direction, norm)
+register struct inode *rip; /* pointer to the in-core inode struct */
+register d2_inode *dip; /* pointer to the d2_inode struct */
+int direction; /* READING (from disk) or WRITING (to disk) */
+int norm; /* TRUE = do not swap bytes; FALSE = swap */
+
+{
+/* Same as old_icopy, but to/from V2 disk layout. */
+
+ int i;
+
+ if (direction == READING) {
+ /* Copy V2.x inode to the in-core table, swapping bytes if need be. */
+ rip->i_mode = conv2(norm,dip->d2_mode);
+ rip->i_uid = conv2(norm,dip->d2_uid );
+ rip->i_nlinks = conv2(norm,(int) dip->d2_nlinks);
+ rip->i_gid = conv2(norm,(int) dip->d2_gid );
+ rip->i_size = conv4(norm,dip->d2_size);
+ rip->i_atime = conv4(norm,dip->d2_atime);
+ rip->i_ctime = conv4(norm,dip->d2_ctime);
+ rip->i_mtime = conv4(norm,dip->d2_mtime);
+ rip->i_ndzones = V2_NR_DZONES;
+ rip->i_nindirs = V2_INDIRECTS(rip->i_sp->s_block_size);
+ for (i = 0; i < V2_NR_TZONES; i++)
+ rip->i_zone[i] = conv4(norm, (long) dip->d2_zone[i]);
+ } else {
+ /* Copying V2.x inode to disk from the in-core table. */
+ dip->d2_mode = conv2(norm,rip->i_mode);
+ dip->d2_uid = conv2(norm,rip->i_uid );
+ dip->d2_nlinks = conv2(norm,rip->i_nlinks);
+ dip->d2_gid = conv2(norm,rip->i_gid );
+ dip->d2_size = conv4(norm,rip->i_size);
+ dip->d2_atime = conv4(norm,rip->i_atime);
+ dip->d2_ctime = conv4(norm,rip->i_ctime);
+ dip->d2_mtime = conv4(norm,rip->i_mtime);
+ for (i = 0; i < V2_NR_TZONES; i++)
+ dip->d2_zone[i] = conv4(norm, (long) rip->i_zone[i]);
+ }
+}
--- /dev/null
+/* This procedure examines a file system and figures out whether it is
+ * version 1 or version 2. It returns the result as an int. If the
+ * file system is neither, it returns -1. A typical call is:
+ *
+ * n = fsversion("/dev/hd1", "df");
+ *
+ * The first argument is the special file for the file system.
+ * The second is the program name, which is used in error messages.
+ */
+
+#include <sys/types.h>
+#include <minix/config.h>
+#include <minix/const.h>
+#include <minix/minlib.h>
+#include <minix/type.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "mfs/const.h"
+
+static char super[SUPER_BLOCK_BYTES];
+
+#define MAGIC_OFFSET_MFS 0x18
+#define MAGIC_OFFSET_EXT 0x38
+#define MAGIC_VALUE_EXT2 0xef53
+
+static int check_super(off_t offset, unsigned short magic)
+{
+ return (memcmp(super + offset, &magic, sizeof(magic)) == 0) ? 1 : 0;
+}
+
+int fsversion(dev, prog)
+char *dev, *prog;
+{
+ int fd;
+
+ if ((fd = open(dev, O_RDONLY)) < 0) {
+ std_err(prog);
+ std_err(" cannot open ");
+ perror(dev);
+ return(-1);
+ }
+
+ lseek(fd, (off_t) SUPER_BLOCK_BYTES, SEEK_SET); /* skip boot block */
+ if (read(fd, (char *) &super, sizeof(super)) != sizeof(super)) {
+ std_err(prog);
+ std_err(" cannot read super block on ");
+ perror(dev);
+ close(fd);
+ return(-1);
+ }
+ close(fd);
+
+ /* first check MFS, a valid MFS may look like EXT but not vice versa */
+ if (check_super(MAGIC_OFFSET_MFS, SUPER_MAGIC)) return FSVERSION_MFS1;
+ if (check_super(MAGIC_OFFSET_MFS, SUPER_V2)) return FSVERSION_MFS2;
+ if (check_super(MAGIC_OFFSET_MFS, SUPER_V3)) return FSVERSION_MFS3;
+ if (check_super(MAGIC_OFFSET_EXT, MAGIC_VALUE_EXT2)) return FSVERSION_EXT2;
+
+ return(-1);
+}
--- /dev/null
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <minix/gcov.h>
+
+int gcov_flush_svr(char *buff, int buff_sz, int server_nr)
+{
+ message msg;
+
+ msg.GCOV_BUFF_P = buff;
+ msg.GCOV_BUFF_SZ = buff_sz;
+ msg.GCOV_PID = server_nr;
+
+ /* Make the call to server. It will call the gcov library,
+ * buffer the stdio requests, and copy the buffer to this user
+ * space
+ */
+ return _syscall(VFS_PROC_NR, GCOV_FLUSH, &msg);
+}
+
+
+/* wrappers for file system calls from gcc libgcov library.
+ Default calls are wrapped. In libsys, an alternative
+ implementation for servers is used.
+*/
+
+FILE *_gcov_fopen(char *name, char *mode){
+ return fopen(name, mode);
+}
+
+
+size_t _gcov_fread(void *ptr, size_t itemsize, size_t nitems
+ , FILE *stream){
+ return fread(ptr, itemsize, nitems, stream);
+}
+
+size_t _gcov_fwrite(void *ptr, size_t itemsize, size_t nitems
+ , FILE *stream){
+ return fwrite(ptr, itemsize, nitems, stream);
+}
+
+int _gcov_fclose(FILE *stream){
+ return fclose(stream);
+}
+
+int _gcov_fseek(FILE *stream, long offset, int ptrname){
+ return fseek(stream, offset, ptrname);
+}
+
+char *_gcov_getenv(const char *name){
+ return getenv(name);
+}
+
--- /dev/null
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <minix/gcov.h>
+
+void __gcov_flush(void)
+{
+ /* A version of __gcov_flush for cases in which no gcc -lgcov
+ * is given; i.e. non-gcc or gcc without active gcov.
+ */
+ ;
+}
+
--- /dev/null
+/* getdma.c
+ */
+
+#include <lib.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+int getdma(procp, basep, sizep)
+endpoint_t *procp;
+phys_bytes *basep;
+phys_bytes *sizep;
+{
+ int r;
+ message m;
+
+ r= _syscall(PM_PROC_NR, GETDMA, &m);
+ if (r == 0)
+ {
+ *procp= m.m2_i1;
+ *basep= m.m2_l1;
+ *sizep= m.m2_l2;
+ }
+ return r;
+}
--- /dev/null
+#include <lib.h>
+#include <unistd.h>
+
+PUBLIC gid_t getngid(endpoint_t proc_ep)
+{
+ message m;
+ m.m1_i1 = proc_ep; /* search gid for this process */
+ if (_syscall(PM_PROC_NR, GETEPINFO, &m) < 0) return ( (gid_t) -1);
+ return( (gid_t) m.m2_i2); /* return search result */
+}
--- /dev/null
+#include <lib.h>
+#include <unistd.h>
+
+PUBLIC pid_t getnpid(endpoint_t proc_ep)
+{
+ message m;
+ m.m1_i1 = proc_ep; /* search pid for this process */
+ return _syscall(PM_PROC_NR, GETEPINFO, &m);
+}
--- /dev/null
+#include <lib.h>
+#include <unistd.h>
+
+
+PUBLIC int getnprocnr(pid_t pid)
+{
+ message m;
+ int t = GETPROCNR;
+ m.m1_i1 = pid; /* pass pid >=0 to search for */
+ m.m1_i2 = 0; /* don't pass name to search for */
+ if (_syscall(PM_PROC_NR, t, &m) < 0) return(-1);
+ return(m.m1_i1); /* return search result */
+}
+
--- /dev/null
+#include <lib.h>
+#include <errno.h>
+#include <sys/ucred.h>
+#include <unistd.h>
+
+PUBLIC int getnucred(endpoint_t proc_ep, struct ucred *ucred)
+{
+ message m;
+ pid_t pid;
+
+ if (ucred == NULL) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ m.m1_i1 = proc_ep; /* search for this process */
+
+ pid = _syscall(PM_PROC_NR, GETEPINFO, &m);
+ if (pid < 0) {
+ return -1;
+ }
+
+ ucred->pid = pid;
+ ucred->uid = m.PM_NUID;
+ ucred->gid = m.PM_NGID;
+
+ return 0;
+}
--- /dev/null
+#include <lib.h>
+#include <unistd.h>
+
+PUBLIC uid_t getnuid(endpoint_t proc_ep)
+{
+ message m;
+ m.m1_i1 = proc_ep; /* search uid for this process */
+ if (_syscall(PM_PROC_NR, GETEPINFO, &m) < 0) return ( (uid_t) -1);
+ return( (uid_t) m.m2_i1); /* return search result */
+}
--- /dev/null
+#include <lib.h>
+#include <unistd.h>
+
+
+PUBLIC int getprocnr()
+{
+ message m;
+ m.m1_i1 = -1; /* don't pass pid to search for */
+ m.m1_i2 = 0; /* don't pass name to search for */
+ if (_syscall(PM_PROC_NR, GETPROCNR, &m) < 0) return(-1);
+ return(m.m1_i1); /* return own process number */
+}
+
--- /dev/null
+SRCS+= _cpufeature.c _cpuid.S get_bp.S getprocessor.S \
+ oneC_sum.S read_tsc.S read_tsc_64.c
--- /dev/null
+#include <sys/types.h>
+#include <stdint.h>
+#include <minix/minlib.h>
+#include <minix/cpufeature.h>
+#include <machine/vm.h>
+
+int _cpufeature(int cpufeature)
+{
+ u32_t eax, ebx, ecx, edx;
+ int proc;
+
+ eax = ebx = ecx = edx = 0;
+ proc = getprocessor();
+
+ /* If processor supports CPUID and its CPUID supports enough
+ * parameters, retrieve EDX feature flags to test against.
+ */
+ if(proc >= 586) {
+ eax = 0;
+ _cpuid(&eax, &ebx, &ecx, &edx);
+ if(eax > 0) {
+ eax = 1;
+ _cpuid(&eax, &ebx, &ecx, &edx);
+ }
+ }
+
+ switch(cpufeature) {
+ case _CPUF_I386_PSE:
+ return edx & CPUID1_EDX_PSE;
+ case _CPUF_I386_PGE:
+ return edx & CPUID1_EDX_PGE;
+ case _CPUF_I386_APIC_ON_CHIP:
+ return edx & CPUID1_EDX_APIC_ON_CHIP;
+ case _CPUF_I386_TSC:
+ return edx & CPUID1_EDX_TSC;
+ case _CPUF_I386_FPU:
+ return edx & CPUID1_EDX_FPU;
+#define SSE_FULL_EDX (CPUID1_EDX_FXSR | CPUID1_EDX_SSE | CPUID1_EDX_SSE2)
+#define SSE_FULL_ECX (CPUID1_ECX_SSE3 | CPUID1_ECX_SSSE3 | \
+ CPUID1_ECX_SSE4_1 | CPUID1_ECX_SSE4_2)
+ case _CPUF_I386_SSE1234_12:
+ return (edx & SSE_FULL_EDX) == SSE_FULL_EDX &&
+ (ecx & SSE_FULL_ECX) == SSE_FULL_ECX;
+ case _CPUF_I386_FXSR:
+ return edx & CPUID1_EDX_FXSR;
+ case _CPUF_I386_SSE:
+ return edx & CPUID1_EDX_SSE;
+ case _CPUF_I386_SSE2:
+ return edx & CPUID1_EDX_SSE2;
+ case _CPUF_I386_SSE3:
+ return ecx & CPUID1_ECX_SSE3;
+ case _CPUF_I386_SSSE3:
+ return ecx & CPUID1_ECX_SSSE3;
+ case _CPUF_I386_SSE4_1:
+ return ecx & CPUID1_ECX_SSE4_1;
+ case _CPUF_I386_SSE4_2:
+ return ecx & CPUID1_ECX_SSE4_2;
+ case _CPUF_I386_HTT:
+ return edx & CPUID1_EDX_HTT;
+ case _CPUF_I386_HTT_MAX_NUM:
+ return (ebx >> 16) & 0xff;
+ }
+
+ return 0;
+}
+
--- /dev/null
+/* _cpuid() - interface to cpuid instruction */
+
+
+/* void _cpuid(u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx); */
+/* 0 for OK, nonzero for unsupported */
+
+#include <machine/asm.h>
+
+ENTRY(_cpuid)
+/* save work registers */
+ push %ebp
+ push %ebx
+
+/* set eax parameter to cpuid and execute cpuid */
+ movl 12(%esp), %ebp
+ mov (%ebp), %eax
+ movl 16(%esp), %ebp
+ mov (%ebp), %ebx
+ movl 20(%esp), %ebp
+ mov (%ebp), %ecx
+ movl 24(%esp), %ebp
+ mov (%ebp), %edx
+
+.byte 0x0F, 0xA2 /* CPUID */
+
+/* store results in pointer arguments */
+ movl 12(%esp), %ebp
+ movl %eax, (%ebp)
+ movl 16(%esp), %ebp
+ movl %ebx, (%ebp)
+ movl 20(%esp), %ebp
+ movl %ecx, (%ebp)
+ movl 24(%esp), %ebp
+ movl %edx, (%ebp)
+
+/* restore registers */
+ pop %ebx
+ pop %ebp
+
+ ret
--- /dev/null
+/* get_bp.s */
+/* */
+/* return EBP in EAX */
+/* */
+/* Created: Sep 7, 1992 by Philip Homburg */
+
+#include <machine/asm.h>
+
+ENTRY(get_bp)
+ movl %ebp, %eax
+ ret
+
+/* $PchId: get_bp.ack.s,v 1.3 1996/02/23 08:30:52 philip Exp $ */
--- /dev/null
+/* getprocessor() - determine processor type Author: Kees J. Bot */
+/* 26 Jan 1994 */
+#include <machine/asm.h>
+
+/* int getprocessor(void); */
+/* Return 386, 486, 586, ... */
+ENTRY(getprocessor)
+ push %ebp
+ movl %esp, %ebp
+ andl $0xFFFFFFFC, %esp /* Align stack to avoid AC fault */
+ movl $0x00040000, %ecx /* Try to flip the AC bit introduced on the 486 */
+ call flip
+ movl $386, %eax /* 386 if it didn't react to "flipping" */
+ je gotprocessor
+ movl $0x00200000, %ecx /* Try to flip the ID bit introduced on the 586 */
+ call flip
+ movl $486, %eax /* 486 if it didn't react */
+ je gotprocessor
+ pushf
+ pusha /* Save the world */
+ movl $1, %eax
+.byte 0x0F, 0xA2 /* CPUID instruction tells the processor type */
+ andb $0x0F, %ah /* Extract the family (5, 6, ...) */
+ movzbl %ah, %eax
+ cmpl $15, %eax /* 15: extended family */
+ jne direct
+ movl $6, %eax /* Make it 686 */
+direct:
+ imull $100, %eax /* 500, 600, ... */
+ addl $86, %eax /* 586, 686, ... */
+ movl %eax, 7*4(%esp) /* Pass eax through */
+ popa
+ popf
+gotprocessor:
+ leave
+ ret
+
+flip:
+ pushf /* Push eflags */
+ pop %eax /* eax = eflags */
+ movl %eax, %edx /* Save original eflags */
+ xorl %ecx, %eax /* Flip the bit to test */
+ push %eax /* Push modified eflags value */
+ popf /* Load modified eflags register */
+ pushf
+ pop %eax /* Get it again */
+ push %edx
+ popf /* Restore original eflags register */
+ xorl %edx, %eax /* See if the bit changed */
+ testl %ecx, %eax
+ ret
--- /dev/null
+/* oneC_sum() - One complement`s checksum Author: Kees J. Bot */
+/* 9 May 1995 */
+/* See RFC 1071, "Computing the Internet checksum" */
+/* See also the C version of this code. */
+#include <machine/asm.h>
+
+ENTRY(oneC_sum)
+ push %ebp
+ movl %esp, %ebp
+ push %esi
+ push %edi
+ movzwl 8(%ebp), %eax /* Checksum of previous block */
+ movl 12(%ebp), %esi /* Data to compute checksum over */
+ movl 16(%ebp), %edi /* Number of bytes */
+
+ xorl %edx, %edx
+ xorb %cl, %cl
+align:
+ testl $3, %esi /* Is the data aligned? */
+ je aligned
+ testl %edi, %edi
+ je 0f
+ movb (%esi), %dl /* Rotate the first unaligned bytes */
+ decl %edi /* into the edx register */
+0:
+ incl %esi
+ rorl $8, %edx
+ rorl $8, %eax /* Rotate the checksum likewise */
+ addb $8, %cl /* Number of bits rotated */
+ jmp align
+aligned:
+ addl %edx, %eax /* Summate the unaligned bytes */
+ adcl $0, %eax /* Add carry back in for one`s complement */
+
+ jmp add6test
+_ALIGN_TEXT
+add6:
+ addl (%esi), %eax /* Six times unrolled loop, see below */
+ adcl 4(%esi), %eax
+ adcl 8(%esi), %eax
+ adcl 12(%esi), %eax
+ adcl 16(%esi), %eax
+ adcl 20(%esi), %eax
+ adcl $0, %eax
+ addl $24, %esi
+add6test:
+ subl $24, %edi
+ jae add6
+ addl $24, %edi
+
+ jmp add1test
+_ALIGN_TEXT
+add1:
+ addl (%esi), %eax /* while ((edi -= 4) >= 0) */
+ adcl $0, %eax /* eax += *esi++; */
+ addl $4, %esi /* edi += 4; */
+add1test:
+ subl $4, %edi
+ jae add1
+ addl $4, %edi
+
+ je done /* Are there extra bytes? */
+ movl (%esi), %edx /* Load extra bytes in a full dword */
+ andl mask-4(,%edi,4), %edx /* Mask off excess */
+ addl %edx, %eax /* Add in the last bits */
+ adcl $0, %eax
+done:
+ roll %cl, %eax /* Undo the rotation at the beginning */
+ movl %eax, %edx
+ shrl $16, %eax
+ addw %dx, %ax /* Add the two words in eax to form */
+ adcw $0, %ax /* a 16 bit sum */
+ pop %edi
+ pop %esi
+ pop %ebp
+ ret
+
+#ifdef __ACK__
+.rom
+#else
+.data
+#endif
+.balign 4
+mask:
+.long 0x000000FF, 0x0000FFFF, 0x00FFFFFF
+
+/* */
+/* $PchId: oneC_sum.ack.s,v 1.2 1996/03/12 19:33:51 philip Exp $ */
--- /dev/null
+/* */
+/* sections */
+#include <machine/asm.h>
+
+/**===========================================================================* */
+/* PUBLIC void read_tsc(unsigned long *high, unsigned long *low); */
+/* Read the cycle counter of the CPU. Pentium and up. */
+ENTRY(read_tsc)
+ push %edx
+ push %eax
+.byte 0x0f /* this is the RDTSC instruction */
+.byte 0x31 /* it places the TSC in EDX:EAX */
+ push %ebp
+ movl 16(%esp), %ebp
+ movl %edx, (%ebp)
+ movl 20(%esp), %ebp
+ movl %eax, (%ebp)
+ pop %ebp
+ pop %eax
+ pop %edx
+ ret
+
+/**===========================================================================* */
+/* PUBLIC void read_host_time_ns(unsigned long *high, unsigned long *low); */
+/* access real time in ns from host in vmware. */
+ENTRY(read_host_time_ns)
+ pushl %edx
+ pushl %eax
+ pushl %ecx
+ movl $0x10001, %ecx
+.byte 0x0f /* this is the RDTSC instruction */
+.byte 0x31 /* it places the TSC in EDX:EAX */
+ pushl %ebp
+ movl 20(%esp), %ebp
+ movl %edx, (%ebp)
+ movl 24(%esp), %ebp
+ movl %eax, (%ebp)
+ popl %ebp
+ popl %ecx
+ popl %eax
+ popl %edx
+ ret
--- /dev/null
+
+#include <minix/u64.h>
+#include <minix/minlib.h>
+
+/* Utility function to work directly with u64_t
+ * By Antonio Mancina
+ */
+void read_tsc_64(t)
+u64_t* t;
+{
+ u32_t lo, hi;
+ read_tsc (&hi, &lo);
+ *t = make64 (lo, hi);
+}
+
--- /dev/null
+#include <lib.h>
+/* Integer to ASCII for signed decimal integers. */
+
+PRIVATE int next;
+PRIVATE char qbuf[8];
+
+_PROTOTYPE( char *itoa, (int n));
+
+char *itoa(n)
+int n;
+{
+ register int r, k;
+ int flag = 0;
+
+ next = 0;
+ if (n < 0) {
+ qbuf[next++] = '-';
+ n = -n;
+ }
+ if (n == 0) {
+ qbuf[next++] = '0';
+ } else {
+ k = 10000;
+ while (k > 0) {
+ r = n / k;
+ if (flag || r > 0) {
+ qbuf[next++] = '0' + r;
+ flag = 1;
+ }
+ n -= r * k;
+ k = k / 10;
+ }
+ }
+ qbuf[next] = 0;
+ return(qbuf);
+}
--- /dev/null
+#include <lib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+PUBLIC int mapdriver(label, major, dev_style, flags)
+char *label;
+int major;
+int dev_style;
+int flags;
+{
+ message m;
+ m.m2_p1 = label;
+ m.m2_l1 = strlen(label);
+ m.m2_i1 = major;
+ m.m2_i2 = dev_style;
+ m.m2_i3 = flags;
+ if (_syscall(VFS_PROC_NR, MAPDRIVER, &m) < 0) return(-1);
+ return(0);
+}
+
--- /dev/null
+/* paramvalue() - decode kernel parameter values Author: Kees J. Bot
+ * 7 May 1994
+ * The kernel returns the results of parameter queries
+ * by the XXQUERYPARAM svrctl calls as an array of hex digits, like this:
+ * "75020000,080C0000". These are the values of two four-byte variables.
+ * Paramvalue() decodes such a string.
+ */
+#define nil 0
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <minix/queryparam.h>
+
+size_t paramvalue(char **value, void *address, size_t size)
+/* Decode the string *value storing the result in the object at address with
+ * the given size. *value is left at the next parameter, *address is padded
+ * with zeros if needed, and the actual size of the value is returned.
+ */
+{
+ unsigned char *addr= address;
+ char *v= *value;
+ int nibble;
+ size_t n;
+
+ n= 0;
+
+ while (*v != 0 && *v != ',') {
+ nibble= *v++ - '0';
+ if (nibble > 0x9) nibble= nibble + '0' - 'A' + 0xA;
+ if (nibble > 0xF) nibble= nibble + 'A' - 'a';
+ if (size > 0) {
+ if (n % 2 == 0) {
+ *addr= nibble << 4;
+ } else {
+ *addr++|= nibble;
+ size--;
+ }
+ n++;
+ }
+ }
+ while (size > 0) { *addr++= 0; size--; }
+ while (*v != 0 && *v++ != ',') {}
+ *value= v;
+ return n / 2;
+}
+
+
+/*
+ * $PchId: paramvalue.c,v 1.3 1996/02/22 09:15:56 philip Exp $
+ */
--- /dev/null
+/* servxcheck() - Service access check. Author: Kees J. Bot
+ * 8 Jan 1997
+ */
+#define nil 0
+#define ioctl _ioctl
+#define open _open
+#define write _write
+#define close _close
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include <net/hton.h>
+#include <net/gen/in.h>
+#include <net/gen/tcp.h>
+#include <net/gen/tcp_io.h>
+#include <net/gen/inet.h>
+#include <net/gen/socket.h>
+#include <net/gen/netdb.h>
+
+/* Default service access file. */
+static const char *path_servacces = _PATH_SERVACCES;
+
+#define WLEN 256
+
+static int getword(FILE *fp, char *word)
+/* Read a word from the file open by 'fp', skip whitespace and comments.
+ * Colon and semicolon are returned as a one character "word". Returns
+ * word[0] or EOF.
+ */
+{
+ int c;
+ char *pw;
+ int wc;
+
+ wc= 0;
+ for (;;) {
+ if ((c= getc(fp)) == EOF) return EOF;
+ if (c == '#') { wc= 1; continue; }
+ if (c == '\n') { wc= 0; continue; }
+ if (wc) continue;
+ if (c <= ' ') continue;
+ break;
+ }
+
+ pw= word;
+ if (c == ':' || c == ';') {
+ *pw++ = c;
+ } else {
+ do {
+ if (pw < word + WLEN-1) *pw++ = c;
+ c= getc(fp);
+ } while (c != EOF && c > ' ' && c != ':' && c != ';');
+ if (c != EOF) ungetc(c, fp);
+ }
+ *pw= 0;
+ return word[0];
+}
+
+static int netspec(char *word, ipaddr_t *addr, ipaddr_t *mask)
+/* Try to interpret 'word' as an network spec, e.g. 172.16.102.64/27. */
+{
+ char *slash;
+ int r;
+ static char S32[]= "/32";
+
+ if (*word == 0) return 0;
+
+ if ((slash= strchr(word, '/')) == NULL) slash= S32;
+
+ *slash= 0;
+ r= inet_aton(word, addr);
+ *slash++= '/';
+ if (!r) return 0;
+
+ r= 0;
+ while ((*slash - '0') < 10u) {
+ r= 10*r + (*slash++ - '0');
+ if (r > 32) return 0;
+ }
+ if (*slash != 0 || slash[-1] == '/') return 0;
+ *mask= htonl(r == 0 ? 0L : (0xFFFFFFFFUL >> (32 - r)) << (32 - r));
+ return 1;
+}
+
+static int match(const char *word, const char *pattern)
+/* Match word onto a pattern. Pattern may contain the * wildcard. */
+{
+ unsigned cw, cp;
+#define lc(c, d) ((((c)= (d)) - 'A') <= ('Z' - 'A') ? (c)+= ('a' - 'A') : 0)
+
+ for (;;) {
+ (void) lc(cw, *word);
+ (void) lc(cp, *pattern);
+
+ if (cp == '*') {
+ do pattern++; while (*pattern == '*');
+ (void) lc(cp, *pattern);
+ if (cp == 0) return 1;
+
+ while (cw != 0) {
+ if (cw == cp && match(word+1, pattern+1)) return 1;
+ word++;
+ (void) lc(cw, *word);
+ }
+ return 0;
+ } else
+ if (cw == 0 || cp == 0) {
+ return cw == cp;
+ } else
+ if (cw == cp) {
+ word++;
+ pattern++;
+ } else {
+ return 0;
+ }
+ }
+#undef lc
+}
+
+static int get_name(ipaddr_t addr, char *name)
+/* Do a reverse lookup on the remote IP address followed by a forward lookup
+ * to check if the host has that address. Return true if this is so, return
+ * either the true name or the ascii IP address in name[].
+ */
+{
+ struct hostent *he;
+ int i;
+
+ he= gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
+ if (he != NULL) {
+ strcpy(name, he->h_name);
+ he= gethostbyname(name);
+
+ if (he != NULL && he->h_addrtype == AF_INET) {
+ for (i= 0; he->h_addr_list[i] != NULL; i++) {
+ if (memcmp(he->h_addr_list[i], &addr, sizeof(addr)) == 0) {
+ strcpy(name, he->h_name);
+ return 1;
+ }
+ }
+ }
+ }
+ strcpy(name, inet_ntoa(addr));
+ return 0;
+}
+
+/* "state" and "log" flags, made to be bitwise comparable. */
+#define DEFFAIL 0x01
+#define FAIL (0x02 | DEFFAIL)
+#define PASS 0x04
+
+int servxcheck(unsigned long peer, const char *service,
+ void (*logf)(int pass, const char *name))
+{
+ FILE *fp;
+ char word[WLEN];
+ char name[WLEN];
+ int c;
+ int got_name, slist, seen, explicit, state, log;
+ ipaddr_t addr, mask;
+
+ /* Localhost? */
+ if ((peer & htonl(0xFF000000)) == htonl(0x7F000000)) return 1;
+
+ if ((fp= fopen(path_servacces, "r")) == nil) {
+ /* Succeed on error, fail if simply nonexistent. */
+ return (errno != ENOENT);
+ }
+
+ slist= 1; /* Services list (before the colon.) */
+ seen= 0; /* Given service not yet seen. */
+ explicit= 0; /* Service mentioned explicitly. */
+ got_name= -1; /* No reverse lookup done yet. */
+ log= FAIL; /* By default log failures only. */
+ state= DEFFAIL; /* Access denied until we know better. */
+
+ while ((c= getword(fp, word)) != EOF) {
+ if (c == ':') {
+ slist= 0; /* Switch to access list. */
+ } else
+ if (c == ';') {
+ slist= 1; /* Back to list of services. */
+ seen= 0;
+ } else
+ if (slist) {
+ /* Traverse services list. */
+
+ if (match(service, word)) {
+ /* Service has been spotted! */
+ if (match(word, service)) {
+ /* Service mentioned without wildcards. */
+ seen= explicit= 1;
+ } else {
+ /* Matched by a wildcard. */
+ if (!explicit) seen= 1;
+ }
+ }
+ } else {
+ /* Traverse access list. */
+
+ if (c == 'l' && strcmp(word, "log") == 0) {
+ if (seen) {
+ /* Log failures and successes. */
+ log= FAIL|PASS;
+ }
+ continue;
+ }
+
+ if (c != '-' && c != '+') {
+ if (logf == nil) {
+ syslog(LOG_ERR, "%s: strange check word '%s'\n",
+ path_servacces, word);
+ }
+ continue;
+ }
+
+ if (seen) {
+ if (state == DEFFAIL) {
+ /* First check determines the default. */
+ state= c == '+' ? FAIL : PASS;
+ }
+
+ if ((state == PASS) == (c == '+')) {
+ /* This check won't change state. */
+ } else
+ if (word[1] == 0) {
+ /* Lone + or - allows all or none. */
+ state= c == '-' ? FAIL : PASS;
+ } else
+ if (netspec(word+1, &addr, &mask)) {
+ /* Remote host is on the specified network? */
+ if (((peer ^ addr) & mask) == 0) {
+ state= c == '-' ? FAIL : PASS;
+ }
+ } else {
+ /* Name check. */
+ if (got_name == -1) {
+ got_name= get_name(peer, name);
+ }
+
+ /* Remote host name matches the word? */
+ if (!got_name) {
+ state= FAIL;
+ } else
+ if (match(name, word+1)) {
+ state= c == '-' ? FAIL : PASS;
+ }
+ }
+ }
+ }
+ }
+ fclose(fp);
+
+ if ((log & state) != 0) {
+ /* Log the result of the check. */
+ if (got_name == -1) (void) get_name(peer, name);
+
+ if (logf != nil) {
+ (*logf)(state == PASS, name);
+ } else {
+ syslog(LOG_NOTICE, "service '%s' %s to %s\n",
+ service, state == PASS ? "granted" : "denied", name);
+ }
+ }
+ return state == PASS;
+}
+
+char *servxfile(const char *file)
+/* Specify a file to use for the access checks other than the default. Return
+ * the old path.
+ */
+{
+ const char *oldpath= path_servacces;
+ path_servacces= file;
+ return (char *) oldpath; /* (avoid const poisoning) */
+}
--- /dev/null
+/* svrctl() - special server control functions. Author: Kees J. Bot
+ * 24 Apr 1994
+ */
+#include <lib.h>
+#include <stdio.h>
+#include <sys/svrctl.h>
+
+int svrctl(int request, void *argp)
+{
+ message m;
+
+ m.m2_i1 = request;
+ m.m2_p1 = argp;
+
+ switch ((request >> 8) & 0xFF) {
+ case 'M':
+ case 'S':
+ /* PM handles calls for itself and the kernel. */
+ return _syscall(PM_PROC_NR, SVRCTL, &m);
+ case 'F':
+ case 'I':
+ /* VFS handles calls for itself and inet. */
+ return _syscall(VFS_PROC_NR, SVRCTL, &m);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
--- /dev/null
+#ifndef _INCLUDE_TOOLS_H
+#define _INCLUDE_TOOLS_H 1
+
+/* Constants describing the disk */
+#define SECTOR_SIZE 512
+#define SECTOR_SHIFT 9
+#define RATIO(b) ((b)/SECTOR_SIZE)
+#define ISO_SECTOR_SIZE 2048
+#define ISO_PVD_OFFSET 16
+#define HRATIO (SECTOR_SIZE / HCLICK_SIZE)
+#define PARAMSEC 1 /* sector containing boot parameters */
+#define DSKBASE 0x1E /* floppy disk parameter vector */
+#define DSKPARSIZE 11 /* there are this many bytes of parameters */
+#define ESC '\33' /* escape key */
+#define HEADERSEG 0x0060 /* place for an array of struct exec's */
+#define MINIXSEG 0x0080 /* MINIX loaded here (rounded up to a click) */
+#define BOOTSEG 0x07C0 /* bootstraps are loaded here */
+#define SIGNATURE 0xAA55 /* proper bootstraps have this signature */
+#define SIGNATPOS 510 /* offset within bootblock */
+#define FREESEG 0x0800 /* Memory from FREESEG to cseg is free */
+#define MSEC_PER_TICK 55 /* 18.2 ticks per second */
+
+/* Scan codes for four different keyboards (from kernel/keyboard.c) */
+#define DUTCH_EXT_SCAN 32 /* 'd' */
+#define OLIVETTI_SCAN 12 /* '=' key on olivetti */
+#define STANDARD_SCAN 13 /* '=' key on IBM */
+#define US_EXT_SCAN 22 /* 'u' */
+
+/* Other */
+#define ROOT_INO ((ino_t) 1) /* Inode nr of root dir. */
+#define IM_NAME_MAX 63
+
+/* Variables */
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+typedef struct vector {
+ u16_t offset;
+ u16_t segment;
+} vector;
+
+struct image_header {
+ char name[IM_NAME_MAX + 1]; /* Null terminated. */
+ struct exec process;
+};
+
+EXTERN vector rem_part; /* boot partition table entry */
+EXTERN u16_t cseg, dseg; /* code and data segment of the boot program */
+EXTERN u32_t runsize; /* size of this program */
+EXTERN u16_t device; /* drive being booted from */
+EXTERN u16_t heads, sectors; /* the drive's number of heads and sectors */
+extern u16_t eqscancode; /* Set by peek/getch() if they see a '=' */
+
+/* Sticky attributes */
+#define E_SPECIAL 0x01 /* These are known to the program */
+#define E_DEV 0x02 /* The value is a device name */
+#define E_RESERVED 0x04 /* May not be set by user, e.g. scancode */
+#define E_STICKY 0x07 /* Don't go once set */
+
+/* Volatile attributes */
+#define E_VAR 0x08 /* Variable */
+#define E_FUNCTION 0x10 /* Function definition */
+
+typedef struct environment {
+ struct environment *next;
+ char flags;
+ char *name; /* name = value */
+ char *arg; /* name(arg) {value} */
+ char *value;
+ char *defval; /* Safehouse for default values */
+} environment;
+
+/* External variables */
+EXTERN environment *env; /* Lists the environment */
+EXTERN int fsok; /* True if the boot device contains an FS */
+EXTERN u32_t lowsec; /* Offset to the file system on the boot dev */
+
+#if defined(_MINIX) || defined(__minix) || defined(__ACK__)
+/* Prototypes */
+_PROTOTYPE( off_t r_super, (void));
+_PROTOTYPE( void r_stat, (Ino_t _inum, struct stat *_stp ));
+_PROTOTYPE( ino_t r_readdir, (char *_name ));
+_PROTOTYPE( off_t r_vir2abs, (off_t _virblk ));
+_PROTOTYPE( ino_t r_lookup, (Ino_t _cwd, char *_path ));
+#endif
+
+#ifdef _MONHEAD
+_PROTOTYPE( void readerr, (off_t _sec, int _err ));
+_PROTOTYPE( int numprefix, (char *_s, char **_ps ));
+_PROTOTYPE( int numeric, (char *_s ));
+_PROTOTYPE( dev_t name2dev, (char *_name ));
+_PROTOTYPE( int delay, (char *_msec ));
+_PROTOTYPE( char *unix_err, (int _err ));
+_PROTOTYPE( void init_cache, (void));
+_PROTOTYPE( void invalidate_cache, (void));
+_PROTOTYPE( char *b_value, (char *_name ));
+_PROTOTYPE( void raw_copy, (int _doff, int _dseg, int _soff, int _sseg,
+ int _count));
+_PROTOTYPE( void raw_clear, (int _off, int _seg, int _count));
+_PROTOTYPE( void bootstrap, (int _device, int _partoff, int _partseg));
+
+_PROTOTYPE( long a2l, (char *_a ));
+_PROTOTYPE( char *ul2a, (u32_t _n ));
+_PROTOTYPE( char *u2a, (int _n1 ));
+
+/* Functions defined in monhead.s and usable by other files. */
+_PROTOTYPE( void reset_video, (int color));
+_PROTOTYPE( int dev_geometry, (void));
+_PROTOTYPE( u16_t get_ext_memsize, (void));
+_PROTOTYPE( u16_t get_low_memsize, (void));
+_PROTOTYPE( u16_t get_processor, (void));
+_PROTOTYPE( u32_t get_tick, (void));
+_PROTOTYPE( u16_t get_video, (void));
+_PROTOTYPE( u16_t get_word, (int _off, int _seg));
+_PROTOTYPE( int getchar, (void));
+_PROTOTYPE( void minix, (void));
+_PROTOTYPE( void minix86, (int _kcs, int _kds, char *_bpar, int _psize));
+_PROTOTYPE( void minix386, (int _kcs, int _kds, char *_bpar, int _psize));
+_PROTOTYPE( int peekchar, (void));
+_PROTOTYPE( void put_word, (int _off, int _seg, int _word));
+_PROTOTYPE( int putchar, (char _c));
+_PROTOTYPE( int readsectors, (int _off, int _seg, off_t _adr, int _ct));
+_PROTOTYPE( void reboot, (void));
+_PROTOTYPE( void relocate, (void));
+_PROTOTYPE( int writesectors, (int _off, int _seg, off_t _adr, int _ct));
+#endif
+
+#endif
--- /dev/null
+/* Few u64 utils implemented in C
+ * Author: Gautam BT
+ */
+#include <minix/u64.h>
+
+#if !defined(__LONG_LONG_SUPPORTED)
+u64_t rrotate64(u64_t x, unsigned short b)
+{
+ u64_t r, t;
+
+ b %= 64;
+
+ if(b == 32) {
+ r.lo = x.hi;
+ r.hi = x.lo;
+ return r;
+ }else if(b < 32) {
+ r.lo = (x.lo >> b) | (x.hi << (32 - b));
+ r.hi = (x.hi >> b) | (x.lo << (32 - b));
+ return r;
+ }else {
+ /* Rotate by 32 bits first then rotate by remaining */
+ t.lo = x.hi;
+ t.hi = x.lo;
+ b = b - 32;
+ r.lo = (t.lo >> b) | (t.hi << (32 - b));
+ r.hi = (t.hi >> b) | (t.lo << (32 - b));
+ return r;
+ }
+}
+
+u64_t rshift64(u64_t x, unsigned short b)
+{
+ u64_t r;
+
+ if(b >= 64)
+ return make64(0,0);
+
+ if(b >= 32) {
+ r.hi = 0;
+ r.lo = x.hi >> (b - 32);
+ }else {
+ r.lo = (x.lo >> b) | (x.hi << (32 - b));
+ r.hi = (x.hi >> b);
+ }
+ return r;
+}
+
+u64_t xor64(u64_t a, u64_t b)
+{
+ u64_t r;
+ r.hi = a.hi ^ b.hi;
+ r.lo = a.lo ^ b.lo;
+
+ return r;
+}
+
+u64_t and64(u64_t a, u64_t b)
+{
+ u64_t r;
+ r.hi = a.hi & b.hi;
+ r.lo = a.lo & b.lo;
+
+ return r;
+}
+
+u64_t not64(u64_t a)
+{
+ u64_t r;
+
+ r.hi = ~a.hi;
+ r.lo = ~a.lo;
+
+ return r;
+}
+#else
+
+#if !defined(__LONG_LONG_SUPPORTED)
+#error "ERROR: These functions require long long support"
+#endif
+
+u64_t rrotate64(u64_t x, unsigned short b)
+{
+ b %= 64;
+ if ((b &= 63) == 0)
+ return x;
+ return (x >> b) | (x << (64 - b));
+}
+
+u64_t rshift64(u64_t x, unsigned short b)
+{
+ if (b >= 64)
+ return 0;
+ return x >> b;
+}
+
+u64_t xor64(u64_t a, u64_t b)
+{
+ return a ^ b;
+}
+
+u64_t and64(u64_t a, u64_t b)
+{
+ return a & b;
+}
+
+u64_t not64(u64_t a)
+{
+ return ~a;
+}
+#endif
+
--- /dev/null
+
+#include <lib.h>
+#include <minix/vm.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+int vm_adddma(req_proc_e, proc_e, start, size)
+endpoint_t req_proc_e;
+endpoint_t proc_e;
+phys_bytes start;
+phys_bytes size;
+{
+ message m;
+
+ m.VMAD_REQ= req_proc_e;
+ m.VMAD_EP= proc_e;
+ m.VMAD_START= start;
+ m.VMAD_SIZE= size;
+
+ return _syscall(VM_PROC_NR, VM_ADDDMA, &m);
+}
+
+int vm_deldma(req_proc_e, proc_e, start, size)
+endpoint_t req_proc_e;
+endpoint_t proc_e;
+phys_bytes start;
+phys_bytes size;
+{
+ message m;
+
+ m.VMDD_REQ= proc_e;
+ m.VMDD_EP= proc_e;
+ m.VMDD_START= start;
+ m.VMDD_SIZE= size;
+
+ return _syscall(VM_PROC_NR, VM_DELDMA, &m);
+}
+
+int vm_getdma(req_proc_e, procp, basep, sizep)
+endpoint_t req_proc_e;
+endpoint_t *procp;
+phys_bytes *basep;
+phys_bytes *sizep;
+{
+ int r;
+ message m;
+
+ m.VMGD_REQ = req_proc_e;
+
+ r= _syscall(VM_PROC_NR, VM_GETDMA, &m);
+ if (r == 0)
+ {
+ *procp= m.VMGD_PROCP;
+ *basep= m.VMGD_BASEP;
+ *sizep= m.VMGD_SIZEP;
+ }
+ return r;
+}
+
--- /dev/null
+#include <lib.h>
+#include <unistd.h>
+
+PUBLIC int vm_memctl(endpoint_t ep, int req)
+{
+ message m;
+ m.VM_RS_CTL_ENDPT = ep;
+ m.VM_RS_CTL_REQ = req;
+
+ return _syscall(VM_PROC_NR, VM_RS_MEMCTL, &m);
+}
--- /dev/null
+#define _SYSTEM 1
+#include <lib.h>
+#include <unistd.h>
+
+/* return -1, when the query itself or the processing of query has errors.
+ * return 1, when there are more processes waiting to be queried.
+ * return 0, when there are no more processes.
+ * note that for the return value of 0 and 1, the 'endpt' is set accordingly.
+ */
+PUBLIC int vm_query_exit(int *endpt)
+{
+ message m;
+ int r;
+
+ r = _syscall(VM_PROC_NR, VM_QUERY_EXIT, &m);
+ if (r != OK)
+ return -1;
+ if (endpt == NULL)
+ return -1;
+
+ *endpt = m.VM_QUERY_RET_PT;
+ return (m.VM_QUERY_IS_MORE ? 1 : 0);
+}
--- /dev/null
+#include <lib.h>
+#include <unistd.h>
+
+PUBLIC int vm_set_priv(int nr, void *buf)
+{
+ message m;
+ m.VM_RS_NR = nr;
+ m.VM_RS_BUF = (long) buf;
+ return _syscall(VM_PROC_NR, VM_RS_SET_PRIV, &m);
+}
+
--- /dev/null
+#include <lib.h>
+#include <unistd.h>
+
+PUBLIC int vm_update(endpoint_t src_e, endpoint_t dst_e)
+{
+ message m;
+ m.VM_RS_SRC_ENDPT = src_e;
+ m.VM_RS_DST_ENDPT = dst_e;
+
+ return _syscall(VM_PROC_NR, VM_RS_UPDATE, &m);
+}