/*
 * kmem.h - unified kernel memory allocator definition
 *
 * Authors  Alain Greiner     (2016,2017,2018,2019,2020)
 *
 * 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; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _KMEM_H_
#define _KMEM_H_

#include <hal_kernel_types.h>
#include <kcm.h>

/*************************************************************************************
 * This defines the generic Allocation Flags that can be associated to
 * a Kernel Memory Request.
 ************************************************************************************/

#define AF_NONE       0x0000   // no attributes
#define AF_KERNEL     0x0001   // for kernel use ???
#define AF_ZERO       0x0002   // data buffer must be reset to 0

/*************************************************************************************
 * These two functions allocate physical memory in a local or remote cluster
 * as specified by the <cxy>, <order> and <flags> arguments, and return a local
 * pointer on the allocated buffer. The buffer size (in bytes) is a power of 2,
 * equal to (1 << order) bytes. It can be initialized to zero if requested.
 * Depending on the <order> value, it uses two specialised allocators:
 * - When order is larger or equal to CONFIG_PPM_PAGE_ORDER, the PPM (Physical Pages
 *   Manager) allocates 2**(order - PPM_PAGE_ORDER) contiguous small physical pages.
 *   This allocator implements the buddy algorithm.
 * - When order is smaller than CONFIG_PPM_PAGE_ORDER, the KCM (Kernel Cache Manager) 
 *   allocates an aligned block of 2**order bytes from specialised KCM[ORDER] caches
 *  (one KCM cache per block size).  
 *************************************************************************************
 * @ cxy    : [in] target cluster identifier for a remote access).
 * @ order  : [in] ln( block size in bytes).
 * @ flags  : [in] allocation flags defined above.
 * @ return local pointer on allocated buffer if success / return NULL if no memory.
 ************************************************************************************/
void * kmem_alloc( uint32_t  order,
                   uint32_t  flags );

void * kmem_remote_alloc( cxy_t     cxy,
                          uint32_t  order,
                          uint32_t  flags );

/*************************************************************************************
 * These two functions release a previously allocated physical memory block,
 * as specified by the <cxy>, <order> and <ptr> arguments. 
 * - When order is larger or equal to CONFIG_PPM_PAGE_ORDER, the PPM (Physical Pages
 *   Manager) releases 2**(order - PPM_PAGE_ORDER) contiguous small physical pages.
 *   This allocator implements the buddy algorithm.
 * - When order is smaller than CONFIG_PPM_PAGE_ORDER, the KCM (Kernel Cache Manager)
 *   release release the block of 2**order bytes to the specialised KCM[order] cache.
 *************************************************************************************
 * @ cxy    : [in] target cluster identifier for a remote access.
 * @ ptr    : [in] local pointer to released block.
 * @ order  : [in] ln( block size in bytes ).
 ************************************************************************************/
void  kmem_free( void    * ptr,
                 uint32_t  order );

void  kmem_remote_free( cxy_t     cxy,
                        void    * ptr,
                        uint32_t  order );


#endif	/* _KMEM_H_ */
