/*
 * kmem.h - kernel unified memory allocator interface
 *
 * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
 *          Mohamed Lamine Karaoui (2015)
 *          Alain Greiner (2016)
 *
 * 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_types.h>
#include <kcm.h>

/*************************************************************************************
 * This enum defines the Kernel Memory Types for dynamically allocated objects.
 ************************************************************************************/

enum
{
  KMEM_PAGE             = 0,   /*! reserved for PPM allocator                       */
  KMEM_GENERIC          = 1,   /*! reserved for KHM allocator                       */
  KMEM_KCM              = 2,   /*! kcm_t                                            */
  KMEM_VSEG             = 3,   /*! vseg_t                                           */
  KMEM_DEVICE           = 4,   /*! device_t                                         */
  KMEM_MAPPER           = 5,   /*! mapper_t                                         */
  KMEM_PROCESS          = 6,   /*! process_t                                        */
  KMEM_TBD_7            = 7,
  KMEM_TBD_8            = 8,
  KMEM_TBD_9            = 9,

  KMEM_FATFS_INODE      = 10,  /*! fatfs_inode_t                                    */
  KMEM_FATFS_CTX        = 11,  /*! fatfs_ctx_t                                      */
  KMEM_RAMFS_INODE      = 12,  /*  ramfs_inode_t                                    */
  KMEM_RAMFS_CTX        = 13,  /*! ramfs_ctx_t                                      */
  KMEM_VFS_CTX          = 14,  /*! vfs_context_t                                    */
  KMEM_VFS_INODE        = 15,  /*! vfs_inode_t                                      */
  KMEM_VFS_DENTRY       = 16,  /*! vfs_dentry_t                                     */
  KMEM_VFS_FILE         = 17,  /*! vfs_file_t                                       */
  KMEM_SEM              = 18,  /*! remote_sem_t                                     */
  KMEM_TBD_19           = 19,

  KMEM_64_BYTES         = 20,  /*! fixed size buffer                                */
  KMEM_128_BYTES        = 21,  /*! fixed size buffer                                */
  KMEM_256_BYTES        = 22,  /*! fixed size buffer                                */
  KMEM_512_BYTES        = 23,  /*! fixed size buffer                                */
  KMEM_1024_BYTES       = 24,  /*! fixed size buffer                                */
  KMEM_2048_BYTES       = 25,  /*! fixed size buffer                                */

  KMEM_TYPES_NR         = 26,
};

/*************************************************************************************
 * 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   // must be reset to 0

/*************************************************************************************
 * This structure defines a Kernel Memory Request. 
 ************************************************************************************/

typedef struct kmem_req_s
{
    uint32_t      type;   /*! request type                                          */
    uint32_t      size;   /*! ln2(nb_pages) if PPM / bytes if KHM / unused by KCM   */
    uint32_t      flags;  /*! request attributes                                    */
    void        * ptr;    /*! local pointer on allocated buffer (only used by free) */
} 
kmem_req_t;

/*************************************************************************************
 * This generic function allocates physical memory in the local cluster
 * as specified by the request descriptor.
 * It uses three specialised physical memory allocators:
 * - PPM (Physical Pages Manager) allocates N contiguous physical pages,
 *       N must be a power of 2.
 * - KHM (Kernel Heap Manager) allocates a physical memory buffer,
 *       that can have any size.
 * - KCM (Kernel Cache Manager) allocates various fixed size objects,
 *       handling a dedicated cache for each object type.
 *************************************************************************************
 * @ req : local pointer to allocation request
 * @ return a local pointer to allocated buffer / NULL otherwise
 ************************************************************************************/
void * kmem_alloc( kmem_req_t * req );

/*************************************************************************************
 * This function releases previously allocated physical memory, as specified
 * by the "type" and "ptr" fiels of the kmem-req_t request.
 *************************************************************************************
 * @ req : local pointer to request descriptor.
 ************************************************************************************/
void  kmem_free ( kmem_req_t * req );


#endif	/* _KMEM_H_ */
