Index: trunk/kernel/mm/ppm.h
===================================================================
--- trunk/kernel/mm/ppm.h	(revision 690)
+++ trunk/kernel/mm/ppm.h	(revision 1)
@@ -1,7 +1,7 @@
 /*
- * ppm.h - Per-cluster Physical Pages Manager definition.
- *
+ * ppm.h - Per-cluster Physical Pages Manager Interface
+ * 
  * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
- *          Alain Greiner    (2016,2017,2018,2019,2020)
+ *          Alain Greiner    (2016)
  *
  * Copyright (c) UPMC Sorbonne Universites
@@ -26,244 +26,137 @@
 #define _PPM_H_
 
-#include <hal_kernel_types.h>
+#include <hal_types.h>
 #include <list.h>
-#include <busylock.h>
-#include <remote_queuelock.h>
+#include <spinlock.h>
 #include <boot_info.h>
 #include <page.h>
 
+#define  PPM_SIGNATURE     0xBABEF00D
 
 /*****************************************************************************************
- * This structure defines the Physical Pages Manager in a cluster.
- * In each cluster, the physical memory bank starts at local physical address 0 and
- * contains an integer number of small pages, defined by the <pages_nr> field in the
- * boot_info structure. It is split in three parts:
- *
- * - the "kernel_code" section contains the kernel code, loaded by the boot-loader.
- *   It starts at local PPN = 0 and the size is defined by the <pages_offset> field
- *   in the boot_info structure.
- * - the local "pages_tbl" section contains the physical page descriptors array.
- *   It starts at local PPN = pages_offset, and it contains one entry per small page.
- *   It is created and initialized by the hal_ppm_create() function. 
- * - The "kernel_heap" section contains all physical pages that are are not in the
- *   "kernel_code" and "pages_tbl" sections, and that have not been reserved.
- *   The reserved pages are defined in the boot_info structure.
- *
- * The main service provided by the PMM is the dynamic allocation of physical pages
- * from the "kernel_heap" section. This low-level allocator implements the "buddy" 
- * algorithm: an allocated block is an integer number n of small pages, where n 
- * is a power of 2, and ln(n) is called order. The free_pages_root[] array contains
- * the roots ot the local lists of free pages for different sizes, as required by
- * the "buddy" algorithm. 
- * The local threads can access these free_lists by calling the ppm_alloc_pages() and
- * ppm_free_page() functions, and the remote threads can access the same free lists,
- * by calling the ppm_remote_alloc_pages() and ppm_remote_free_pages functions.
- * Therefore, these free lists are protected by a remote_busy_lock.
- * 
- * Another service is to register the dirty pages in a specific local dirty_list,
- * also rooted in the PPM, in order to be able to synchronize all dirty pages on disk.
- * This dirty list is protected by a specific remote_queuelock, because it can be
- * modified by a remote thread.
+ * This structure defines the list of blocks of a given size for the "buddy"
+ * allocation algorithm implemented by the ppm_t manager.
  ****************************************************************************************/
+typedef struct buddy_list_s
+{
+	list_entry_t  root;       // root of the list 
+	uint32_t      pages_nr;   // number of blocks
+}
+buddy_list_t;
 
