/*
    Copyright 2001 (c) by Claudio Jeker,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public 
    Licence. A full copy of the GNU GPL is provided in the file COPYING 
    found in the development root of Topsy.
*/
/*
	
    File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/VMemory/Attic/vm_object.h,v $
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2922 $
    Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $  by: $Author: baderma $
 
*/

/* vm_object.h: definition of the vm object managers and other types used for
	 vm object handling.
 */

/* object manager functions:
	 - init: init manager
	 - connect: attach object to a region
	 - disconnect: remove region from object
	 - share: share an object to an other region
	 - attach: attach a non anonymous object to a anonymous object
	 - extend: grow/shrink object
	 - loan_out: loan out the defined page
	 - loan_in: loan in the defined page
	 - loan_alloc: return a page ready to loan (only for loan object)
	 - lookup: for page fault handler
	 - get_type: return manager type
	 - get_arg: return object argument (e.g. file name)
	 - lock/unlock: lock/unlock object
	 
	 NOTES: vm object manager do not need to access the pmap layer.
	 				The only functions that do access (update) the pmap layer are:
						- vm_region_lookup to allocate pages
						- vm_region_free and all other functions that free pages
						- vm_region_loan_*
						- all functions that change protection or split a region
 */
#ifndef __VM_OBJECT_H__
#define __VM_OBJECT_H__

#include "vm_page.h"
#include "vm_region.h"

struct vm_oref;
struct vm_map;
struct vm_manager;

int vm_manager_init(void);

int vm_manager_add(unsigned short type, struct vm_manager* manager);
int vm_manager_unadd(unsigned short type);
int vm_object_connect(int type,
                      struct vm_object_arg* arg, struct vm_oref* oref);
void vm_manager_list(void);
extern int (*vm_object_attach)(struct vm_oref*);


/* intitialize manager: allocate structures needed by the manager called only
	 on startup/load of the manager.
 */
typedef int(*vm_manager_initalize)(void);

/* connect: attach the specified object to a region (modifies a vm_oref). */
typedef int(*vm_manager_connect)(struct vm_oref*, struct vm_object_arg*);

/* discconect: remove a region from an object, if possible free some memory */
typedef int(*vm_manager_disconnect)(struct vm_oref*);

/* share: share a region with a new region. */
typedef int(*vm_manager_share)(struct vm_oref*, struct vm_oref*, int);

/* attach: attach a non anonymous object to a anonymous region.
	 This is used for region COW. Use default handler if non anonymous.
 */
typedef int(*vm_manager_attach)(struct vm_oref*);

/* extend: grow or shrink the size of object. Use default handler if
	 this call makes no sens for the object */
typedef int(*vm_manager_extend)(struct vm_oref*, size_t);

/* loan_out: loan out the specified pages. */
typedef int(*vm_manager_loan_alloc)(struct vm_oref*, offset_t*,
                                    struct vm_page**, int);
typedef int(*vm_manager_loan_dealloc)(struct vm_oref*, offset_t);
typedef int(*vm_manager_loan_out)(struct vm_oref*, offset_t,
                                  struct vm_page**, int*);
typedef int(*vm_manager_loan_in)(struct vm_oref*, offset_t*, struct vm_page*);

/* lookup: main function, lookup page in object.
	 Used by the page fault handler
 */
typedef int(*vm_manager_lookup)(struct vm_oref*,
                                offset_t, int, struct vm_page**);

/* map: function for mapping memory used by the kernel.
	 Used only during bootup.
 */
typedef int(*vm_manager_map)(struct vm_oref*, offset_t, address_t, address_t);

/* get_type: return type of the manager */
typedef int(*vm_manager_get_type)(struct vm_oref*, unsigned short*, char**);

/* get_arg: return argument of the object (e.g. file name) */
typedef int(*vm_manager_get_arg)(struct vm_oref*,
                                 struct vm_object_arg*);

/* XXX missing but needed lock/unlock, lock/unlock object, needed for some work
	 on region level (resize, chprot,...).
 */

struct vm_manager
{
  vm_manager_connect connect;
  vm_manager_disconnect disconnect;
  vm_manager_share share;
  vm_manager_attach attach;
  vm_manager_extend extend;
  vm_manager_loan_alloc loan_alloc;
  vm_manager_loan_dealloc loan_dealloc;
  vm_manager_loan_out loan_out;
  vm_manager_loan_in loan_in;
  vm_manager_lookup lookup;
  vm_manager_map map;
  vm_manager_get_type get_type;
  vm_manager_get_arg get_arg;
  vm_manager_initalize init;
};

/* should be moved to vm_extern.h */
#define VM_OBJ_SHARE_RO		0x01
#define VM_OBJ_SHARE_RW		0x02
#define VM_OBJ_SHARE_COW	0x04
#define VM_OBJ_SHARE_SNAP	0x08
#define VM_OBJ_SHARE_MASK	0x0F
#define VM_OBJ_NEEDS_COPY 0x10

struct vm_oref
{
  struct vm_manager*		manager;
  union {
    struct vm_map*			vm_map;
    address_t				object;
  } obj;
  offset_t					offset;
  int						flags;
};

int default_disconnect(struct vm_oref* oref);
int default_share(struct vm_oref* dest, struct vm_oref* src, int flag);
int default_attach(struct vm_oref* oref);
int default_extend(struct vm_oref* oref, size_t size);
int default_get_type(struct vm_oref* oref, unsigned short* type, char** s);
int default_get_arg(struct vm_oref* oref, struct vm_object_arg* arg);

int default_loan_alloc(struct vm_oref* oref, offset_t* pagestartPtr,
                       struct vm_page** pagePtr, int flags);
int default_loan_dealloc(struct vm_oref* oref, offset_t pagestart);
int default_loan_out(struct vm_oref* oref, offset_t pagestart,
                     struct vm_page** pagePtr, int* remove);
int default_loan_in(struct vm_oref* oref, offset_t* pagestartPtr,
                    struct vm_page* page);
int default_lookup(struct vm_oref* oref, offset_t offset, int type,
                   struct vm_page** page);
int default_map(struct vm_oref* oref, offset_t offset, address_t virt, address_t phys);

/* Here we include all manager headerfiles.
	 So we get the types and the struct vm_manager of each manager.
 */
#include "vm_anon.h"
#include "vm_file.h"
#include "steal_alloc.h"
#include "vm_loan.h"
#include "vm_dmap.h"

#endif
