/* * hal_gpt.h - Generic Page Table API definition. * * Authors Alain Greiner (2016,2017,2018,2019) * * Copyright (c) UPMC Sorbonne Universites * * This file is part of ALMOS-MKH. * * ALMOS-MKH 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-MKH 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-MKH; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _GPT_H_ #define _GPT_H_ #include ///////////////////////////////////////////////////////////////////////////////////////// // Generic Page Table Definition (implementation in hal_gpt.c) // // It is specified as a simple (one dimensional) array indexed by the VPN (vpn_t type), // even if implementations can use a more sophisticated organisation (two-levels or more). // - The number of entries (number of pages in a virtual space) is architecture // dependent, and is defined as (CONFIG_USER_SPACE_SIZE / CONFIG_PPM_PAGE_SIZE). // - Each entry contains a Physical Page Number (ppn_t type), and a set of attributes, // defined as a 32 bits-vector. // // Any arch-specific implementation must implement this API. ///////////////////////////////////////////////////////////////////////////////////////// /**** Forward declarations ****/ struct page_s; struct process_s; /**************************************************************************************** * These macros define the masks for the Generic Page Table Entry attributes. ***************************************************************************************/ #define GPT_MAPPED 0x0001 /*! PTE is mapped */ #define GPT_SMALL 0x0002 /*! PTE is a small page */ #define GPT_READABLE 0x0004 /*! PTE is readable */ #define GPT_WRITABLE 0x0008 /*! PTE is writable */ #define GPT_EXECUTABLE 0x0010 /*! PTE is executable */ #define GPT_CACHABLE 0x0020 /*! PTE can be cached */ #define GPT_USER 0x0040 /*! PTE is user accessible */ #define GPT_DIRTY 0x0080 /*! PTE has been written */ #define GPT_ACCESSED 0x0100 /*! PTE has been "recently" accessed */ #define GPT_GLOBAL 0x0200 /*! PTE is kept in TLB at context switch */ #define GPT_COW 0x0400 /*! PTE must be copied on write */ #define GPT_SWAP 0x0800 /*! PTE swapped on disk (not implemented yet) */ #define GPT_LOCKED 0x1000 /*! PTE is currently accessed by a thread */ /**************************************************************************************** * This structure defines the Generic Page Table descriptor. ***************************************************************************************/ typedef struct gpt_s { void * ptr; /*! local pointer on GPT root */ uint32_t pte1_wait_events; /*! total number of pte1 wait events on this gpt */ uint32_t pte1_wait_iters; /*! total number of iterations in all pte1 wait */ uint32_t pte2_wait_events; /*! total number of pte2 wait events on this gpt */ uint32_t pte2_wait_iters; /*! total number of iterations in all pte2 wait */ } gpt_t; /**************************************************************************************** * This function allocates physical memory for a local GPT, * and initializes the GPT descriptor, creating an empty GPT. **************************************************************************************** * @ gpt : pointer on generic page table descriptor. * @ returns 0 if success / returns ENOMEM if error. ***************************************************************************************/ error_t hal_gpt_create( gpt_t * gpt ); /**************************************************************************************** * This function releases all memory dynamically allocated for a generic page table. * For a multi-levels radix tree implementation, it includes all nodes in the tree. * All GPT entries are supposed to be previously unmapped. **************************************************************************************** * @ gpt : pointer on generic page table descriptor. ***************************************************************************************/ void hal_gpt_destroy( gpt_t * gpt); /**************************************************************************************** * This blocking function atomically set the GPT_LOCKED attribute in a target PTE * of a remote GPT identified by the and arguments, after checking * (in a busy waiting loop) that this attribute has been reset. * It returns in the and buffers the value of the PTE before modification. * It atomically allocates memory to register this attribute in the PTE when * required by a specific GPT implementation (example : allocate a PT2 in the TSAR GPT). * WARNING : Only small pages can be locked. **************************************************************************************** * @ gpt_xp : [in] extended pointer on the generic page table. * @ vpn : [in] virtual page number of the target PTE. * @ attr : [out] local buffer for GPT attributes. * @ ppn : [out] local buffer for physical page number. * @ returns 0 if success / return -1 if error (no memory or big page). ***************************************************************************************/ error_t hal_gpt_lock_pte( xptr_t gpt_xp, vpn_t vpn, uint32_t * attr, ppn_t * ppn ); /**************************************************************************************** * This function atomically reset the GPT_LOCKED attribute in a target PTE in a * remote GPT identified by the and arguments. **************************************************************************************** * @ gpt_xp : pointer on the generic page table * @ vpn : virtual page number of the target PTE. ***************************************************************************************/ void hal_gpt_unlock_pte( xptr_t gpt_xp, vpn_t vpn ); /**************************************************************************************** * This low level function maps a new PTE or modifies an existing PTE in a remote GPT * identified by the and arguments, as defined by and args. * This function can be used for both a small page (PTE2), and a big page (PTE1). * * WARNING : For a small page, it checks that the GPT_LOCKED attribute has been * previously set, to prevent concurrent mapping accesses. **************************************************************************************** * @ gpt_xp : [in] extended pointer on the page table * @ vpn : [in] virtual page number * @ attr : [in] GPT attributes * @ ppn : [in] physical page number ***************************************************************************************/ void hal_gpt_set_pte( xptr_t gpt_xp, vpn_t vpn, uint32_t attr, ppn_t ppn ); /**************************************************************************************** * This low level function unmaps and unlocks a PTE from a remote GPT identified by the * and arguments. It does NOT release the allocated physical memory. * This function can be used for both a small page (PTE2), and a big page (PTE1). **************************************************************************************** * @ gpt_xp : [in] extended pointer on the page table * @ vpn : [in] virtual page number. ***************************************************************************************/ void hal_gpt_reset_pte( xptr_t gpt_xp, vpn_t vpn ); /**************************************************************************************** * This low level function returns in the and arguments the current values * of a PTE in a a remote GPT, identified by the and arguments. * This function can be used for both a small page (PTE2), and a big page (PTE1). **************************************************************************************** * @ gpt_xp : [in] extended pointer on the page table. * @ vpn : [in] virtual page number. * @ attr : [out] local buffer for generic attributes. * @ ppn : [out] local buffer for physical page number. ***************************************************************************************/ void hal_gpt_get_pte( xptr_t gpt_xp, vpn_t vpn, uint32_t * attr, ppn_t * ppn ); /**************************************************************************************** * This function is used to implement the "fork" system call: It copies a remote * source PTE, identified by the and arguments, to a local * destination PTE, identified by the and arguments. * It does nothing if the source PTE is not MAPPED and SMALL. * It optionnally activates the "Copy on Write" mechanism: when the argument is * true: the GPT_WRITABLE flag is reset, and the GPT_COW flag is set. * A new second level PT2 is allocated for the destination GPT if required. * It returns in the and arguments the PPN value for the copied PTE, * and a boolean indicating if the PTE is mapped and small, and was actually copied. **************************************************************************************** * @ dst_gpt : [in] local pointer on local destination GPT. * @ dst_vpn : [in] vpn defining the PTE in the desination GPT. * @ src_gpt_xp : [in] extended pointer on remote source GPT. * @ src_vpn : [in] vpn defining the PTE in the source GPT. * @ cow : [in] set COW flag & reset WRITABLE flag if true. * @ ppn : [out] PPN value (only if mapped is true). * @ mapped : [out] true if src_gpt[vpn] actually copied to dst_gpt[vpn]. * @ return 0 if success / return -1 if no memory for a new PT2. ***************************************************************************************/ error_t hal_gpt_pte_copy( gpt_t * dst_gpt, vpn_t dst_vpn, xptr_t src_gpt_xp, vpn_t src_vpn, bool_t cow, ppn_t * ppn, bool_t * mapped ); /**************************************************************************************** * This function atomically set the COW flag and reset the WRITABLE flag for all PTEs * of a remote GPT identified by the , , and argument in a remote GPT * identified by the argument, using remote accesses. * - The MAPPED and SMALL attributes must be set, and the LOCKED attibute must be reset * in the argument. * - The MAPPED and SMALL attributes must be set in the target PTE. **************************************************************************************** * @ gpt_xp : [in] extended pointer on the page table * @ vpn : [in] virtual page number * @ attr : [in] generic attributes * @ ppn : [in] physical page number ***************************************************************************************/ void hal_gpt_update_pte( xptr_t gpt_xp, vpn_t vpn, uint32_t attr, ppn_t ppn ); #endif /* _GPT_H_ */