Basic VM and other minor improvements.
Not complete, probably not fully debugged or optimized.
This commit is contained in:
@@ -27,6 +27,7 @@ libc_FILES=" \
|
||||
_sprofile.c \
|
||||
_svrctl.c \
|
||||
_sysuname.c \
|
||||
_vm_dmacalls.c \
|
||||
asynchio.c \
|
||||
basename.c \
|
||||
bcmp.c \
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
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, GETPROCNR, &m) < 0) return(-1);
|
||||
if (_syscall(PM_PROC_NR, t, &m) < 0) return(-1);
|
||||
return(m.m1_i1); /* return search result */
|
||||
}
|
||||
|
||||
|
||||
62
lib/other/_vm_dmacalls.c
Normal file
62
lib/other/_vm_dmacalls.c
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
#include <lib.h>
|
||||
#define vm_adddma _vm_adddma
|
||||
#define vm_deldma _vm_deldma
|
||||
#define vm_getdma _vm_getdma
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ libc_FILES=" \
|
||||
_mkfifo.c \
|
||||
_mknod.c \
|
||||
_mount.c \
|
||||
_mmap.c \
|
||||
_open.c \
|
||||
_opendir.c \
|
||||
_pathconf.c \
|
||||
@@ -101,6 +102,7 @@ libc_FILES=" \
|
||||
getloadavg.c \
|
||||
getopt.c \
|
||||
gettimeofday.c \
|
||||
glob.c \
|
||||
nice.c \
|
||||
priority.c \
|
||||
usleep.c"
|
||||
|
||||
40
lib/posix/_mmap.c
Executable file
40
lib/posix/_mmap.c
Executable file
@@ -0,0 +1,40 @@
|
||||
#define _SYSTEM 1
|
||||
#include <lib.h>
|
||||
#define mmap _mmap
|
||||
#define munmap _munmap
|
||||
#include <sys/mman.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
PUBLIC void *mmap(void *addr, size_t len, int prot, int flags,
|
||||
int fd, off_t offset)
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
|
||||
m.VMM_ADDR = (vir_bytes) addr;
|
||||
m.VMM_LEN = len;
|
||||
m.VMM_PROT = prot;
|
||||
m.VMM_FLAGS = flags;
|
||||
m.VMM_FD = fd;
|
||||
m.VMM_OFFSET = offset;
|
||||
|
||||
r = _syscall(VM_PROC_NR, VM_MMAP, &m);
|
||||
|
||||
if(r != OK) {
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
return (void *) m.VMM_RETADDR;
|
||||
}
|
||||
|
||||
PUBLIC int munmap(void *addr, size_t len)
|
||||
{
|
||||
message m;
|
||||
|
||||
m.VMUM_ADDR = addr;
|
||||
m.VMUM_LEN = len;
|
||||
|
||||
return _syscall(VM_PROC_NR, VM_UNMAP, &m);
|
||||
}
|
||||
@@ -28,7 +28,7 @@ int getloadavg(double *loadavg, int nelem)
|
||||
nelem = PERIODS;
|
||||
|
||||
/* How many ticks are missing from the newest-filled slot? */
|
||||
#define TICKSPERSLOT (_LOAD_UNIT_SECS * HZ)
|
||||
#define TICKSPERSLOT (_LOAD_UNIT_SECS * sys_hz())
|
||||
unfilled_ticks = TICKSPERSLOT - (loadinfo.last_clock % TICKSPERSLOT);
|
||||
|
||||
for(p = 0; p < nelem; p++) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Z=../../commands/zoneinfo
|
||||
|
||||
CFLAGS="-O -D_MINIX -D_POSIX_SOURCE -D__USG -I$Z"
|
||||
CFLAGS="-D_MINIX -D_POSIX_SOURCE -D__USG -I$Z"
|
||||
|
||||
LIBRARIES=libc
|
||||
libc_FILES="
|
||||
|
||||
@@ -67,6 +67,7 @@ libc_FILES=" \
|
||||
mkdir.s \
|
||||
mkfifo.s \
|
||||
mknod.s \
|
||||
mmap.s \
|
||||
mount.s \
|
||||
open.s \
|
||||
opendir.s \
|
||||
@@ -119,6 +120,7 @@ libc_FILES=" \
|
||||
uname.s \
|
||||
unlink.s \
|
||||
utime.s \
|
||||
vm_dmacalls.s \
|
||||
wait.s \
|
||||
waitpid.s \
|
||||
write.s"
|
||||
|
||||
7
lib/syscall/mmap.s
Executable file
7
lib/syscall/mmap.s
Executable file
@@ -0,0 +1,7 @@
|
||||
.sect .text
|
||||
.extern __mmap
|
||||
.define _mmap
|
||||
.align 2
|
||||
|
||||
_mmap:
|
||||
jmp __mmap
|
||||
16
lib/syscall/vm_dmacalls.s
Normal file
16
lib/syscall/vm_dmacalls.s
Normal file
@@ -0,0 +1,16 @@
|
||||
.sect .text
|
||||
.extern __vm_adddma
|
||||
.define _vm_adddma
|
||||
.extern __vm_deldma
|
||||
.define _vm_deldma
|
||||
.extern __vm_getdma
|
||||
.define _vm_getdma
|
||||
.align 2
|
||||
|
||||
_vm_adddma:
|
||||
jmp __vm_adddma
|
||||
_vm_deldma:
|
||||
jmp __vm_deldma
|
||||
_vm_getdma:
|
||||
jmp __vm_getdma
|
||||
|
||||
@@ -5,6 +5,7 @@ CFLAGS="-O -D_MINIX -D_POSIX_SOURCE"
|
||||
LIBRARIES=libsys
|
||||
|
||||
libsys_FILES=" \
|
||||
alloc_util.c \
|
||||
assert.c \
|
||||
panic.c \
|
||||
pci_attr_r16.c \
|
||||
@@ -64,12 +65,20 @@ libsys_FILES=" \
|
||||
sys_vinl.c \
|
||||
sys_vinw.c \
|
||||
sys_vircopy.c \
|
||||
sys_vm_map.c \
|
||||
sys_vm_setbuf.c \
|
||||
sys_vmctl.c \
|
||||
sys_voutb.c \
|
||||
sys_voutl.c \
|
||||
sys_voutw.c \
|
||||
taskcall.c \
|
||||
ds.c"
|
||||
ds.c \
|
||||
vm_allocmem.c \
|
||||
vm_brk.c \
|
||||
vm_exec_newmem.c \
|
||||
vm_exit.c \
|
||||
vm_fork.c \
|
||||
vm_map_phys.c \
|
||||
vm_umap.c \
|
||||
vm_push_sig.c"
|
||||
|
||||
TYPE=both
|
||||
|
||||
69
lib/syslib/alloc_util.c
Normal file
69
lib/syslib/alloc_util.c
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <minix/sysutil.h>
|
||||
|
||||
int sys_umap_data_fb(endpoint_t ep, vir_bytes buf, vir_bytes len, phys_bytes *phys)
|
||||
{
|
||||
int r;
|
||||
|
||||
if((r=sys_umap(ep, VM_D, buf, len, phys)) != OK) {
|
||||
if(r != EINVAL)
|
||||
return r;
|
||||
r = sys_umap(ep, D, buf, len, phys);
|
||||
}
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void *alloc_contig(size_t len, int flags, phys_bytes *phys)
|
||||
{
|
||||
int r;
|
||||
vir_bytes buf;
|
||||
int mmapflags = MAP_PREALLOC|MAP_CONTIG|MAP_ANON;
|
||||
|
||||
if(flags & AC_LOWER16M)
|
||||
mmapflags |= MAP_LOWER16M;
|
||||
|
||||
/* First try to get memory with mmap. This is gauranteed
|
||||
* to be page-aligned, and we can tell VM it has to be
|
||||
* pre-allocated and contiguous.
|
||||
*/
|
||||
errno = 0;
|
||||
buf = (vir_bytes) mmap(0, len, PROT_READ|PROT_WRITE, mmapflags, -1, 0);
|
||||
|
||||
/* If that failed, maybe we're not running in paged mode.
|
||||
* If that's the case, ENXIO will be returned.
|
||||
* Memory returned with malloc() will be preallocated and
|
||||
* contiguous, so fallback on that, and ask for a little extra
|
||||
* so we can page align it ourselves.
|
||||
*/
|
||||
if(buf == (vir_bytes) MAP_FAILED) {
|
||||
if(errno != (_SIGN ENXIO)) {
|
||||
return NULL;
|
||||
}
|
||||
#define ALIGN 4096
|
||||
if(flags & AC_ALIGN4K) {
|
||||
if(len + ALIGN < len)
|
||||
return NULL;
|
||||
len += ALIGN;
|
||||
}
|
||||
if(!(buf = (vir_bytes) malloc(len))) {
|
||||
return NULL;
|
||||
}
|
||||
if(flags & AC_ALIGN4K)
|
||||
buf += ALIGN - (buf % ALIGN);
|
||||
}
|
||||
|
||||
/* Get physical address. */
|
||||
if(sys_umap_data_fb(SELF, buf, len, phys) != OK)
|
||||
panic("alloc_contig.c", "sys_umap_data_fb failed", NO_NUM);
|
||||
|
||||
return (void *) buf;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
#define GRANTBAD -1001
|
||||
|
||||
int
|
||||
ds_subscribe(ds_name_regexp, type, flags)
|
||||
char *ds_name_regexp;
|
||||
@@ -20,7 +22,7 @@ int flags;
|
||||
(vir_bytes) ds_name_regexp, len, CPF_READ);
|
||||
|
||||
if(!GRANT_VALID(g))
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
|
||||
flags &= DS_INITIAL;
|
||||
|
||||
@@ -49,7 +51,7 @@ u32_t value;
|
||||
(vir_bytes) ds_name, len, CPF_READ);
|
||||
|
||||
if(!GRANT_VALID(g))
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
|
||||
m.DS_KEY_GRANT = (char *) g;
|
||||
m.DS_KEY_LEN = len;
|
||||
@@ -78,7 +80,7 @@ char *value;
|
||||
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||
(vir_bytes) ds_name, len_key, CPF_READ);
|
||||
if(!GRANT_VALID(g_key))
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
|
||||
/* Grant for value. */
|
||||
len_str = strlen(value)+1;
|
||||
@@ -87,7 +89,7 @@ char *value;
|
||||
|
||||
if(!GRANT_VALID(g_str)) {
|
||||
cpf_revoke(g_key);
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
}
|
||||
|
||||
m.DS_KEY_GRANT = (char *) g_key;
|
||||
@@ -118,7 +120,7 @@ u32_t *value;
|
||||
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||
(vir_bytes) ds_name, len_key, CPF_READ);
|
||||
if(!GRANT_VALID(g_key))
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
|
||||
/* Do request. */
|
||||
m.DS_KEY_GRANT = (char *) g_key;
|
||||
@@ -150,7 +152,7 @@ size_t len_str;
|
||||
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||
(vir_bytes) ds_name, len_key, CPF_READ);
|
||||
if(!GRANT_VALID(g_key))
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
|
||||
/* Grant for value. */
|
||||
g_str = cpf_grant_direct(DS_PROC_NR,
|
||||
@@ -158,7 +160,7 @@ size_t len_str;
|
||||
|
||||
if(!GRANT_VALID(g_str)) {
|
||||
cpf_revoke(g_key);
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
}
|
||||
|
||||
/* Do request. */
|
||||
@@ -187,13 +189,13 @@ size_t len_str;
|
||||
message m;
|
||||
cp_grant_id_t g_key, g_str;
|
||||
|
||||
if(len_key < 1 || len_str < 1) return -1;
|
||||
if(len_key < 1 || len_str < 1) return -1002;
|
||||
|
||||
/* Grant for key. */
|
||||
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||
(vir_bytes) ds_key, len_key, CPF_WRITE);
|
||||
if(!GRANT_VALID(g_key))
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
|
||||
/* Grant for value. */
|
||||
g_str = cpf_grant_direct(DS_PROC_NR,
|
||||
@@ -201,7 +203,7 @@ size_t len_str;
|
||||
|
||||
if(!GRANT_VALID(g_str)) {
|
||||
cpf_revoke(g_key);
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
}
|
||||
|
||||
/* Do request. */
|
||||
@@ -238,7 +240,7 @@ u32_t *value;
|
||||
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||
(vir_bytes) ds_key, len_key, CPF_WRITE);
|
||||
if(!GRANT_VALID(g_key))
|
||||
return -1;
|
||||
return GRANTBAD;
|
||||
|
||||
/* Do request. */
|
||||
m.DS_KEY_GRANT = (char *) g_key;
|
||||
|
||||
@@ -19,9 +19,19 @@ int num; /* number to go with format string */
|
||||
* value of a defined constant.
|
||||
*/
|
||||
message m;
|
||||
endpoint_t me = NONE;
|
||||
char name[20];
|
||||
void (*suicide)(void);
|
||||
|
||||
if(panicing) return;
|
||||
panicing= 1;
|
||||
|
||||
if(sys_whoami(&me, name, sizeof(name)) == OK && me != NONE)
|
||||
printf("%s(%d): ", name, me);
|
||||
else
|
||||
printf("(sys_whoami failed): ");
|
||||
printf("syslib:panic.c: stacktrace: ");
|
||||
util_stacktrace();
|
||||
|
||||
if (NULL != who && NULL != mess) {
|
||||
if (num != NO_NUM) {
|
||||
printf("Panic in %s: %s: %d\n", who, mess, num);
|
||||
@@ -39,12 +49,10 @@ int num; /* number to go with format string */
|
||||
/* If exiting nicely through PM fails for some reason, try to
|
||||
* commit suicide. E.g., message to PM might fail due to deadlock.
|
||||
*/
|
||||
printf("panic: trying exception\n");
|
||||
suicide = (void (*)(void)) -1;
|
||||
suicide();
|
||||
|
||||
/* If committing suicide fails for some reason, hang. */
|
||||
printf("panic: for ever and ever\n");
|
||||
for(;;) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -52,8 +52,9 @@ cpf_grow(void)
|
||||
assert(new_size > ngrants);
|
||||
|
||||
/* Allocate a block of new size. */
|
||||
if(!(new_grants=malloc(new_size * sizeof(grants[0]))))
|
||||
if(!(new_grants=malloc(new_size * sizeof(grants[0])))) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy old block to new block. */
|
||||
if(grants && ngrants > 0)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include "syslib.h"
|
||||
|
||||
PUBLIC int sys_fork(parent, child, child_endpoint, map_ptr)
|
||||
int parent; /* process doing the fork */
|
||||
int child; /* which proc has been created by the fork */
|
||||
PUBLIC int sys_fork(parent, child, child_endpoint, map_ptr, flags)
|
||||
endpoint_t parent; /* process doing the fork */
|
||||
endpoint_t child; /* which proc has been created by the fork */
|
||||
int *child_endpoint;
|
||||
struct mem_map *map_ptr;
|
||||
u32_t flags;
|
||||
{
|
||||
/* A process has forked. Tell the kernel. */
|
||||
|
||||
@@ -14,6 +15,7 @@ struct mem_map *map_ptr;
|
||||
m.PR_ENDPT = parent;
|
||||
m.PR_SLOT = child;
|
||||
m.PR_MEM_PTR = (char *) map_ptr;
|
||||
m.PR_FORK_FLAGS = flags;
|
||||
r = _taskcall(SYSTASK, SYS_FORK, &m);
|
||||
*child_endpoint = m.PR_ENDPT;
|
||||
return r;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
/*===========================================================================*
|
||||
@@ -22,4 +25,29 @@ int len2; /* length or process nr */
|
||||
return(_taskcall(SYSTASK, SYS_GETINFO, &m));
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* sys_whoami *
|
||||
*===========================================================================*/
|
||||
PUBLIC int sys_whoami(endpoint_t *who_ep, char *who_name, int len)
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
int lenmin;
|
||||
|
||||
m.I_REQUEST = GET_WHOAMI;
|
||||
|
||||
if(len < 2)
|
||||
return EINVAL;
|
||||
|
||||
if((r = _taskcall(SYSTASK, SYS_GETINFO, &m)) != OK)
|
||||
return r;
|
||||
|
||||
lenmin = MIN(len, sizeof(m.GIWHO_NAME)) - 1;
|
||||
|
||||
strncpy(who_name, m.GIWHO_NAME, lenmin);
|
||||
who_name[lenmin] = '\0';
|
||||
*who_ep = m.GIWHO_EP;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#include "syslib.h"
|
||||
|
||||
/*===========================================================================*
|
||||
* sys_vm_map *
|
||||
*===========================================================================*/
|
||||
PUBLIC int sys_vm_map(proc_nr, do_map, base, size, offset)
|
||||
int proc_nr;
|
||||
int do_map;
|
||||
phys_bytes base;
|
||||
phys_bytes size;
|
||||
phys_bytes offset;
|
||||
{
|
||||
message m;
|
||||
int result;
|
||||
|
||||
m.m4_l1= proc_nr;
|
||||
m.m4_l2= do_map;
|
||||
m.m4_l3= base;
|
||||
m.m4_l4= size;
|
||||
m.m4_l5= offset;
|
||||
|
||||
result = _taskcall(SYSTASK, SYS_VM_MAP, &m);
|
||||
return(result);
|
||||
}
|
||||
|
||||
61
lib/syslib/sys_vmctl.c
Executable file
61
lib/syslib/sys_vmctl.c
Executable file
@@ -0,0 +1,61 @@
|
||||
#include "syslib.h"
|
||||
|
||||
PUBLIC int sys_vmctl(endpoint_t who, int param, u32_t value)
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
|
||||
m.SVMCTL_WHO = who;
|
||||
m.SVMCTL_PARAM = param;
|
||||
m.SVMCTL_VALUE = value;
|
||||
r = _taskcall(SYSTASK, SYS_VMCTL, &m);
|
||||
return(r);
|
||||
}
|
||||
|
||||
PUBLIC int sys_vmctl_get_pagefault_i386(endpoint_t *who, u32_t *cr2, u32_t *err)
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
|
||||
m.SVMCTL_WHO = SELF;
|
||||
m.SVMCTL_PARAM = VMCTL_GET_PAGEFAULT;
|
||||
r = _taskcall(SYSTASK, SYS_VMCTL, &m);
|
||||
if(r == OK) {
|
||||
*who = m.SVMCTL_PF_WHO;
|
||||
*cr2 = m.SVMCTL_PF_I386_CR2;
|
||||
*err = m.SVMCTL_PF_I386_ERR;
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
PUBLIC int sys_vmctl_get_cr3_i386(endpoint_t who, u32_t *cr3)
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
|
||||
m.SVMCTL_WHO = who;
|
||||
m.SVMCTL_PARAM = VMCTL_I386_GETCR3;
|
||||
r = _taskcall(SYSTASK, SYS_VMCTL, &m);
|
||||
if(r == OK) {
|
||||
*cr3 = m.SVMCTL_VALUE;
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
PUBLIC int sys_vmctl_get_memreq(endpoint_t *who, vir_bytes *mem,
|
||||
vir_bytes *len, int *wrflag)
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
|
||||
m.SVMCTL_WHO = SELF;
|
||||
m.SVMCTL_PARAM = VMCTL_MEMREQ_GET;
|
||||
r = _taskcall(SYSTASK, SYS_VMCTL, &m);
|
||||
if(r == OK) {
|
||||
*who = m.SVMCTL_MRG_EP;
|
||||
*mem = (vir_bytes) m.SVMCTL_MRG_ADDR;
|
||||
*len = m.SVMCTL_MRG_LEN;
|
||||
*wrflag = m.SVMCTL_MRG_WRITE;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
21
lib/syslib/vm_allocmem.c
Normal file
21
lib/syslib/vm_allocmem.c
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
#include <minix/vm.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* vm_allocmem *
|
||||
*===========================================================================*/
|
||||
PUBLIC int vm_allocmem(phys_clicks clicks, phys_clicks *retmembase)
|
||||
{
|
||||
message m;
|
||||
int result;
|
||||
|
||||
m.VMAM_CLICKS = clicks;
|
||||
result = _taskcall(VM_PROC_NR, VM_ALLOCMEM, &m);
|
||||
if(result == OK)
|
||||
*retmembase = m.VMAM_MEMBASE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
19
lib/syslib/vm_brk.c
Normal file
19
lib/syslib/vm_brk.c
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
#include <minix/vm.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* vm_brk *
|
||||
*===========================================================================*/
|
||||
PUBLIC int vm_brk(endpoint_t ep, char *addr)
|
||||
{
|
||||
message m;
|
||||
int result;
|
||||
|
||||
m.VMB_ENDPOINT = ep;
|
||||
m.VMB_ADDR = (void *) addr;
|
||||
|
||||
return _taskcall(VM_PROC_NR, VM_BRK, &m);
|
||||
}
|
||||
|
||||
26
lib/syslib/vm_exec_newmem.c
Normal file
26
lib/syslib/vm_exec_newmem.c
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
#include <minix/vm.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* vm_exec_newmem *
|
||||
*===========================================================================*/
|
||||
PUBLIC int vm_exec_newmem(endpoint_t ep, struct exec_newmem *args,
|
||||
int argssize, char **ret_stack_top, int *ret_flags)
|
||||
{
|
||||
message m;
|
||||
int result;
|
||||
|
||||
m.VMEN_ENDPOINT = ep;
|
||||
m.VMEN_ARGSPTR = (void *) args;
|
||||
m.VMEN_ARGSSIZE = argssize;
|
||||
|
||||
result = _taskcall(VM_PROC_NR, VM_EXEC_NEWMEM, &m);
|
||||
|
||||
*ret_stack_top = m.VMEN_STACK_TOP;
|
||||
*ret_flags = m.VMEN_FLAGS;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
34
lib/syslib/vm_exit.c
Normal file
34
lib/syslib/vm_exit.c
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
#include <minix/vm.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* vm_exit *
|
||||
*===========================================================================*/
|
||||
PUBLIC int vm_exit(endpoint_t ep)
|
||||
{
|
||||
message m;
|
||||
int result;
|
||||
|
||||
m.VME_ENDPOINT = ep;
|
||||
|
||||
result = _taskcall(VM_PROC_NR, VM_EXIT, &m);
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* vm_willexit *
|
||||
*===========================================================================*/
|
||||
PUBLIC int vm_willexit(endpoint_t ep)
|
||||
{
|
||||
message m;
|
||||
int result;
|
||||
|
||||
m.VMWE_ENDPOINT = ep;
|
||||
|
||||
result = _taskcall(VM_PROC_NR, VM_WILLEXIT, &m);
|
||||
return(result);
|
||||
}
|
||||
|
||||
23
lib/syslib/vm_fork.c
Normal file
23
lib/syslib/vm_fork.c
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
#include <minix/vm.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* vm_fork *
|
||||
*===========================================================================*/
|
||||
PUBLIC int vm_fork(endpoint_t ep, int slot, int *childep)
|
||||
{
|
||||
message m;
|
||||
int result;
|
||||
|
||||
m.VMF_ENDPOINT = ep;
|
||||
m.VMF_SLOTNO = slot;
|
||||
|
||||
result = _taskcall(VM_PROC_NR, VM_FORK, &m);
|
||||
|
||||
*childep = m.VMF_CHILD_ENDPOINT;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
37
lib/syslib/vm_map_phys.c
Normal file
37
lib/syslib/vm_map_phys.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#define _SYSTEM 1
|
||||
#include <lib.h>
|
||||
#define vm_map_phys _vm_map_phys
|
||||
#define vm_unmap_phys _vm_unmap_phys
|
||||
#include <sys/mman.h>
|
||||
#include <minix/vm.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
PUBLIC void *vm_map_phys(endpoint_t who, size_t len, void *phaddr)
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
|
||||
m.VMMP_EP = who;
|
||||
m.VMMP_PHADDR = phaddr;
|
||||
m.VMMP_LEN = len;
|
||||
|
||||
r = _syscall(VM_PROC_NR, VM_MAP_PHYS, &m);
|
||||
|
||||
if(r != OK) return MAP_FAILED;
|
||||
|
||||
return (void *) m.VMMP_VADDR_REPLY;
|
||||
}
|
||||
|
||||
PUBLIC int vm_unmap_phys(endpoint_t who, void *vaddr, size_t len)
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
|
||||
m.VMUP_EP = who;
|
||||
m.VMUP_VADDR = vaddr;
|
||||
|
||||
return _syscall(VM_PROC_NR, VM_UNMAP_PHYS, &m);
|
||||
}
|
||||
|
||||
20
lib/syslib/vm_push_sig.c
Normal file
20
lib/syslib/vm_push_sig.c
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
#include <minix/vm.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* vm_push_sig *
|
||||
*===========================================================================*/
|
||||
PUBLIC int vm_push_sig(endpoint_t ep, vir_bytes *old_sp)
|
||||
{
|
||||
message m;
|
||||
int result;
|
||||
|
||||
m.VMPS_ENDPOINT = ep;
|
||||
result = _taskcall(VM_PROC_NR, VM_PUSH_SIG, &m);
|
||||
*old_sp = (vir_bytes) m.VMPS_OLD_SP;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
22
lib/syslib/vm_umap.c
Normal file
22
lib/syslib/vm_umap.c
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
#include "syslib.h"
|
||||
|
||||
#include <minix/vm.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* vm_umap *
|
||||
*===========================================================================*/
|
||||
PUBLIC int vm_umap(int seg, vir_bytes offset, vir_bytes len, phys_bytes *addr)
|
||||
{
|
||||
message m;
|
||||
int result;
|
||||
|
||||
m.VMU_SEG = seg;
|
||||
m.VMU_OFFSET = offset;
|
||||
m.VMU_LENGTH = len;
|
||||
result = _taskcall(VM_PROC_NR, VM_UMAP, &m);
|
||||
*addr = m.VMU_RETADDR;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# Makefile for lib/utils.
|
||||
# Makefile for lib/sysutil.
|
||||
|
||||
CFLAGS="-O -D_MINIX -D_POSIX_SOURCE"
|
||||
|
||||
LIBRARIES=libsysutil
|
||||
LIBRARIES=libsys
|
||||
|
||||
libsysutil_FILES=" \
|
||||
libsys_FILES=" \
|
||||
asynsend.c \
|
||||
kmalloc.c \
|
||||
kprintf.c \
|
||||
kputc.c \
|
||||
@@ -21,6 +22,8 @@ libsysutil_FILES=" \
|
||||
taskcall.c \
|
||||
read_tsc.s \
|
||||
read_tsc_64.c \
|
||||
stacktrace.c \
|
||||
sys_hz.c \
|
||||
profile_extern.c \
|
||||
profile.c"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "sysutil.h"
|
||||
|
||||
static char print_buf[80]; /* output is buffered here */
|
||||
static char print_buf[80*25]; /* output is buffered here */
|
||||
|
||||
int kputc_use_private_grants= 0;
|
||||
|
||||
@@ -56,15 +56,22 @@ int c;
|
||||
|
||||
for(p = 0; procs[p] != NONE; p++) {
|
||||
/* Send the buffer to this output driver. */
|
||||
int may_asyn = 0;
|
||||
m.DIAG_BUF_COUNT = buf_count;
|
||||
if(GRANT_VALID(printgrants[p])) {
|
||||
m.m_type = DIAGNOSTICS_S;
|
||||
m.DIAG_PRINT_BUF_G = (char *) printgrants[p];
|
||||
may_asyn = 1;
|
||||
} else {
|
||||
m.m_type = DIAGNOSTICS;
|
||||
m.DIAG_PRINT_BUF_G = print_buf;
|
||||
}
|
||||
(void) _sendrec(procs[p], &m);
|
||||
if(may_asyn && procs[p] == LOG_PROC_NR) {
|
||||
m.m_type = ASYN_DIAGNOSTICS;
|
||||
(void) asynsend(procs[p], &m);
|
||||
} else {
|
||||
sendrec(procs[p], &m);
|
||||
}
|
||||
}
|
||||
|
||||
buf_count = 0;
|
||||
|
||||
@@ -10,20 +10,31 @@
|
||||
|
||||
#include "sysutil.h"
|
||||
|
||||
#define CALIBRATE_TICKS (HZ/5)
|
||||
#define CALIBRATE_TICKS(h) ((h)/5)
|
||||
#define MICROHZ 1000000 /* number of micros per second */
|
||||
#define MICROSPERTICK (MICROHZ/HZ) /* number of micros per HZ tick */
|
||||
#define MICROSPERTICK(h) (MICROHZ/(h)) /* number of micros per HZ tick */
|
||||
|
||||
static u32_t calib_tsc;
|
||||
#define CALIBRATE \
|
||||
if(!calibrated) { \
|
||||
int r; \
|
||||
if((r=micro_delay_calibrate()) != OK) \
|
||||
panic(__FILE__, "micro_delay: calibrate failed\n", r); \
|
||||
}
|
||||
|
||||
static u32_t calib_tsc, Hz = 0;
|
||||
static int calibrated = 0;
|
||||
|
||||
int
|
||||
micro_delay_calibrate(void)
|
||||
{
|
||||
u64_t start, end, diff, hz;
|
||||
u64_t start, end, diff;
|
||||
struct tms tms;
|
||||
unsigned long t = 0;
|
||||
|
||||
/* Get HZ. */
|
||||
if(sys_getinfo(GET_HZ, &Hz, sizeof(Hz), 0, 0) != OK)
|
||||
Hz = HZ;
|
||||
|
||||
/* Wait for clock to tick. */
|
||||
while(!t || (t == times(&tms)))
|
||||
t = times(&tms);
|
||||
@@ -34,7 +45,7 @@ micro_delay_calibrate(void)
|
||||
* this using the TSC.
|
||||
*/
|
||||
read_tsc_64(&start);
|
||||
while(times(&tms) < t+CALIBRATE_TICKS) ;
|
||||
while(times(&tms) < t+CALIBRATE_TICKS(Hz)) ;
|
||||
read_tsc_64(&end);
|
||||
|
||||
diff = sub64(end, start);
|
||||
@@ -43,10 +54,12 @@ micro_delay_calibrate(void)
|
||||
"micro_delay_calibrate: CALIBRATE_TICKS too high "
|
||||
"for TSC frequency\n", NO_NUM);
|
||||
calib_tsc = ex64lo(diff);
|
||||
#if 0
|
||||
printf("micro_delay_calibrate: "
|
||||
"%lu cycles/%d ticks of %d Hz; %lu cycles/s\n",
|
||||
calib_tsc, CALIBRATE_TICKS, HZ,
|
||||
div64u(mul64u(calib_tsc, HZ), CALIBRATE_TICKS));
|
||||
calib_tsc, CALIBRATE_TICKS(Hz), Hz,
|
||||
div64u(mul64u(calib_tsc, Hz), CALIBRATE_TICKS(Hz)));
|
||||
#endif
|
||||
calibrated = 1;
|
||||
|
||||
return OK;
|
||||
@@ -60,17 +73,11 @@ micro_delay(u32_t micros)
|
||||
/* Start of delay. */
|
||||
read_tsc_64(&now);
|
||||
|
||||
/* We have to be calibrated. */
|
||||
if(!calibrated) {
|
||||
int r;
|
||||
printf("micro_delay: calibrating\n");
|
||||
if((r=micro_delay_calibrate()) != OK)
|
||||
panic(__FILE__, "micro_delay: calibrate failed\n", r);
|
||||
}
|
||||
CALIBRATE;
|
||||
|
||||
/* We have to know when to end the delay. */
|
||||
end = add64u(now, div64u(mul64u(calib_tsc,
|
||||
micros * HZ / CALIBRATE_TICKS), MICROHZ));
|
||||
micros * Hz / CALIBRATE_TICKS(Hz)), MICROHZ));
|
||||
|
||||
/* If we have to wait for at least one HZ tick, use the regular
|
||||
* tickdelay first. Round downwards on purpose, so the average
|
||||
@@ -78,8 +85,8 @@ micro_delay(u32_t micros)
|
||||
* we call tickdelay). We can correct for both overhead of tickdelay
|
||||
* itself and the short wait in the busywait later.
|
||||
*/
|
||||
if(micros >= MICROSPERTICK)
|
||||
tickdelay(micros*HZ/MICROHZ);
|
||||
if(micros >= MICROSPERTICK(Hz))
|
||||
tickdelay(micros*Hz/MICROHZ);
|
||||
|
||||
/* Wait (the rest) of the delay time using busywait. */
|
||||
while(cmp64(now, end) < 0)
|
||||
@@ -87,3 +94,4 @@ micro_delay(u32_t micros)
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
63
lib/sysutil/stacktrace.c
Normal file
63
lib/sysutil/stacktrace.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
stacktrace.c
|
||||
|
||||
Created: Jan 19, 1993 by Philip Homburg
|
||||
|
||||
Copyright 1995 Philip Homburg
|
||||
*/
|
||||
|
||||
typedef unsigned int reg_t;
|
||||
|
||||
#define FUNC_STACKTRACE(statement) \
|
||||
{ \
|
||||
reg_t bp, pc, hbp; \
|
||||
extern reg_t get_bp(void); \
|
||||
\
|
||||
bp= get_bp(); \
|
||||
while(bp) \
|
||||
{ \
|
||||
pc= ((reg_t *)bp)[1]; \
|
||||
hbp= ((reg_t *)bp)[0]; \
|
||||
statement; \
|
||||
if (hbp != 0 && hbp <= bp) \
|
||||
{ \
|
||||
pc = -1; \
|
||||
statement; \
|
||||
break; \
|
||||
} \
|
||||
bp= hbp; \
|
||||
} \
|
||||
}
|
||||
|
||||
void util_nstrcat(char *str, unsigned long number)
|
||||
{
|
||||
int n = 10, lead = 1;
|
||||
char nbuf[12], *p;
|
||||
p = nbuf;
|
||||
*p++ = '0';
|
||||
*p++ = 'x';
|
||||
for(n = 0; n < 8; n++) {
|
||||
int i;
|
||||
i = (number >> ((7-n)*4)) & 0xF;
|
||||
if(!lead || i) {
|
||||
*p++ = i < 10 ? '0' + i : 'a' + i - 10;
|
||||
lead = 0;
|
||||
}
|
||||
}
|
||||
if(lead) *p++ = '0';
|
||||
*p++ = ' ';
|
||||
*p++ = '\0';
|
||||
strcat(str, nbuf);
|
||||
}
|
||||
|
||||
void util_stacktrace(void)
|
||||
{
|
||||
FUNC_STACKTRACE(printf("0x%lx ", (unsigned long) pc));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void util_stacktrace_strcat(char *str)
|
||||
{
|
||||
FUNC_STACKTRACE(util_nstrcat(str, pc));
|
||||
}
|
||||
|
||||
41
lib/sysutil/sys_hz.c
Normal file
41
lib/sysutil/sys_hz.c
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/types.h>
|
||||
#include <minix/u64.h>
|
||||
#include <minix/config.h>
|
||||
#include <minix/const.h>
|
||||
|
||||
#include "sysutil.h"
|
||||
|
||||
static u32_t Hz;
|
||||
|
||||
u32_t
|
||||
sys_hz(void)
|
||||
{
|
||||
if(Hz <= 0) {
|
||||
int r;
|
||||
/* Get HZ. */
|
||||
if((r=sys_getinfo(GET_HZ, &Hz, sizeof(Hz), 0, 0)) != OK) {
|
||||
Hz = HZ;
|
||||
printf("sys_hz: %d: reverting to HZ = %d\n", r, Hz);
|
||||
}
|
||||
}
|
||||
|
||||
return Hz;
|
||||
}
|
||||
|
||||
u32_t
|
||||
micros_to_ticks(u32_t micros)
|
||||
{
|
||||
u32_t ticks;
|
||||
|
||||
ticks = div64u(mul64u(micros, sys_hz()), 1000000);
|
||||
if(ticks < 1) ticks = 1;
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user