/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

#ident		"$Header: mftpr.h 1.10 90/06/27 $"

#ifndef	_SYS_MFTPR_H_

/*
 * mftpr.h
 *	Various asm functions to read/write processor special registers.
 *
 * i386 version.
 *
 * Historic name, stands for "move from/to processor registers".
 */

/* $Log:	mftpr.h,v $
 */

/*
 * Code to read/write processor registers from C.
 */

/* increment performance counter and flush tlb */
#define FLUSH_TLB()	{l.cnt.v_tlbflush++; LFLUSH_TLB();}

#ifndef	lint				/* lint can't handle asm fcts yet */

asm READ_PTROOT()			/* page-table root */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%cr3, %eax
/PEEPON					/* turn peephole opt back on */
}

asm WRITE_PTROOT(val)			/* page-table root */
{
%ureg val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %cr3
/PEEPON					/* turn peephole opt back on */

%mem val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %cr3
/PEEPON					/* turn peephole opt back on */
}

asm LFLUSH_TLB()			/* flush TLB (11 cycles on 386) */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%cr3, %eax
	movl	%eax, %cr3
/PEEPON					/* turn peephole opt back on */
}

asm void INVAL_ONCHIP_CACHE()
{
/PEEPOFF				/* turn off peephole optimizer */
	.byte	0x0f, 0x08		/* invd: using the manly encoding */
/PEEPON					/* turn peephole opt back on */
}

asm unsigned READ_MSW()			/* machine status word (CR0) */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%cr0, %eax
/PEEPON					/* turn peephole opt back on */
}

asm WRITE_MSW(val)			/* machine status word (CR0) */
{
%con val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %cr0
/PEEPON					/* turn peephole opt back on */
%mem val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %cr0
/PEEPON					/* turn peephole opt back on */
}

asm READ_DSR()				/* Debug-Status Register (DR6) */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%db6, %eax
/PEEPON					/* turn peephole opt back on */
}

asm WRITE_DSR(val)			/* Debug-Status Register (DR6) */
{
%con val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %db6
/PEEPON					/* turn peephole opt back on */
}

asm WRITE_DCR(val)			/* Debug-Control Register (DR7) */
{
%con val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %db7
/PEEPON					/* turn peephole opt back on */
}

asm WRITE_DB0(val)			/* Debug-Register 0*/
{
%mem val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %db0
/PEEPON					/* turn peephole opt back on */
}
asm WRITE_DB1(val)			/* Debug-Register 0*/
{
%mem val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %db1
/PEEPON					/* turn peephole opt back on */
}
asm WRITE_DB2(val)			/* Debug-Register 0*/
{
%mem val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %db2
/PEEPON					/* turn peephole opt back on */
}
asm WRITE_DB3(val)			/* Debug-Register 0*/
{
%mem val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %db3
/PEEPON					/* turn peephole opt back on */
}
asm WRITE_DB6(val)			/* Debug-Register 6*/
{
%mem val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %db6
/PEEPON					/* turn peephole opt back on */
}
asm WRITE_DB7(val)			/* Debug-Register 0*/
{
%mem val;
/PEEPOFF				/* turn off peephole optimizer */
	movl	val, %eax
	movl	%eax, %db7
/PEEPON					/* turn peephole opt back on */
}

asm READ_DB0()				/* Debug-Status Register (DR6) */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%db0, %eax
/PEEPON					/* turn peephole opt back on */
}

asm READ_DB1()				/* Debug-Status Register (DR6) */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%db1, %eax
/PEEPON					/* turn peephole opt back on */
}

asm READ_DB2()				/* Debug-Status Register (DR6) */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%db2, %eax
/PEEPON					/* turn peephole opt back on */
}

asm READ_DB3()				/* Debug-Status Register (DR6) */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%db3, %eax
/PEEPON					/* turn peephole opt back on */
}

asm READ_DB6()				/* Debug-Status Register (DR6) */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%db6, %eax
/PEEPON					/* turn peephole opt back on */
}

asm READ_DB7()				/* Debug-Status Register (DR6) */
{
/PEEPOFF				/* turn off peephole optimizer */
	movl	%db7, %eax
/PEEPON					/* turn peephole opt back on */
}

/*
 * inb(port)
 *	Read an 8 bit value from a I/O address given by port.
 *
 * Returns value in %al (upper 3 bytes cleared).
 */
asm int inb(port)
{
%reg port;
	xorl	%eax,%eax		/* clear %eax */
/PEEPOFF
	movl	port, %edx		/* get port */
	inb	(%dx)			/* read port */
/PEEPON
%mem port;
	xorl	%eax,%eax		/* clear %eax */
/PEEPOFF
	movw	port,%dx		/* get port */
	inb	(%dx)			/* read port */
/PEEPON
}