+/*****************************************************************************************
+ * This structure defines the Physical Memory Manager in a cluster.
+ * In all clusters, the physical memory bank starts at address 0.
+ * The segments kcode and kdata are mapped in the first "offset" pages.
+ * The physical page descriptors array is implemented just after this offset zone.
+ * The main service provided by the PMM is the dynamic allocation of physical pages. 
+ * This low-level allocator implements the buddy algorithm.
+ ****************************************************************************************/
 typedef struct ppm_s
 {
-	remote_busylock_t   free_lock;          /*! lock protecting free_pages[] lists      */
-	list_entry_t        free_pages_root[CONFIG_PPM_MAX_ORDER];  /*! roots of free lists */
-	uint32_t            free_pages_nr[CONFIG_PPM_MAX_ORDER];    /*! free pages number   */
-	page_t            * pages_tbl;          /*! pointer on page descriptors array       */
-	uint32_t            pages_nr;           /*! total number of small physical page     */
-    remote_queuelock_t  dirty_lock;         /*! lock protecting dirty pages list        */
-    list_entry_t        dirty_root;         /*! root of dirty pages list                */
-    void              * vaddr_base;         /*! pointer on local physical memory base   */
+	uint32_t       signature;               /*! set when initialised                    */
+	spinlock_t     free_lock;               /*! lock protecting free_pages[] array      */
+	list_entry_t   free_pages_root[CONFIG_PPM_MAX_ORDER];  /*! roots of free lists      */
+	uint32_t       free_pages_nr[CONFIG_PPM_MAX_ORDER];    /*! numbers of free pages    */
+    uint32_t       total_free_pages;        /*! total number of free pages              */
+	page_t       * pages_tbl;               /*! pointer on page descriptors array       */
+	uint32_t       pages_nr;                /*! total number of 4 Kbytes physical page  */
+    uint32_t       pages_offset;            /*! allocated pages for kcode & kdata       */
+    uint32_t       pages_desc;              /*! allocated pages for pages_tbl[] array   */
+    spinlock_t     dirty_lock;              /*! lock protecting the dirty list          */
+    list_entry_t   dirty_root;              /*! root of dirty pages list                */
 }
 ppm_t;
 
-/************** functions to allocate / release physical pages  *************************/
+/*****************************************************************************************
+ * This function initializes a PPM (Physical Pages Manager) in a cluster.
+ * The physical memory base address in all cluster is zero.
+ * The physical memory size is NOT constrained to be smaller than 4 Gbytes. 
+ * @ ppm          : pointer on physical pages manager.
+ * @ pages_nr     : total physical memory size (number of 4 Kbytes pages).
+ * @ pages_offset : number of pages already allocated in this physical memory.
+ ****************************************************************************************/
+void ppm_init( ppm_t    * ppm, 
+               uint32_t   pages_nr,
+	           uint32_t   pages_offset );
 
 /*****************************************************************************************
- * This local allocator must be called by a thread running in local cluster. 
- * It allocates N contiguous physical 4 Kbytes pages from the local cluster, where 
- * N is a power of 2 defined by the <order> argument. 
- * In normal use, it should not be called directly, as the recommended way to allocate
+ * This is the low-level physical pages allocation function.
+ * It allocates N contiguous physical pages. N is a power of 2.
+ * In normal use, you don't need to call it directly, as the recommanded way to get 
  * physical pages is to call the generic allocator defined in kmem.h.
- *****************************************************************************************
- * @ order     : ln2( number of 4 Kbytes pages)
- * @ returns a local pointer on the page descriptor if success / NULL if error.
+ * @ order        : ln2( number of 4 Kbytes pages)
+ * @ returns a pointer on the page descriptor if success / NULL otherwise
  ****************************************************************************************/
 page_t * ppm_alloc_pages( uint32_t order );
 
 /*****************************************************************************************
- * This function must be called by a thread running in local cluster to release
- * physical pages. It takes the lock protecting the free_lists before register the 
- * released page in the relevant free_list.
- * In normal use, it should not be called directly, as the recommended way to free
+ * This is the low-level physical pages release function.
+ * In normal use, you do not need to call it directly, as the recommanded way to free 
  * physical pages is to call the generic allocator defined in kmem.h.
- *****************************************************************************************
- * @ page   : local pointer on the page descriptor to be released
+ * @ page         : pointer to the page descriptor to be released
  ****************************************************************************************/
 void ppm_free_pages( page_t * page );
 
 /*****************************************************************************************
- * This function does the same as the ppm_free_page() function, without taking the lock.
- * It is used by the hal_ppm_init() function to initialize the pages_tbl[] array, when
- * there is no concurrent access issue.
- *****************************************************************************************
- * @ page   : local pointer on the page descriptor to be released
+ * This function check if a page descriptor is valid.
+ * @ page         : pointer on a page descriptor
+ * @ returns true if valid / false otherwise.
  ****************************************************************************************/
