Index: trunk/kernel/mm/vmm.h
===================================================================
--- trunk/kernel/mm/vmm.h	(revision 406)
+++ trunk/kernel/mm/vmm.h	(revision 407)
@@ -40,9 +40,9 @@
 
 /*********************************************************************************************
- * This structure defines the STACK allocator used by the VMM to dynamically allocate
- * STACK vsegs requested or released by the user process.
- * This allocator handles a fixed size array of fixed size slots stores in the STACK zone.
+ * This structure defines the STACK allocator used by the VMM to dynamically handle
+ * a STACK vseg requested or released by an user process.
+ * This allocator handles a fixed size array of fixed size slots in the STACK zone.
  * The stack size and the number of slots are defined by the CONFIG_VMM_STACK_SIZE, and
- * CONFIG_THREAD
+ * CONFIG_VMM_STACK_BASE parameters.
  * Each slot can contain one user stack vseg. The first page in the slot is not allocated
  * to detect stack overflow.
@@ -50,5 +50,4 @@
  * All allocation / release operations are registered in the stack_bitmap, that completely
  * define the STACK zone state.
- * In this implementation, the max number of slots is 32.
  ********************************************************************************************/
 
@@ -62,5 +61,5 @@
 
 /*********************************************************************************************
- * This structure defines the MMAP allocator used by the VMM to dynamically allocate
+ * This structure defines the MMAP allocator used by the VMM to dynamically handle  
  * MMAP vsegs requested or released by an user process.
  * This allocator should be only used in the reference cluster.
@@ -92,5 +91,5 @@
  * This local VMM provides three main services:
  * 1) It registers all vsegs statically or dynamically defined in the vseg list.
- * 2) It allocates virtual memory space for the STACKS and MMAP vsegs.
+ * 2) It allocates virtual memory space for the STACKS and MMAP vsegs (FILE/ANON/REMOTE).
  * 3) It contains the local copy of the generic page table descriptor.
  ********************************************************************************************/
