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.
This commit is contained in:
Gianluca Guida 2011-03-22 13:47:35 +00:00
parent 6bcf58bab8
commit 878ba523ac
36 changed files with 1712 additions and 0 deletions

View file

@ -0,0 +1,38 @@
.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>

View file

@ -0,0 +1,20 @@
/* 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);
}

View file

@ -0,0 +1,20 @@
/* 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);
}

View file

@ -0,0 +1,55 @@
/* 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;
}

View file

@ -0,0 +1,57 @@
/* 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;
}

191
lib/nbsd_libminlib/fslib.c Normal file
View file

@ -0,0 +1,191 @@
/* 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]);
}
}

View file

@ -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 <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);
}

54
lib/nbsd_libminlib/gcov.c Normal file
View file

@ -0,0 +1,54 @@
#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);
}

View file

@ -0,0 +1,14 @@
#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.
*/
;
}

View file

@ -0,0 +1,24 @@
/* 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;
}

View file

@ -0,0 +1,10 @@
#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 */
}

View file

@ -0,0 +1,9 @@
#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);
}

View file

@ -0,0 +1,14 @@
#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 */
}

View file

@ -0,0 +1,28 @@
#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;
}

View file

@ -0,0 +1,10 @@
#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 */
}

View file

@ -0,0 +1,13 @@
#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 */
}

View file

@ -0,0 +1,2 @@
SRCS+= _cpufeature.c _cpuid.S get_bp.S getprocessor.S \
oneC_sum.S read_tsc.S read_tsc_64.c

View file

@ -0,0 +1,66 @@
#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;
}

View file

@ -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 <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

View file

@ -0,0 +1,13 @@
/* 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 $ */

View file

@ -0,0 +1,51 @@
/* 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

View file

@ -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 <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 $ */

View file

@ -0,0 +1,42 @@
/* */
/* 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

View file

@ -0,0 +1,15 @@
#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);
}

36
lib/nbsd_libminlib/itoa.c Normal file
View file

@ -0,0 +1,36 @@
#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);
}

View file

@ -0,0 +1,21 @@
#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);
}

View file

@ -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 <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 $
*/

View file

@ -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 <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) */
}

View file

@ -0,0 +1,28 @@
/* 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;
}
}

129
lib/nbsd_libminlib/tools.h Normal file
View file

@ -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

View file

@ -0,0 +1,112 @@
/* 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

View file

@ -0,0 +1,59 @@
#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;
}

View file

@ -0,0 +1,11 @@
#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);
}

View file

@ -0,0 +1,23 @@
#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);
}

View file

@ -0,0 +1,11 @@
#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);
}

View file

@ -0,0 +1,11 @@
#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);
}