/*
 * Copyright (c) 1993 - 2000 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef	_VM_SPT_H
#define	_VM_SPT_H

#pragma ident	"@(#)seg_spt.h	1.15	00/10/02 SMI"

#ifdef	__cplusplus
extern "C" {
#endif

#ifndef _ASM

#include <sys/types.h>
#include <sys/t_lock.h>

/*
 * Passed data when creating spt segment.
 */
struct  segspt_crargs {
	struct	seg	*seg_spt;
	struct anon_map *amp;
	uint_t		prot;
	uint_t		flags;
};

struct spt_data {
	struct vnode	*vp;
	struct anon_map	*amp;
	size_t 		realsize;
	struct page	**ppa;
	uint_t		prot;
	kmutex_t 	lock;
	size_t		pcachecnt;	/* # of times in pcache */
	uint_t		flags;		/* Dynamic ISM or regular ISM */
	spgcnt_t	lckpgs;		/* # of locked DISM pages */
};

/*
 * Private data for spt_shm segment.
 */
struct sptshm_data {
	struct as	*sptas;
	struct anon_map *amp;
	size_t		softlockcnt;	/* # outstanding lock operations */
	struct seg 	*sptseg;	/* pointer to spt segment */
	char		*vpage;		/* indicating locked pages */
};

#define	DISM_PG_LOCKED		0x1	/* DISM page is locked */
#define	DISM_PPA_CHANGED	0x2	/* DISM new lock, need to rebuild ppa */

#endif

#ifdef _KERNEL

#ifndef _ASM

/*
 * Functions used in shm.c to call ISM.
 */
int	sptcreate(size_t size, struct seg **sptseg, struct anon_map *amp,
	    uint_t prot, uint_t flags);
void	sptdestroy(struct as *, struct anon_map *);
int	segspt_shmattach(struct seg *, caddr_t *);

#define	isspt(sp)	((sp)->shm_sptinfo ? (sp)->shm_sptinfo->sptas : NULL)
#define	spt_on(a)	(share_page_table || ((a) & SHM_SHARE_MMU))
#define	spt_pageable(a)	((a) & SHM_PAGEABLE)

/*
 * This can be applied to a segment with seg->s_ops == &segspt_shmops
 * to determine the real size of the ISM segment.
 */
#define	spt_realsize(seg) (((struct spt_data *) \
	(((struct sptshm_data *)((seg)->s_data))->sptseg->s_data))->realsize)

#endif

/*
 * In a 64-bit address space, we'll try to put ISM segments between
 * PREDISM_BASE and PREDISM_BOUND.  The HAT may use these constants to
 * predict that a VA is contained by an ISM segment, which may optimize
 * translation.  The range must _only_ be treated as advisory; ISM segments
 * may fall outside of the range, and non-ISM segments may be contained
 * within the range.
 */
#define	PREDISM_BASESHIFT	33
#define	PREDISM_BASE		((uintptr_t)1 << PREDISM_BASESHIFT)
#define	PREDISM_BOUND		((uintptr_t)1 << 63)

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _VM_SPT_H */
