/* $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: consio.c 1.13 90/04/24 $"

/*
 * consio.c
 *	Machine dependent cnputc(), putflush() implementation.
 *
 * Also, getchar for debug.
 */

/* $Log:	consio.c,v $
 */

#include "sys/types.h"
#include "sys/devsw.h"
#include "sys/signal.h"
#include "sys/param.h"
#include "sys/debug.h"
#include "sys/systm.h"
#include "sys/mutex.h"
#include "sys/user.h"
#include "sys/timer.h"
#include "sys/proc.h"
#include "sys/vm.h"
#include "sys/cfg.h"
#include "sys/arch.h"

#include "sys/engine.h"

#include "sys/pte.h"
#include "sys/plocal.h"
#include "sys/gate.h"
#include "sys/intctl.h"

static	char	pclastc[MAXNUMCPU];/* last char output, for putprocid */

int	putprocid = 1;		/* default: pre-pend proc-ID to output lines */

extern	short	upyet;		/* says if init done yet */
extern	unchar	cons_slic;	/* SLIC id of console device */

lock_t	prf_lock;		/* lock for mutual exclusion in printf */

#ifdef	DEBUG
/*
 * Data for DEBUG console....
 */
sema_t		dc_mutex;		/* semaphore for dumb console */
#endif	/* DEBUG  */

/*
 * initmonio()
 *	Init monitor IO.
 */

initmonio()
{
	register int i;

	for(i = 0; i < MAXNUMCPU; i++) {
		pclastc[i] = '\n';
	}
	init_lock(&prf_lock);
#ifdef	DEBUG
	init_sema(&dc_mutex, 1);
#endif	/* DEBUG  */
}

/*
 * cnputc()
 *	Arrange that a character be output on the "console".
 *
 */

/*ARGSUSED*/
cnputc(c)
	char	c;
{
	register int me;
	spl_t	s;

	if (c == '\n')
		cnputc('\r');

	if (!upyet) {
		sq_putc(c);
		return;
	}

	me = l.me;

	/*
	 * If desired, pre-pend processor # to output lines.
	 */

	if (putprocid && pclastc[me] == '\n') {
		pclastc[me] = '\0';
		cnputc('0' + (me/10));
		cnputc('0' + (me%10));
		cnputc(':');
		cnputc(' ');
	}

	/*
	 * Output character.
	 */

	s = splhi();				/* mutex SLIC usage */

	sq_putc(c);
	pclastc[me] = c;

	splx(s);
}

/*
 * sq_putc()
 *	Low level output of character.
 *	On the PC/3AT call kd_putc(), other machines send char via SLIC.
 *
 * Assumes caller did splhi() or otherwise blocks interrupts.
 * Can't do this here, since this used at boot time before
 * turned on kernel page-tables (==> splhi(), splx() use wrong
 * virt-addr for SLIC).
 */

sq_putc(c)
	char	c;
{
	extern void kd_putc();
#ifdef	i386
#ifdef	DEBUG
	if (upyet) l.holdgate = 0;			/* avoid panic loop */
#endif	/* DEBUG  */
#endif	/* i386  */
	if (arch_type == SYSTYP_S1)
		kd_putc(c);
	else
		mIntr(cons_slic, PUTCHAR_BIN, (unchar)c);
}
