Coherent4.2.10/i386/die.c

Compare this file to the similar file:
Show the results in this format:

/* $Header: /ker/i386/RCS/die.c,v 2.3 93/10/29 00:56:42 nigel Exp Locker: nigel $ */
/*
 * die.c -- Get information out from a very young kernel which probably
 * can't do printf()'s.
 *
 * $Log:	die.c,v $
 * Revision 2.3  93/10/29  00:56:42  nigel
 * R98 (aka 4.2 Beta) prior to removing System Global memory
 * 
 * Revision 2.2  93/08/19  03:40:00  nigel
 * Nigel's R83
 * 
 */

#if KLAATU
#define SERIAL_CONSOLE	1
#define INS8250 0x3f8	/* klaatu */
#endif

#if GORT
#define SERIAL_CONSOLE	1
#define	INS8250	0x290	/* gort */
#endif

#ifndef INS8250
#define INS8250 0x3f8
#endif

#define	_KERNEL		1

#include <kernel/reg.h>
#include <sys/mmu.h>
#include <ctype.h>

#define COLOR	((char *) (0x0000B0000 + ctob(SBASE-PBASE)))
#define MONO	((char *) (0x0000B8000 + ctob(SBASE-PBASE)))
#define PAGING	(0x80000000)	/* Paging bit in cr0, set if paging is on.  */
static int chirp_off;

/*
 * void _chirp(char c, off);
 * Put character 'c' directly in video memory at offset 'off';
 *
 * This routine must not use any static variables, since the .data
 * segment is not necessarily available yet.
 */
void
_chirp(c, off)
char c;
int off;
{
#if SERIAL_CONSOLE
	__putchar(c);
#else
	if (!paging()) {
		*(COLOR + off) = c;
		*(MONO + off) = c;
	} else {
		*((char *) (ctob(VIDEOa) + off)) = c;
		*((char *) (ctob(VIDEOb) + off)) = c;
	}
#endif
}

/*
 * void chirp(char c);
 * Put character 'c' directly in the first character of video memory;
 *
 * This routine must not use any static variables, since the .data
 * segment is not necessarily available yet.
 */
void
chirp(c)
char c;
{
	_chirp(c, 158);
}

/*
 * void strchirp(char *str);
 * Put string 'str' directly in the next character of video memory;
 * Note that calls to chirp and dchirp do not effect what mchirp considers
 *      to be the next character.
 *
 * This routine uses a ds variable, so it must not be used until the .data
 * segment is available (this currently happens in the middle of mchinit).
 */
void
strchirp(str)
char *str;
{
	char c;
	
	while ((c = * str ++) != 0) {
		_chirp (c, chirp_off);
		chirp_off += 2;
	}
}

/*
 * void mchirp(char c);
 * Put character 'c' directly in the next character of video memory;
 * If c == 0 reset the "next" character to be the first character.
 * Note that calls to chirp and dchirp do not effect what mchirp considers
 *      to be the next character.
 *
 * This routine uses a static variable, so it must not be used until the .data
 * segment is available (this currently happens in the middle of mchinit).
 */
void
mchirp(c)
char c;
{
	if ('\0' != c) {
		_chirp(c, chirp_off);
		chirp_off += 2;

		/* Don't go past 80 x 25 screen */

		if (chirp_off > 4000)	/* Don't go past 80 x 25 screen */
			chirp_off = 0;
	} else
		chirp_off = 0;
}

/*
 * void dchirp(char c, charpos);
 * Put character 'c' directly in the 'charpos' character of video memory;
 *
 * This routine must not use any static variables, since the .data
 * segment is not necessarily available yet.
 */
void
dchirp(c, charpos)
	char c;
	int charpos;
{
	_chirp(c, charpos<<1);
}

/*
 * void die(char c);
 * Put character 'c' directly in video memory, and then halt.
 */
void
die(c)
	char c;
{
	_chirp(c, 0);
	for (;;) {
		halt();
	}
}

