Index: trunk/kernel/syscalls/sys_mmap.c
===================================================================
--- trunk/kernel/syscalls/sys_mmap.c	(revision 23)
+++ trunk/kernel/syscalls/sys_mmap.c	(revision 407)
@@ -24,130 +24,215 @@
 
 #include <hal_types.h>
+#include <hal_uspace.h>
+#include <shared_syscalls.h>
 #include <errno.h>
 #include <thread.h>
 #include <printk.h>
+#include <mapper.h>
 #include <vfs.h>
 #include <process.h>
 #include <vmm.h>
 
-///////////////////////////////////
+//////////////////////////////////
 int sys_mmap( mmap_attr_t * attr )
 {
-    printk("\n[WARNING] function %s not implemented\n", __FUNCTION__ );
-    return 0;
-/*    
-	error_t err;
-	uint_t count;
-	struct thread_s *this;
-	struct process_s *process;
-	struct vfs_file_s *file;
-	mmap_attr_t attr;
-	size_t isize;
-	int retval;
+    vseg_t      * vseg;
+    cxy_t         vseg_cxy;
+    vseg_type_t   vseg_type;
+    mmap_attr_t   k_attr;       // attributes copy in kernel space
+    xptr_t        mapper_xp;
+    error_t       error;
+    paddr_t       paddr;        // unused, but required for user space checking
+
+	uint64_t      tm_start;
+	uint64_t      tm_end;
+
+	tm_start = hal_get_cycles();
+
+	thread_t    * this    = CURRENT_THREAD;
+	process_t   * process = this->process;
+
+    // check arguments in user space
+    error = vmm_v2p_translate( false , attr , &paddr );
+
+    if ( error )
+    {
+        printk("\n[ERROR] in %s : arguments not in used space = %x\n",
+        __FUNCTION__ , (intptr_t)attr );
+		this->errno = EINVAL;
+		return -1;
+    }
+
+    // copy arguments from uspace
+    hal_copy_from_uspace( &k_attr , attr , sizeof(mmap_attr_t) );
+
+    // get fdid, offset, and length arguments
+    uint32_t fdid   = k_attr.fdid;
+    uint32_t offset = k_attr.offset;
+    uint32_t length = k_attr.length;
+
+    // get flags
+    bool_t     map_fixed   = ( (k_attr.flags & MAP_FIXED)   != 0 );
+    bool_t     map_anon    = ( (k_attr.flags & MAP_ANON)    != 0 );
+    bool_t     map_remote  = ( (k_attr.flags & MAP_REMOTE)  != 0 );
+    bool_t     map_shared  = ( (k_attr.flags & MAP_SHARED)  != 0 );
+    bool_t     map_private = ( (k_attr.flags & MAP_PRIVATE) != 0 );
+
+    // MAP_FIXED not supported
+    if( map_fixed )
+    {
+        printk("\n[ERROR] in %s : MAP_FIXED not supported\n", __FUNCTION__ );
+        this->errno = EINVAL;
+        return -1;
+    }
+
+    if( map_shared == map_private )
+    {
+        printk("\n[ERROR] in %s : MAP_SHARED xor MAP_PRIVATE\n", __FUNCTION__ );
+        this->errno = EINVAL;
+        return -1;
+    }
+
+    // FIXME handle Copy_On_Write for MAP_PRIVATE...
+
+    // get access rigths
+    bool_t     prot_read   = ( (k_attr.prot & PROT_READ )   != 0 );
+    bool_t     prot_write  = ( (k_attr.prot & PROT_WRITE)   != 0 );
+
+    // test mmap type : can be FILE / ANON / REMOTE
+
+    if( (map_anon == false) && (map_remote == false) )   // FILE
+    {
+	    // FIXME: handle concurent delete of file by another thread closing it 
+
+		if( fdid >= CONFIG_PROCESS_FILE_MAX_NR ) 
+		{
+			printk("\n[ERROR] in %s: bad file descriptor = %d\n", __FUNCTION__ , fdid );
+            this->errno = EBADFD;
+            return -1;
+        }
+
+        // get extended pointer on file descriptor
+        xptr_t file_xp = process_fd_get_xptr( process , fdid );
+
+        if( file_xp == XPTR_NULL )
+        {
+			printk("\n[ERROR] in %s: file %d not found\n", __FUNCTION__ , fdid );
+            this->errno = EBADFD;
+            return -1;
+        }
+
+        // get file cluster and local pointer
+        cxy_t        file_cxy = GET_CXY( file_xp );
+        vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
+
+        // get inode pointer, mapper pointer and file attributes
+        vfs_inode_t * inode_ptr  = hal_remote_lpt(XPTR(file_cxy , &file_ptr->inode ));
+        uint32_t      file_attr  = hal_remote_lw (XPTR(file_cxy , &file_ptr->attr  ));
+        mapper_t    * mapper_ptr = hal_remote_lpt(XPTR(file_cxy , &file_ptr->mapper));
+
+        // get file size
+		uint32_t size = hal_remote_lw( XPTR( file_cxy , &inode_ptr->size ) );
+
+        // chek offset and length arguments
+		if( (offset + length) > size)
+		{
+			printk("\n[ERROR] in %s: offset (%d) + len (%d) >= file's size (%d)\n", 
+			__FUNCTION__, k_attr.offset, k_attr.length, size );
+            this->errno = ERANGE;
+            return -1;
+		}
+
+        // check access rights
+		if( (prot_read  && !(file_attr & FD_ATTR_READ_ENABLE)) ||
+		    (prot_write && !(file_attr & FD_ATTR_WRITE_ENABLE)) )
+		{
+			printk("\n[ERROR] in %s: prot = %x / file_attr = %x)\n", 
+			__FUNCTION__ , k_attr.prot , file_attr );
+			this->errno = EACCES;
+			return -1;
+		}
+
+		// increment file refcount
+		vfs_file_count_up( file_xp );
+
+        mapper_xp = XPTR( file_cxy , mapper_ptr );
+        vseg_type = VSEG_TYPE_FILE;
+        vseg_cxy  = file_cxy;
+    }
+    else                                                // ANON or REMOTE
+    {
+        // no mapper for ANON or REMOTE
+        mapper_xp = XPTR_NULL;
+
+        if( map_anon )
+        {
+            vseg_type = VSEG_TYPE_ANON;
+            vseg_cxy  = local_cxy;
+        }
+        else
+        {
+            vseg_type = VSEG_TYPE_REMOTE;
+            vseg_cxy  = k_attr.fdid;
  
-	this = current_thread;
-	process = this->process;
-	err  = EINVAL;
-	file = NULL;
-
-	if((err = cpu_copy_from_uspace(&attr, attr, sizeof(mmap_attr_t))))
-	{
-		printk(INFO, "%s: failed, copying from uspace @%x\n",
-		       __FUNCTION__, 
-		       attr);
-
-		this->info.errno = EFAULT;
-		return (int)VM_FAILED;
-	}
-
-	if((attr.flags  & VM_REG_HEAP)                     ||
-	   ((attr.flags & VM_REG_PVSH) == VM_REG_PVSH)     || 
-	   ((attr.flags & VM_REG_PVSH) == 0)               ||
-	   (attr.length == 0)                              ||
-	   (attr.offset & PMM_PAGE_MASK)                   || 
-	   ((attr.addr != NULL) && (((uint_t)attr.addr & PMM_PAGE_MASK)          ||
-				(NOT_IN_USPACE(attr.length + (uint_t)attr.addr)) ||
-				(NOT_IN_USPACE((uint_t)attr.addr)) )))
-	{
-		printk(INFO, "%s: failed, we don't like flags (%x), length (%d), or addr (%x)\n",
-		       __FUNCTION__, 
-		       attr.flags, 
-		       attr.length, 
-		       attr.addr);
-     
-		this->info.errno = EINVAL;
-		return (int)VM_FAILED;
-	}
-   
-	if(attr.flags & VM_REG_ANON)
-	{
-		attr.offset = 0;
-		attr.addr   = (attr.flags & VM_REG_FIXED) ? attr.addr : NULL;
-	}
-	else
-	{      
-		// FIXME: possible concurent delete of file from another bugy thread closing it 
-		if((attr.fd >= CONFIG_TASK_FILE_MAX_NR) || (process_fd_lookup(process, attr.fd, &file)))
-		{
-			printk(INFO, "%s: failed, bad file descriptor (%d)\n", 
-			       __FUNCTION__, 
-			       attr.fd);
-
-			this->info.errno = EBADFD;
-			return (int)VM_FAILED;
-		}
-     
-		//atomic_add(&file->f_count, 1);
-		vfs_file_up(file);//FIXME coalsce access to remote node info
-     
-		//FIXME: does we really to get the size...
-		isize = vfs_inode_size_get_remote(file->f_inode.ptr, file->f_inode.cid);
-		if((attr.offset + attr.length) > isize)
-		{
-			printk(INFO, "%s: failed, offset (%d) + len (%d) >= file's size (%d)\n", 
-			       __FUNCTION__, 
-			       attr.offset, 
-			       attr.length, 
-			       isize);
-
-			this->info.errno = ERANGE;
-			goto SYS_MMAP_FILE_ERR;
-		}
-
-		if(((attr.prot & VM_REG_RD) && !(VFS_IS(file->f_flags, VFS_O_RDONLY)))   ||
-		   ((attr.prot & VM_REG_WR) && !(VFS_IS(file->f_flags, VFS_O_WRONLY)))   ||
-		   ((attr.prot & VM_REG_WR) && (VFS_IS(file->f_flags, VFS_O_APPEND))))//    ||
-			//(!(attr.prot & VM_REG_RD) && (attr.flags & VM_REG_PRIVATE)))
-		{
-			printk(INFO, "%s: failed, EACCES prot (%x), f_flags (%x)\n", 
-			       __FUNCTION__, 
-			       attr.prot, 
-			       file->f_flags);
-
-			this->info.errno = EACCES;
-			goto SYS_MMAP_FILE_ERR;
-		}
-	}
-
-	retval = (int) vmm_mmap(process,
-				file,
-				attr.addr,
-				attr.length,
-				attr.prot,
-				attr.flags,
-				attr.offset);
-   
-	if((retval != (int)VM_FAILED) || (attr.flags & VM_REG_ANON))
-		return retval;
-
-SYS_MMAP_FILE_ERR:
-	printk(INFO, "%s: Failed, Droping file count \n", 
-	       __FUNCTION__);
-   
-	vfs_close( file , &count );
-
-	if(count == 1) process_fd_put( process , attr.fd );
-
-	return (int)VM_FAILED;
-*/
+            if( cluster_is_undefined( vseg_cxy ) )
+            {
+                printk("\n[ERROR] in %s : illegal cxy for MAP_REMOTE\n", __FUNCTION__ );
+                this->errno = EINVAL;
+                return -1;
+            }
+        }
+    }
+
+    // get reference process cluster and local pointer
+    xptr_t      ref_xp  = process->ref_xp;
+    cxy_t       ref_cxy = GET_CXY( ref_xp );
+    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
+
+    // create the vseg in reference cluster
+    if( local_cxy == ref_cxy )
+    {
+        vseg = vmm_create_vseg( process,
+                                vseg_type,
+                                0,               // base address unused for mmap()
+                                length,
+                                offset,
+                                0,               // file_size unused for mmap()
+                                mapper_xp,
+                                vseg_cxy );
+    }
+    else
+    {
+        rpc_vmm_create_vseg_client( ref_cxy,
+                                    ref_ptr,
+                                    vseg_type,
+                                    0,            // base address unused for mmap()
+                                    length,
+                                    offset,
+                                    0,            // file size unused for mmap()
+                                    mapper_xp,
+                                    vseg_cxy,
+                                    &vseg ); 
+    }
+    
+    if( vseg == NULL )
+    {
+        printk("\n[ERROR] in %s : cannot create vseg\n", __FUNCTION__ );
+        this->errno = ENOMEM;
+        return -1;
+    }
+
+    // copy vseg base address to user space
+    hal_copy_to_uspace( &attr->addr , &vseg->min , sizeof(intptr_t) );
+
+    tm_end = hal_get_cycles();
+
+syscall_dmsg("\n[DBG] %s : core[%x,%d] created vseg %s in cluster %x / cycle %d\n"
+"      base = %x / length = %x / cost = %d\n",
+__FUNCTION__, local_cxy , this->core->lid , vseg_type_str(vseg->type) ,
+vseg->cxy , (uint32_t)tm_start , vseg->min , length , (uint32_t)(tm_end - tm_start) );
+
+        return 0;
+
 }  // end sys_mmap()
+
