typedef struct Conf	Conf;
typedef struct Confmem	Confmem;
typedef struct FPsave	FPsave;
typedef struct ISAConf	ISAConf;
typedef struct KMap	KMap;
typedef struct Lance	Lance;
typedef struct Lancemem	Lancemem;
typedef struct Label	Label;
typedef struct Lock	Lock;
typedef struct Mach	Mach;
typedef struct MMU	MMU;
typedef struct Pcidev	Pcidev;
typedef struct PMMU	PMMU;
typedef struct Softtlb	Softtlb;
typedef struct Ureg	Ureg;
typedef struct Proc	Proc;
typedef uvlong		Tval;

#pragma incomplete Pcidev

#define MAXSYSARG	5	/* for mount(fd, afd, mpt, flag, arg) */

/*
 *  parameters for sysproc.c and rebootcmd.c
 */
#define AOUT_MAGIC	N_MAGIC || magic==P_MAGIC
/* r3k or r4k boot images */
#define BOOT_MAGIC	(0x160<<16) || magic == ((0x160<<16)|3)

/*
 *  machine dependent definitions used by ../port/dat.h
 */

struct Lock
{
	ulong	key;			/* semaphore (non-zero = locked) */
	ulong	sr;
	uintptr	pc;
	Proc	*p;
	Mach	*m;
	ushort	isilock;
};

struct Label
{
	uintptr	sp;
	uintptr	pc;
};

struct Confmem
{
	uintptr	base;
	ulong	npage;
	uintptr	kbase;
	uintptr	klimit;
};

struct Conf
{
	ulong	nmach;		/* processors */
	ulong	nproc;		/* processes */
	Confmem	mem[2];		/* physical memory */
	ulong	npage;		/* total physical pages of memory */
	ulong	upages;		/* user page pool */
	ulong	nimage;		/* number of page cache image headers */
	ulong	nswap;		/* number of swap pages */
	int	nswppo;		/* max # of pageouts per segment pass */
	ulong	copymode;	/* 0 is copy on write, 1 is copy on reference */
	ulong	ialloc;		/* bytes available for interrupt-time allocation */
	ulong	pipeqsize;	/* size in bytes of pipe queues */
	int	nuart;		/* number of uart devices */
	int	monitor;	/* has monitor? */
};

/*
 * floating point registers
 */
enum
{
	/* floating point state */
	FPinit,
	FPactive,
	FPinactive,
	FPemu,

	/* bit meaning floating point illegal */
	FPillegal= 0x100,
};

enum {
	Nfpregs		= 32,		/* floats; half as many doubles */
};

/*
 * floating point
 * fpstate is separate, kept in Proc
 */
struct FPsave
{
	/* /dev/proc expects the registers to be first in FPsave */
	ulong	reg[Nfpregs];		/* the canonical bits */
	union {
		ulong	fpstatus;	/* both are fcr31 */
		ulong	fpcontrol;
	};

	int	fpdelayexec;		/* executing delay slot of branch */
	uintptr	fpdelaypc;		/* pc to resume at after */
	ulong	fpdelaysts;	/* save across user-mode delay-slot execution */

	/* stuck-fault detection */
	uintptr	fppc;			/* addr of last fault */
	int	fpcnt;			/* how many consecutive at that addr */
};

/*
 *  mmu goo in the Proc structure
 */
struct PMMU
{
	int	pidonmach[MAXMACH];
};

#include "../port/portdat.h"

/* First FIVE members' offsets known by l.s */
struct Mach
{
	/* the following are all known by l.s and cannot be moved */
	int		machno;			/* physical id of processor FIRST @ 0 */
	Softtlb*stb;			/* Software tlb simulation SECOND @ 8 */
	Proc*	proc;			/* process on this processor THIRD @ 16 */
	uintptr	splpc;			/* pc that called splhi() FOURTH @ 24 */
	ulong	tlbfault;		/* # of tlb faults FIFTH @ 32 */
	ulong	ktlbfault;		/* @ 36 */
	ulong	utlbfault;		/* @ 40 */

	/* the following is safe to move */
	ulong	tlbpurge;
	ulong	ticks;			/* of the clock since boot time */
	Label	sched;			/* scheduler wakeup */
	void*	alarm;			/* alarms bound to this clock */
	int	lastpid;		/* last pid allocated on this machine */
	Proc*	pidproc[NTLBPID];	/* proc that owns tlbpid on this mach */
	KMap*	kactive;		/* active on this machine */
	int	knext;
	uchar	ktlbx[NTLB];		/* tlb index used for kmap */
	uchar	ktlbnext;
	int	speed;			/* cpu speed */
	ulong	delayloop;		/* for the delay() routine */
	ulong	fairness;		/* for runproc */
	int	flushmmu;
	int	inclockintr;
	int	ilockdepth;
	Perf	perf;			/* performance counters */
	uvlong	cyclefreq;		/* Frequency of user readable cycle counter */

	/* for per-processor timers */
	ulong	lastcount;
	uvlong	fastticks;
	ulong	hz;
	ulong	maxperiod;
	ulong	minperiod;

	Proc*	readied;		/* for runproc */
	ulong	schedticks;		/* next forced context switch */

	int	pfault;
	int	cs;
	int	syscall;
	int	load;
	int	intr;
	int	hashcoll;		/* soft-tlb hash collisions */
	int	paststartup;		/* for putktlb */

	uintptr	stack[1];
};

struct KMap
{
	Ref;
	u64int	virt;
	u64int	phys0;
	u64int	phys1;
	KMap*	next;
	KMap*	konmach[MAXMACH];
	Page*	pg;
	uintptr	pc;			/* of caller to kmap() */
};

#define	VA(k)		((k)->virt)
#define PPN(x)		((uintptr)(x)>>6)		/* PPN in TLBPHYS0-1 */

/* offsets known by l.s */
struct Softtlb
{
	u64int	virt;
	u64int	phys0;
	u64int	phys1;
};

struct
{
	Lock;
	long	machs;		/* bitmap of processors */
	short	exiting;
	int	ispanic;
} active;

extern KMap kpte[];
extern register Mach	*m;
extern register Proc	*up;

extern FPsave initfp;
extern ulong memsize;

extern int normalprint;

/*
 *  a parsed plan9.ini line
 */
#define NISAOPT		8

struct ISAConf {
	char	*type;
	ulong	port;
	int	irq;
	ulong	dma;
	ulong	mem;
	ulong	size;
	ulong	freq;

	int	nopt;
	char	*opt[NISAOPT];
};

typedef struct {
	ulong	port;
	int	size;
} Devport;

struct DevConf
{
	ulong	intnum;			/* interrupt number */
	char	*type;			/* card type, malloced */
	int		nports;			/* Number of ports */
	Devport	*ports;			/* The ports themselves */
};

typedef vlong regint;		/* register sized int, ensure single instr'n */