#define LINESIZE 80

/*
 * puts() -- put a NUL terminated string.
 * Takes one argument--a pointer to a NUL terminated character string.
 */
void
puts(s)
	register char *s;
{
	while (*s != '\0') {
		mchirp(*s++);
	}

}


#define BS '\010'
#define DEL '\0'	/* This is really what getchar() returns!  */
#define NAK '\025'

#define BITS_PER_INT16		16	/* Number of bits in an int16.  */
#define DIGITS_PER_INT16	4	/* Maximum hex digits in a 16 bit number.  */
#define DIGITS_PER_INT8		2	/* Maximum hex digits in an 8 bit number.  */

#if SERIAL_CONSOLE
#define OUTCH(c)	__putchar(c)
#else
#define OUTCH(c)	mchirp(c)
#endif

void
hexprint(n, hexdigits)
int n, hexdigits;
{
	int shift;
	char digit, outch;

	for (shift = 4*(hexdigits-1); shift >= 0; shift -= 4) {
		digit = (n >> shift) & 0xF;
		if (digit > 9)
			outch = 'A'+digit-10;
		else
			outch = '0'+digit;
		OUTCH(outch);
	}
	OUTCH(' ');
}

/*
 * Print a 32/16/8 bit integers in hexadecimal.
 */

void print32(num) int num;	{hexprint(num,8);}
void print16(num) int num;	{hexprint(num,4);}
void print8(num)  int num;	{hexprint(num,2);}


void
outch(c)
int c;
{
	OUTCH(c);
}

#define	ASCII	1
#define	XONXOFF	1
#define	BAUD	9600

/*
 *	file:	i8251.c
 *
 *	This version of putchar works with the serial lines.
 *	Various configurations are possible through conditional
 *	defines:
 *
 *	BAUD	default 9600
 *		specifies the baudrate, can be as high as 38400
 *
 *	CONSOLE	default COM1:
 *		is the base address of the uart
 *
 *	ASCII	default BINARY
 *		if set, maps '\n' into CR, LF and reduces input
 *		to 7-bit
 *
 *	XONXOFF	default not enabled
 *		allows user to control output
 *
 */

#define	THR	(INS8250+0)
#define	IER	(INS8250+1)
#define	IIR	(INS8250+2)
#define	LCR	(INS8250+3)
#define	MCR	(INS8250+4)
#define	LSR	(INS8250+5)
#define	MSR	(INS8250+6)

#define	RBR	THR
#define	DLL	THR
#define	DLM	IER

#define	DR	0x01
#define	THRE	0x20

void
__cinit()
{
#if SERIAL_CONSOLE
	register rate;

#if	BAUD
	rate = 115200L / BAUD;
#else
	rate = 1;
#endif
	outb(LCR, 0x00);
	outb(IER, 0x00);
	outb(LCR, 0x80);
	outb(DLL, rate);
	outb(DLM, rate>>8);
	outb(LCR, 0x03);
	outb(MCR, 0x03);
	__putchar('\007');
	__putchar('g');
#endif
}

#define CTLQ	0021
#define CTLS	0023

int
__getchar()
{
	register int c;

	while( (inb(LSR) & DR) == 0 )
		;
	c = inb( RBR );
#if	ASCII
	c &= 0x7F;
#endif
	return( c );
}

int
__putchar( c )
register char c;
{
	register int f;

#if	ASCII
	if (c == '\n')
		putchar( '\r' );
#endif
	while( ((f=inb(LSR)) & THRE) == 0 )
		;
#if	XONXOFF
	if( (f & DR) != 0 ) {
		f = inb( RBR ) & 0x7F;
		if (f == CTLS) {
			do {
				while( (inb(LSR) & DR) == 0)
					;
				f = inb( RBR ) & 0x7F;
			} while (f != CTLQ);
		}
	}
#endif
	outb( THR, c );
	return( c );
}