-void ppm_free_pages_nolock( page_t * page );
+inline bool_t ppm_page_is_valid( page_t * page );
 
 /*****************************************************************************************
- * This remote  allocator can be called by any thread running in any cluster. 
- * It allocates N contiguous physical 4 Kbytes pages from cluster identified 
- * by the <cxy> argument, where N is a power of 2 defined by the <order> argument. 
- * In normal use, it should not be called directly, as the recommended way to allocate
- * physical pages is to call the generic allocator defined in kmem.h.
- *****************************************************************************************
- * @ cxy       : remote cluster identifier.
- * @ order     : ln2( number of 4 Kbytes pages)
- * @ returns an extended pointer on page descriptor if success / XPTR_NULL if error.
+ * Get the page base address from the page descriptor pointer.
+ * @ page         : pointer to page descriptor
+ * @ returns page base address
  ****************************************************************************************/
-xptr_t  ppm_remote_alloc_pages( cxy_t    cxy,
-                                uint32_t order );
+inline void* ppm_page2base( page_t * page );
 
 /*****************************************************************************************
- * This function can be called by any thread running in any cluster to release physical
- * pages to a remote cluster. It takes the lock protecting the free_list before register
- * the released page in the relevant free_list.
- * In normal use, you do not need to call it directly, as the recommended way to free
- * physical pages is to call the generic allocator defined in kmem.h.
- *****************************************************************************************
- * @ cxy       : remote cluster identifier.
- * @ page      : local pointer on the page descriptor to be released in remote cluster.
+ * Get the page descriptor pointer from the page base address.
+ * @ vaddr        : page base address
+ * @ returns pointer on page descriptor
  ****************************************************************************************/
-void ppm_remote_free_pages( cxy_t    cxy,
-                            page_t * page );
+inline page_t * ppm_base2page( void * vaddr );
 
 /*****************************************************************************************
- * This debug function can be called by any thread running in any cluster to display
- * the current PPM state of a remote cluster.
- *****************************************************************************************
- * @ cxy       : remote cluster identifier.
+ * Get the PPN from the page descriptor pointer.
+ * @ page         : pointer to page descriptor
+ * @ returns physical page number
  ****************************************************************************************/
-void ppm_remote_display( cxy_t cxy );
-
-
-/************** functions to translate [ page <->  base <-> ppn ] ***********************/
+inline ppn_t ppm_page2ppn( page_t * page );
 
 /*****************************************************************************************
- * Get extended pointer on page base from extended pointer on page descriptor.
- *****************************************************************************************
- * @ page_xp    : extended pointer to page descriptor
- * @ returns extended pointer on page base.
+ * Get the page descriptor pointer from the PPN.
+ * @ ppn          : physical page number
+ * @ returns pointer on page descriptor
  ****************************************************************************************/
-inline xptr_t ppm_page2base( xptr_t page_xp );
+inline page_t * ppm_ppn2page( ppn_t ppn );
 
 /*****************************************************************************************
- * Get extended pointer on page descriptor from extended pointer on page base.
- *****************************************************************************************
- * @ base_xp   : extended pointer to page base.
- * @ returns extended pointer on page descriptor
+ * Get the page base address from the PPN.
+ * @ ppn          : physical page number
+ * @ returns page base address
  ****************************************************************************************/
-inline xptr_t ppm_base2page( xptr_t base_xp );
+inline void* ppm_ppn2base( ppn_t ppn );
 
 /*****************************************************************************************
- * Get extended pointer on page base from global PPN.
- *****************************************************************************************
- * @ ppn    : global physical page number.
- * @ returns extended pointer on page base.
+ * Get the PPN from the page base address.
+ * @ vaddr        : page base address
+ * @ returns physical page number
  ****************************************************************************************/
-inline xptr_t ppm_ppn2base( ppn_t ppn );
+inline ppn_t ppm_base2ppn( void * base );
 
 /*****************************************************************************************
- * Get global PPN from extended pointer on page base.
- *****************************************************************************************
- * @ base_xp   : extended pointer to page base.
- * @ returns global physical page number.
+ * This function prints the PPM allocator status.
+ * @ ppm      : pointer on PPM allocator.
  ****************************************************************************************/