/*
 * outb(port, data)
 *	Write an 8 bit value to the I/O address given by port.
 *
 * No return value
 */
asm void outb(port, data)
{
%con port, data;
	movb	data, %al		/* get data */
/PEEPOFF
	movw	port,%dx		/* get port */
	outb	(%dx)			/* write port */
/PEEPON
%con port; reg data;
	movl	data, %eax		/* get data */
/PEEPOFF
	movw	port,%dx		/* get port */
	outb	(%dx)			/* write port */
/PEEPON
%con port; mem data;
	movl	data, %eax		/* get data */
/PEEPOFF
	movw	port,%dx		/* get port */
	outb	(%dx)			/* write port */
/PEEPON
%reg port; con data;
	movb	data,%al		/* get data */
/PEEPOFF
	movl	port,%edx		/* get port */
	outb	(%dx)			/* write port */
/PEEPON
%reg port, data;
	movl	data,%eax		/* get data */
/PEEPOFF
	movl	port,%edx		/* get port */
	outb	(%dx)			/* write port */
/PEEPON
%reg port; mem data;
	movl	data,%eax		/* get data */
/PEEPOFF
	movl	port,%edx		/* get port */
	outb	(%dx)			/* write port */
/PEEPON
%mem port; con data;
	movb	data,%al		/* get data */
/PEEPOFF
	movw	port,%dx		/* get port */
	outb	(%dx)			/* write port */
/PEEPON
%mem port, data;
	movl	data,%eax		/* get data */
/PEEPOFF
	movw	port,%dx		/* get port */
	outb	(%dx)			/* write port */
/PEEPON
}

/*
 * INW(port)
 *	Read a 16 bit value from a I/O address given by port.
 *
 * Returns value in %ax (upper 2 bytes cleared).
 */
asm int inw(port)
{
%mem port;
/PEEPOFF
	xorl	%eax,%eax		/* return value */
	movw	port,%dx		/* get port */
	inw	(%dx)			/* read port */
/PEEPON
}

/*
 * outw(port, data)
 *	Write a 16 bit value to the I/O address given by port.
 *
 * No return value.
 */
asm void outw(port, data)
{
%mem port; con data;
/PEEPOFF
	movw	data,%ax		/* get data */
	movw	port,%dx		/* get port */
	outw	(%dx)			/* write port */
/PEEPON
%mem port, data;
/PEEPOFF
	movl	data,%eax		/* get data */
	movw	port,%dx		/* get port */
	outw	(%dx)			/* write port */
/PEEPON
}

/*
 * hdin(port, addr)
 *	Transfer a 512 byte sector from I/O address port to addr.
 *
 * No return value.
 */
asm void hdin(port, addr)
{
%mem port, addr;
/PEEPOFF
	movl	%edi, %eax			/* save %edi */
	movw	port,%dx			/* get port */
	movl	addr,%edi			/* get address */
	movl	$256,%ecx			/* load count (256 words) */
	rep;	insw				/* string move the words */
	movl	%eax, %edi			/* restore %edi */
/PEEPON
}

/*
 * hdout(port, addr)
 *	Transfer a 512 byte sector from addr to I/O address port.
 *
 * No return value.
 */
asm void hdout(port, addr)
{
%mem port, addr;
/PEEPOFF
	movl	%esi, %eax			/* save %esi */
	movw	port,%dx			/* get port */
	movl	addr,%esi			/* get address */
	movl	$256,%ecx			/* load count (256 words) */
	rep;	outsw				/* string move the words */
	movl	%eax, %esi			/* restore %esi */
/PEEPON
}

asm void intr_disable()
{
/PEEPOFF
	pushfl
	cli
/PEEPON
}

asm void intr_restore()
{
/PEEPOFF
	popfl
/PEEPON
}

asm void intr_enable()
{
/PEEPOFF
	popfl
	sti
/PEEPON
}
#else	/* lint */
void	INVAL_ONCHIP_CACHE();
unsigned READ_MSW();
#endif	/* lint */

/*
 * newptes(vaddr, size)
 *	Insure the MMU TLB for the given address range is flushed of any
 *	stale cached map.  i386 has no per-page way to do this, thus flush
 *	entire TLB.  Doing it in-line avoids some of the overhead.
 */

#define	newptes(vaddr,size)	FLUSH_TLB()

/*
 * flush_tlb()
 *	flush kernel tlb in a "portable way. On the
 *	386, flush entire tlb.
 */
#define	flush_tlb()	FLUSH_TLB()

#define	_SYS_MFTPR_H_
#endif	/* _SYS_MFTPR_H_ */
