/* * ppm.h - Per-cluster Physical Pages Manager Interface * * Authors Ghassan Almaless (2008,2009,2010,2011,2012) * Alain Greiner (2016) * * Copyright (c) UPMC Sorbonne Universites * * This file is part of ALMOS-MKH. * * ALMOS-kernel is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-kernel is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-kernel; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PPM_H_ #define _PPM_H_ #include #include #include #include #include #define PPM_SIGNATURE 0xBABEF00D /***************************************************************************************** * 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: an allocated block is * is an integer number n of 4 Kbytes pages, and n (called order) is a power of 2. ****************************************************************************************/ typedef struct ppm_s { 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; /***************************************************************************************** * This function initializes a PPM (Physical Pages Manager) in a cluster. * The physical memory base address in all clusters 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 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 recommended way to get * physical pages is to call the generic allocator defined in kmem.h. ***************************************************************************************** * @ 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 is the low-level physical pages release function. * 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. ***************************************************************************************** * @ page : pointer to the page descriptor to be released ****************************************************************************************/ void ppm_free_pages( page_t * page ); /***************************************************************************************** * This function check if a page descriptor is valid. ***************************************************************************************** * @ page : pointer on a page descriptor * @ returns true if valid / false otherwise. ****************************************************************************************/ inline bool_t ppm_page_is_valid( page_t * page ); /***************************************************************************************** * Get the page base address from the page descriptor pointer. ***************************************************************************************** * @ page : pointer to page descriptor * @ returns page base address ****************************************************************************************/ inline void* ppm_page2base( page_t * page ); /***************************************************************************************** * Get the page descriptor pointer from the page base address. ***************************************************************************************** * @ vaddr : page base address * @ returns pointer on page descriptor ****************************************************************************************/ inline page_t * ppm_base2page( void * vaddr ); /***************************************************************************************** * Get the PPN from the page descriptor pointer. ***************************************************************************************** * @ page : pointer to page descriptor * @ returns physical page number ****************************************************************************************/ inline ppn_t ppm_page2ppn( page_t * page ); /***************************************************************************************** * Get the page descriptor pointer from the PPN. ***************************************************************************************** * @ ppn : physical page number * @ returns pointer on page descriptor ****************************************************************************************/ inline page_t * ppm_ppn2page( ppn_t ppn ); /***************************************************************************************** * Get the page base address from the PPN. ***************************************************************************************** * @ ppn : physical page number * @ returns page base address ****************************************************************************************/ inline void* ppm_ppn2base( ppn_t ppn ); /***************************************************************************************** * Get the PPN from the page base address. ***************************************************************************************** * @ vaddr : page base address * @ returns physical page number ****************************************************************************************/ inline ppn_t ppm_base2ppn( void * base ); /***************************************************************************************** * This function prints the PPM allocator status. ***************************************************************************************** * @ ppm : pointer on PPM allocator. * @ string : define context of display. ****************************************************************************************/ void ppm_print( ppm_t * ppm, char * string ); /***************************************************************************************** * This function checks PPM allocator consistency. ***************************************************************************************** * @ ppm : pointer on PPM allocator. ****************************************************************************************/ void ppm_assert_order( ppm_t * ppm ); #endif /* _PPM_H_ */