@@ -98,5 +97,5 @@
 typedef struct vmm_s
 {
-	rwlock_t       vsegs_lock;         /*! lock protecting the vsegs list & radix tree      */
+	rwlock_t       vsegs_lock;         /*! lock protecting the vsegs list                   */
 	list_entry_t   vsegs_root;         /*! all vsegs in same process and same cluster       */
 	uint32_t       vsegs_nr;           /*! total number of local vsegs                      */
@@ -107,5 +106,5 @@
     mmap_mgr_t     mmap_mgr;           /*! embedded MMAP vsegs allocator                    */
 
-	uint32_t       pgfault_nr;         /*! page fault counter                               */
+	uint32_t       pgfault_nr;         /*! page fault counter (instrumentation)             */
 	uint32_t       u_err_nr;           /*! TODO ??? [AG]                                    */
 	uint32_t       m_err_nr;           /*! TODO ??? [AG]                                    */
@@ -119,33 +118,16 @@
 
 	intptr_t       entry_point;        /*! main thread entry point                          */
-
-    vseg_t       * heap_vseg;          /*! pointer on local heap vseg descriptor            */
 }
 vmm_t;
 
 /*********************************************************************************************
- * This structure is used to store the arguments of the mmap() system call.
- ********************************************************************************************/
-
-typedef struct mmap_attr_s
-{
-	void     * addr;            /*! requested virtual address (unused : should be NULL)     */
-	uint32_t   length;          /*! requested vseg size (bytes)                             */
-	uint32_t   prot;            /*! access modes                                            */
-	uint32_t   flags;           /*! only MAP_FILE / MAP_ANON / MAP_PRIVATE / MAP_SHARED     */
-	fdid_t     fdid;            /*! file descriptor index (if MAP_FILE is set)              */
-	int32_t    offset;          /*! file offset (if MAP_FILE is set)                        */
-}
-mmap_attr_t;
-
-/*********************************************************************************************
  * This function initialises the virtual memory manager attached to an user process.
- * - It registers the "kentry", "args", "envs" and "heap" vsegs in the vsegs list.
- *   The "code" and "data" vsegs are registered by the elf_load_process() function,
- *   the "stack" vsegs are registered by the thread_user_create() function, and the
- *   "mmap" vsegs are dynamically created by syscalls.
+ * - It initializes the STACK and MMAP allocators.
+ * - It registers the "kentry", "args", "envs" vsegs in the VSL.
+ * - The "code" and "data" vsegs are registered by the elf_load_process() function.
+ * - The "stack" vsegs are dynamically created by the thread_user_create() function.
+ * - The "file", "anon", "remote" vsegs are dynamically created by the mmap() syscalls.
  * - It initializes the generic page table, calling the HAL specific hal_gpt_init() function.
- *   For TSAR it map all pages for the "kentry" vseg, that must be identity mapping.
- * - It initializes the STAK and MMAP allocators.
+ * - For TSAR it map all pages for the "kentry" vseg, that must be identity mapping.
  * TODO : Any error in this function gives a kernel panic => improve error handling.
  *********************************************************************************************
@@ -155,5 +137,20 @@
 
 /*********************************************************************************************
- * This function copies the content of a source VMM to a destination VMM.
+ * This function displays on TXY0 the list or registered vsegs for a given <process>.
+ * If the <mapping> argument is true, it displays for each vesg all mapped PTEs in GPT.
+ *********************************************************************************************
+ * @ process   : pointer on process descriptor.
+ * @ mapping   : detailed mapping if true.
+ ********************************************************************************************/
+void vmm_display( struct process_s * process,
+                  bool_t             mapping );
+
+/*********************************************************************************************
+ * This function is called by the sys_fork() system call.
+ * It copies the content of a parent process descriptor VMM to a child process VMM.
+ * - All vsegs registered in the source VSL are copied in the destination VSL. 
+ * - All PTEs registered in the source GPT are copied in destination GPT. For all writable
+ *   PTEs - but the FILE vsegs - the WRITABLE flag is reset and the COW flag is set in
+ *   the destination GPT. 
  *********************************************************************************************
  * @ dst_process   : pointer on destination process descriptor.
@@ -187,20 +184,31 @@
 /*********************************************************************************************
  * This function allocates memory for a vseg descriptor, initialises it, and register it
- * in the VMM of the process. It checks the collision with pre-existing vsegs in VMM.
- * For STACK and MMAP types vseg, it does not use the base argument, but uses the VMM STACK
- * and MMAP specific allocators to get a base address in virtual space.
- * To comply with the "on-demand" paging policy, this function does NOT modify the
- * page table, and does not allocate physical memory for vseg data.
- *********************************************************************************************
- * @ vmm   : pointer on process descriptor.
- * @ base      : vseg base address
- * @ size      : vseg size (bytes)
- * @ type      : vseg type
- * @ returns pointer on vseg if success / returns NULL if no memory or conflict.
+ * in the VMM of the local process descriptor, that should be the reference process.
+ * For the 'stack", "file", "anon", & "remote" types, it does not use the <base> argument,
+ * but uses the STACK and MMAP virtual memory allocators.
+ * It checks collision with all pre-existing vsegs.
+ * To comply with the "on-demand" paging policy, this function does NOT modify the page table,
+ * and does not allocate physical memory for vseg data.
+ * It should be called by a local thread (could be a RPC thread if the client thread is not
+ * running in the regerence cluster).
+ *********************************************************************************************
+ * @ process     : pointer on local processor descriptor.
+ * @ type        : vseg type.
+ * @ base        : vseg base address (not used for dynamically allocated vsegs).
+ * @ size        : vseg size (bytes).
+ * @ file_offset : offset in file for CODE, DATA, FILE types. 
+ * @ file_size   : can be smaller than "size" for DATA type.
+ * @ mapper_xp   : extended pointer on mapper for CODE, DATA, FILE types.
+ * @ cxy         : physical mapping cluster (for non distributed vsegs).
+ * @ returns pointer on vseg if success / returns NULL if no memory, or conflict.
  ********************************************************************************************/
 vseg_t * vmm_create_vseg( struct process_s * process,
+                          vseg_type_t        type,
                           intptr_t           base,
-	                      intptr_t           size,
-	                      uint32_t           type );
+	                      uint32_t           size,
+                          uint32_t           file_offset,
+                          uint32_t           file_size,
+                          xptr_t             mapper_xp,
+                          cxy_t              cxy );
 
 /*********************************************************************************************
@@ -245,5 +253,5 @@
 /*********************************************************************************************
  * This function removes a given region (defined by a base address and a size) from
- * the VMM of a given process descriptor. This can modify several vsegs:
+ * the VMM of a given process descriptor. This can modify the number of vsegs:
  * (a) if the region is not entirely mapped in an existing vseg, it's an error.
  * (b) if the region has same base and size as an existing vseg, the vseg is removed.
@@ -251,4 +259,6 @@
  * (d) if the removed region cut the vseg in three parts, it is modified, and a new
  *     vseg is created with same type.
+ * FIXME [AG] this function must be called by a thread running in the reference cluster,
+ * and the VMM must be updated in all process descriptors copies. 
  *********************************************************************************************
  * @ process   : pointer on process descriptor
@@ -279,10 +289,10 @@
 
 /*********************************************************************************************
- * This function is called by the generic exception handler when a page fault 
+ * This function is called by the generic exception handler when a page-fault event
  * has been detected in a given cluster. 
+ * - If the local cluster is the reference, it call directly the vmm_get_pte() function.
  * - If the local cluster is not the reference cluster, it send a RPC_VMM_GET_PTE
- *   to the reference cluster to get the missing PTE attributes and PPN, and update
- *   the local page table. 
- * - If the local cluster is the reference, it call directly the vmm_get_pte() function.
+ *   to the reference cluster to get the missing PTE attributes and PPN,
+ *   and update the local page table. 
  *********************************************************************************************
  * @ process   : pointer on process descriptor.
@@ -294,15 +304,35 @@
 
 /*********************************************************************************************
- * This function returns in the "attr" and "ppn" arguments the PTE associated to a given
- * VPN for a given process. This function must be called by a thread running in the 
- * reference cluster. To get the PTE from another cluster, use the RPC_VMM_GET_PTE.
- * The vseg containing the searched VPN should be registered in the reference VMM.
- * If the PTE in the reference page table is unmapped, this function allocates the missing
- * physical page from the target cluster defined by the vseg type, initialize it,
- * and update the reference page table. It calls the RPC_PMEM_GET_PAGES to get and 
- * initialize the missing physical page, if the target cluster is not the reference cluster.
+ * This function is called by the generic exception handler when a copy-on-write event
+ * has been detected in a given cluster. 
+ * - If the local cluster is the reference, it call directly the vmm_get_pte() function.
+ * - If the local cluster is not the reference cluster, it send a RPC_VMM_GET_PTE
+ *   to the reference cluster to get the missing PTE attributes and PPN,
+ *   and update the local page table. 
+ *********************************************************************************************
+ * @ process   : pointer on process descriptor.
+ * @ vpn       : VPN of the missing PTE.
+ * @ returns 0 if success / returns ENOMEM if no memory.
+ ********************************************************************************************/
+error_t vmm_copy_on_write( struct process_s * process,
+                           vpn_t              vpn );
+
+/*********************************************************************************************
+ * This function is called when a new PTE (GPT entry) is required because a "page-fault",
+ * or "copy-on_write" event has been detected for a given <vpn> in a given <process>. 
+ * The <cow> argument defines the type of event to be handled. 
+ * This function must be called by a thread running in reference cluster, and the vseg
+ * containing the searched VPN should be registered in the reference VMM.
+ * - for an actual page-fault, it allocates the missing physical page from the target cluster
+ *   defined by the vseg type, initialize it, and update the reference page table. 
+ * - for a copy-on-write, it allocates a new physical page from the target cluster,
+ *   initialise it from the old physical page, and update the reference page table. 
+ * In both cases, it calls the RPC_PMEM_GET_PAGES to get the new physical page if the
+ * target cluster is not the reference cluster.
+ * It returns in the <attr> and <ppn> arguments the accessed or modified PTE.
  *********************************************************************************************
  * @ process   : [in] pointer on process descriptor.
  * @ vpn       : [in] VPN defining the missing PTE.
+ * @ cow       : [in] "copy_on_write" if true / "page_fault" if false.
  * @ attr      : [out] PTE attributes.
  * @ ppn       : [out] PTE ppn.
@@ -311,4 +341,5 @@
 error_t vmm_get_pte( struct process_s * process,
                      vpn_t              vpn,
+                     bool_t             cow,
                      uint32_t         * attr,
                      ppn_t            * ppn );
