From: Gianluca Guida Date: Tue, 22 Mar 2011 13:47:35 +0000 (+0000) Subject: Add libminlib for NBSD libc compilation. X-Git-Tag: v3.2.0~607 X-Git-Url: http://zhaoyanbai.com/repos/%22../static/icons/man.7.txt?a=commitdiff_plain;h=878ba523acd770738b13e7aa069539103dc011ca;p=minix.git Add libminlib for NBSD libc compilation. This library includes various random and minix-specific functions included in the Minix libc. Most of them should be part of libsys, and in general it would be nice to extinguish this library over time. --- diff --git a/lib/nbsd_libminlib/Makefile b/lib/nbsd_libminlib/Makefile new file mode 100644 index 000000000..e049137d2 --- /dev/null +++ b/lib/nbsd_libminlib/Makefile @@ -0,0 +1,38 @@ +.include +.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 diff --git a/lib/nbsd_libminlib/adddma.c b/lib/nbsd_libminlib/adddma.c new file mode 100644 index 000000000..3652626ec --- /dev/null +++ b/lib/nbsd_libminlib/adddma.c @@ -0,0 +1,20 @@ +/* adddma.c + */ + +#include +#include +#include + +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); +} diff --git a/lib/nbsd_libminlib/deldma.c b/lib/nbsd_libminlib/deldma.c new file mode 100644 index 000000000..32301b46a --- /dev/null +++ b/lib/nbsd_libminlib/deldma.c @@ -0,0 +1,20 @@ +/* deldma.c + */ + +#include +#include +#include + +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); +} diff --git a/lib/nbsd_libminlib/dhcp_gettag.c b/lib/nbsd_libminlib/dhcp_gettag.c new file mode 100644 index 000000000..3dcb6e827 --- /dev/null +++ b/lib/nbsd_libminlib/dhcp_gettag.c @@ -0,0 +1,55 @@ +/* dhcp_gettag() Author: Kees J. Bot + * 1 Dec 2000 + */ +#define nil ((void*)0) +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libminlib/dhcp_settag.c b/lib/nbsd_libminlib/dhcp_settag.c new file mode 100644 index 000000000..7cba82d50 --- /dev/null +++ b/lib/nbsd_libminlib/dhcp_settag.c @@ -0,0 +1,57 @@ +/* dhcp_init(), dhcp_settag() Author: Kees J. Bot + * 1 Dec 2000 + */ +#define nil ((void*)0) +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/nbsd_libminlib/fslib.c b/lib/nbsd_libminlib/fslib.c new file mode 100644 index 000000000..bcbcd24c5 --- /dev/null +++ b/lib/nbsd_libminlib/fslib.c @@ -0,0 +1,191 @@ +/* fslib.c - routines needed by fs and fs utilities */ + +#include /* for unused stuff in :-( */ +#include +#include +#include +#include +#include +#include /* 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 + +/* 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]); + } +} diff --git a/lib/nbsd_libminlib/fsversion.c b/lib/nbsd_libminlib/fsversion.c new file mode 100644 index 000000000..49418995b --- /dev/null +++ b/lib/nbsd_libminlib/fsversion.c @@ -0,0 +1,63 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/lib/nbsd_libminlib/gcov.c b/lib/nbsd_libminlib/gcov.c new file mode 100644 index 000000000..5ce8a3996 --- /dev/null +++ b/lib/nbsd_libminlib/gcov.c @@ -0,0 +1,54 @@ +#include +#include +#include + +#include + +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); +} + diff --git a/lib/nbsd_libminlib/gcov_flush.c b/lib/nbsd_libminlib/gcov_flush.c new file mode 100644 index 000000000..60e678c2d --- /dev/null +++ b/lib/nbsd_libminlib/gcov_flush.c @@ -0,0 +1,14 @@ +#include +#include +#include + +#include + +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. + */ + ; +} + diff --git a/lib/nbsd_libminlib/getdma.c b/lib/nbsd_libminlib/getdma.c new file mode 100644 index 000000000..6588babf8 --- /dev/null +++ b/lib/nbsd_libminlib/getdma.c @@ -0,0 +1,24 @@ +/* getdma.c + */ + +#include +#include +#include + +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; +} diff --git a/lib/nbsd_libminlib/getngid.c b/lib/nbsd_libminlib/getngid.c new file mode 100644 index 000000000..d1c9b06d4 --- /dev/null +++ b/lib/nbsd_libminlib/getngid.c @@ -0,0 +1,10 @@ +#include +#include + +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 */ +} diff --git a/lib/nbsd_libminlib/getnpid.c b/lib/nbsd_libminlib/getnpid.c new file mode 100644 index 000000000..01ece33d5 --- /dev/null +++ b/lib/nbsd_libminlib/getnpid.c @@ -0,0 +1,9 @@ +#include +#include + +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); +} diff --git a/lib/nbsd_libminlib/getnprocnr.c b/lib/nbsd_libminlib/getnprocnr.c new file mode 100644 index 000000000..9f69e31bb --- /dev/null +++ b/lib/nbsd_libminlib/getnprocnr.c @@ -0,0 +1,14 @@ +#include +#include + + +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 */ +} + diff --git a/lib/nbsd_libminlib/getnucred.c b/lib/nbsd_libminlib/getnucred.c new file mode 100644 index 000000000..8fbe905e3 --- /dev/null +++ b/lib/nbsd_libminlib/getnucred.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +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; +} diff --git a/lib/nbsd_libminlib/getnuid.c b/lib/nbsd_libminlib/getnuid.c new file mode 100644 index 000000000..b09c8637d --- /dev/null +++ b/lib/nbsd_libminlib/getnuid.c @@ -0,0 +1,10 @@ +#include +#include + +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 */ +} diff --git a/lib/nbsd_libminlib/getprocnr.c b/lib/nbsd_libminlib/getprocnr.c new file mode 100644 index 000000000..3f5238fb7 --- /dev/null +++ b/lib/nbsd_libminlib/getprocnr.c @@ -0,0 +1,13 @@ +#include +#include + + +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 */ +} + diff --git a/lib/nbsd_libminlib/i386/Makefile.inc b/lib/nbsd_libminlib/i386/Makefile.inc new file mode 100644 index 000000000..a603b4019 --- /dev/null +++ b/lib/nbsd_libminlib/i386/Makefile.inc @@ -0,0 +1,2 @@ +SRCS+= _cpufeature.c _cpuid.S get_bp.S getprocessor.S \ + oneC_sum.S read_tsc.S read_tsc_64.c diff --git a/lib/nbsd_libminlib/i386/_cpufeature.c b/lib/nbsd_libminlib/i386/_cpufeature.c new file mode 100644 index 000000000..7a9630efd --- /dev/null +++ b/lib/nbsd_libminlib/i386/_cpufeature.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + +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; +} + diff --git a/lib/nbsd_libminlib/i386/_cpuid.S b/lib/nbsd_libminlib/i386/_cpuid.S new file mode 100644 index 000000000..9b0929fcd --- /dev/null +++ b/lib/nbsd_libminlib/i386/_cpuid.S @@ -0,0 +1,40 @@ +/* _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 + +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 diff --git a/lib/nbsd_libminlib/i386/get_bp.S b/lib/nbsd_libminlib/i386/get_bp.S new file mode 100644 index 000000000..8b0a2de3b --- /dev/null +++ b/lib/nbsd_libminlib/i386/get_bp.S @@ -0,0 +1,13 @@ +/* get_bp.s */ +/* */ +/* return EBP in EAX */ +/* */ +/* Created: Sep 7, 1992 by Philip Homburg */ + +#include + +ENTRY(get_bp) + movl %ebp, %eax + ret + +/* $PchId: get_bp.ack.s,v 1.3 1996/02/23 08:30:52 philip Exp $ */ diff --git a/lib/nbsd_libminlib/i386/getprocessor.S b/lib/nbsd_libminlib/i386/getprocessor.S new file mode 100644 index 000000000..f1daeba07 --- /dev/null +++ b/lib/nbsd_libminlib/i386/getprocessor.S @@ -0,0 +1,51 @@ +/* getprocessor() - determine processor type Author: Kees J. Bot */ +/* 26 Jan 1994 */ +#include + +/* 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 diff --git a/lib/nbsd_libminlib/i386/oneC_sum.S b/lib/nbsd_libminlib/i386/oneC_sum.S new file mode 100644 index 000000000..518fa0088 --- /dev/null +++ b/lib/nbsd_libminlib/i386/oneC_sum.S @@ -0,0 +1,88 @@ +/* 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 + +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 $ */ diff --git a/lib/nbsd_libminlib/i386/read_tsc.S b/lib/nbsd_libminlib/i386/read_tsc.S new file mode 100644 index 000000000..81ab97d2a --- /dev/null +++ b/lib/nbsd_libminlib/i386/read_tsc.S @@ -0,0 +1,42 @@ +/* */ +/* sections */ +#include + +/**===========================================================================* */ +/* 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 diff --git a/lib/nbsd_libminlib/i386/read_tsc_64.c b/lib/nbsd_libminlib/i386/read_tsc_64.c new file mode 100644 index 000000000..63faa10ad --- /dev/null +++ b/lib/nbsd_libminlib/i386/read_tsc_64.c @@ -0,0 +1,15 @@ + +#include +#include + +/* 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); +} + diff --git a/lib/nbsd_libminlib/itoa.c b/lib/nbsd_libminlib/itoa.c new file mode 100644 index 000000000..f78717d24 --- /dev/null +++ b/lib/nbsd_libminlib/itoa.c @@ -0,0 +1,36 @@ +#include +/* 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); +} diff --git a/lib/nbsd_libminlib/mapdriver.c b/lib/nbsd_libminlib/mapdriver.c new file mode 100644 index 000000000..1b3130f63 --- /dev/null +++ b/lib/nbsd_libminlib/mapdriver.c @@ -0,0 +1,21 @@ +#include +#include +#include + + +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); +} + diff --git a/lib/nbsd_libminlib/paramvalue.c b/lib/nbsd_libminlib/paramvalue.c new file mode 100644 index 000000000..ae76ee9d9 --- /dev/null +++ b/lib/nbsd_libminlib/paramvalue.c @@ -0,0 +1,51 @@ +/* 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 +#include +#include +#include +#include + +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 $ + */ diff --git a/lib/nbsd_libminlib/servxcheck.c b/lib/nbsd_libminlib/servxcheck.c new file mode 100644 index 000000000..330dbc1ca --- /dev/null +++ b/lib/nbsd_libminlib/servxcheck.c @@ -0,0 +1,283 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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) */ +} diff --git a/lib/nbsd_libminlib/svrctl.c b/lib/nbsd_libminlib/svrctl.c new file mode 100644 index 000000000..6d4578c56 --- /dev/null +++ b/lib/nbsd_libminlib/svrctl.c @@ -0,0 +1,28 @@ +/* svrctl() - special server control functions. Author: Kees J. Bot + * 24 Apr 1994 + */ +#include +#include +#include + +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; + } +} diff --git a/lib/nbsd_libminlib/tools.h b/lib/nbsd_libminlib/tools.h new file mode 100644 index 000000000..a69db0e5f --- /dev/null +++ b/lib/nbsd_libminlib/tools.h @@ -0,0 +1,129 @@ +#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 diff --git a/lib/nbsd_libminlib/u64util.c b/lib/nbsd_libminlib/u64util.c new file mode 100644 index 000000000..05b8436c8 --- /dev/null +++ b/lib/nbsd_libminlib/u64util.c @@ -0,0 +1,112 @@ +/* Few u64 utils implemented in C + * Author: Gautam BT + */ +#include + +#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 + diff --git a/lib/nbsd_libminlib/vm_dmacalls.c b/lib/nbsd_libminlib/vm_dmacalls.c new file mode 100644 index 000000000..cc3dd5e69 --- /dev/null +++ b/lib/nbsd_libminlib/vm_dmacalls.c @@ -0,0 +1,59 @@ + +#include +#include +#include +#include + +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; +} + diff --git a/lib/nbsd_libminlib/vm_memctl.c b/lib/nbsd_libminlib/vm_memctl.c new file mode 100644 index 000000000..921ff076a --- /dev/null +++ b/lib/nbsd_libminlib/vm_memctl.c @@ -0,0 +1,11 @@ +#include +#include + +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); +} diff --git a/lib/nbsd_libminlib/vm_query_exit.c b/lib/nbsd_libminlib/vm_query_exit.c new file mode 100644 index 000000000..f590283c6 --- /dev/null +++ b/lib/nbsd_libminlib/vm_query_exit.c @@ -0,0 +1,23 @@ +#define _SYSTEM 1 +#include +#include + +/* 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); +} diff --git a/lib/nbsd_libminlib/vm_set_priv.c b/lib/nbsd_libminlib/vm_set_priv.c new file mode 100644 index 000000000..969acf686 --- /dev/null +++ b/lib/nbsd_libminlib/vm_set_priv.c @@ -0,0 +1,11 @@ +#include +#include + +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); +} + diff --git a/lib/nbsd_libminlib/vm_update.c b/lib/nbsd_libminlib/vm_update.c new file mode 100644 index 000000000..9e860c8e6 --- /dev/null +++ b/lib/nbsd_libminlib/vm_update.c @@ -0,0 +1,11 @@ +#include +#include + +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); +}