-inline ppn_t ppm_base2ppn( xptr_t base_xp );
+void ppm_print( ppm_t * ppm );
 
 /*****************************************************************************************
- * Get global PPN from extended pointer on page descriptor.
- *****************************************************************************************
- * @ page_xp   : pointer to page descriptor
- * @ returns global physical page number.
+ * This function checks PPM allocator consistency.
+ * @ ppm      : pointer on PPM allocator.
  ****************************************************************************************/
-inline ppn_t ppm_page2ppn( xptr_t page_xp );
-
-/*****************************************************************************************
- * Get extended pointer on page descriptor from global PPN.
- *****************************************************************************************
- * @ ppn       : global physical page number
- * @ returns extended pointer on page descriptor.
- ****************************************************************************************/
-inline xptr_t ppm_ppn2page( ppn_t ppn );
-
-
-/*********** debug  functions  **********************************************************/
-
-/*****************************************************************************************
- * This function can be called by any thread running in any cluster.
- * It displays the PPM allocator status in cluster identified by the <cxy> argument.
- *****************************************************************************************
- * @ cxy   : remote cluster
- ****************************************************************************************/
-void ppm_remote_display( cxy_t cxy );
-
-/*****************************************************************************************
- * This function must be called by a thread running in local cluster.
- * It checks the consistency of the local PPM allocator.
- *****************************************************************************************
- * @ return 0 if PPM is OK / return -1 if PPM not consistent.
- ****************************************************************************************/
-error_t ppm_assert_order( void );
-
-
-/*********** functions to handle dirty pages  *******************************************/
-
-/*****************************************************************************************
- * This function registers a page identified by the <page_xp> argument as dirty. 
- * It can be called by a thread running in any cluster.
- * - it takes the queuelock protecting the PPM dirty_list.
- * - it takes the busylock protecting the page flags.
- * - it test the PG_DIRTY flag in the page descriptor.
- *   . if page already dirty => do nothing
- *   . it page not dirty => set the PG_DIRTY flag and register page in PPM dirty list.
- * - it releases the busylock protecting the page flags.
- * - it releases the queuelock protecting the PPM dirty_list.
- *****************************************************************************************
- * @ page_xp  : extended pointer on page descriptor.
- * @ returns true if page was not dirty / returns false if page was dirty
- ****************************************************************************************/
-bool_t ppm_page_do_dirty( xptr_t page_xp );
-
-/*****************************************************************************************
- * This function unregisters a page identified by the <page_xp> argument as dirty. 
- * It can be called by a thread running in any cluster.
- * - it takes the queuelock protecting the PPM dirty_list.
- * - it takes the busylock protecting the page flags.
- * - it test the PG_DIRTY flag in the page descriptor.
- *   . if page not dirty => do nothing
- *   . it page dirty => reset the PG_DIRTY flag and remove page from PPM dirty list.
- * - it releases the busylock protecting the page flags.
- * - it releases the queuelock protecting the PPM dirty_list.
- *****************************************************************************************
- * @ page_xp  : extended pointer on page descriptor.
- * @ returns true if page was dirty / returns false if page was not dirty
- ****************************************************************************************/
-bool_t ppm_page_undo_dirty( xptr_t page_xp );
-
-/*****************************************************************************************
- * This function synchronizes (i.e. update the IOC device) all dirty pages in a cluster.
- * - it takes the queuelock protecting the PPM dirty_list.
- * - it scans the PPM dirty list, and for each page:
- *   . it takes the lock protecting the page.
- *   . it removes the page from the PPM dirty_list.
- *   . it reset the PG_DIRTY flag.
- *   . it releases the lock protecting the page.
- * - it releases the queuelock protecting the PPM dirty_list.
- $ The PPM dirty_list is empty when the sync operation completes.
- ****************************************************************************************/
-void ppm_sync_dirty_pages( void );
+void ppm_assert_order( ppm_t * ppm );
 
 #endif	/* _PPM_H_ */
