Basic VM and other minor improvements.

Not complete, probably not fully debugged or optimized.
This commit is contained in:
Ben Gras
2008-11-19 12:26:10 +00:00
parent c888305e21
commit c078ec0331
273 changed files with 10814 additions and 4305 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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
View 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
View 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
View 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
View 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
View 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;
}