Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/pc/ns16552.h

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname pc/ns16552.h 1994/0902
## diff -e /dev/null /n/fornaxdump/1994/0902/sys/src/brazil/pc/ns16552.h
0a
/*
 *  PC specific code for the ns16552.  It includes support for the 2 built
 *  in uarts plus up to 5 MP-008 8 uart ISA cards.
 */
enum
{
	Maxcard= 5,		/* max serial cards */
	UartFREQ= 1843200,

	Serial=	0,
	Modem=	1,
};

#define uartwrreg(u,r,v)	outb((u)->port + r, (u)->sticky[r] | (v))
#define uartrdreg(u,r)		inb((u)->port + r)

void	ns16552setup(ulong, ulong);

/*
 *  definition of an optional serial card
 */
typedef struct Scard
{
	ISAConf;	/* card configuration */
	int	first;	/* number of first port */
} Scard;
static Scard *scard[Maxcard]; 	/* configs for the serial card */

/* power management currently only makes sense on the AT&T safari */
static void
uartpower(int dev, int onoff)
{
	switch(dev){
	case Modem:
		if(modem(onoff) < 0)
			print("can't turn %s modem speaker\n", onoff?"on":"off");
		break;
	case Serial:
		if(serial(onoff) < 0)
			print("can't turn %s serial port power\n", onoff?"on":"off");
		break;
	}
}

/*
 *  handle an interrupt to a single uart
 */
static void
ns16552intrx(Ureg *ur, void *arg)
{
	USED(ur);

	ns16552intr((ulong)arg);
}

/*
 *  interrupts from the multiport card, MP-008.  A polling port
 *  tells which of 8 devices interrupted.
 */
static void
mp008intr(Ureg *ur, void *arg)
{
	int i, loops;
	uchar n;
	Scard *mp;

	USED(ur);
	mp = arg;
	for(loops = 0;; loops++){
		if(loops > 1024)
			panic("mp008intr");
		n = ~inb(mp->mem);
		if(n == 0)
			return;
		for(i = 0; n; i++){
			if(n & 1)
				ns16552intrx(ur, uart[mp->first+i]);
			n >>= 1;
		}
	}
}

/*
 *  install the uarts (called by reset)
 */
static void
ns16552install(void)
{
	int i, j, port;
	Scard *sc;

	/* first two ports are always there and always the normal frequency */
	ns16552setup(0x3F8, UartFREQ);
	setvec(Uart0vec, ns16552intrx, (void*)0);
	ns16552setup(0x2F8, UartFREQ);
	setvec(Uart1vec, ns16552intrx, (void*)1);

	/* the rest come out of plan9.ini */
	for(i = 0; i < Maxcard; i++){
		sc = scard[i] = xalloc(sizeof(Scard));
		if(isaconfig("serial", i, sc) == 0){
			xfree(sc);
			break;
		}

		if(strcmp(sc->type, "MP008") == 0 || strcmp(sc->type, "mp008") == 0){
			/*
			 *  port gives base port address for uarts
			 *  irq is interrupt
			 *  mem is the polling port
			 *  size is the number of serial ports on the same polling port
			 *  freq is the baud rate generator frequency
			 */
			if(sc->size == 0)
				sc->size = 8;
			if(sc->freq == 0)
				sc->freq = UartFREQ;
			sc->first = nuart;
			setvec(Int0vec+sc->irq, mp008intr, sc);
			port = sc->port;
			for(j=0; j < sc->size; j++){
				ns16552setup(port, sc->freq);
				port += 8;
			}
		} else {
			/*
			 *  port gives base port address for the uart
			 *  irq is interrupt
			 *  freq is the baud rate generator frequency
			 */
			ns16552setup(sc->port, sc->freq);
			setvec(Int0vec+sc->irq, ns16552intrx, (void*)(nuart-1));
		}
	}
}

int
iprint(char *fmt, ...)
{
	char buf[PRINTSIZE];
	int n;

	n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	screenputs(buf, n);

	return n;
}
.
## diffname pc/ns16552.h 1994/1006
## diff -e /n/fornaxdump/1994/0902/sys/src/brazil/pc/ns16552.h /n/fornaxdump/1994/1006/sys/src/brazil/pc/ns16552.h
77c
				ns16552intrx(ur, (void*)(mp->first+i));
.
69,71c
	for(loops = 0; loops < 1024; loops++){
.
## diffname pc/ns16552.h 1994/1007
## diff -e /n/fornaxdump/1994/1006/sys/src/brazil/pc/ns16552.h /n/fornaxdump/1994/1007/sys/src/brazil/pc/ns16552.h
94a

	/* set up a serial console */
	p = getconf("console");
	if(p)
		ns16552special(atoi(p), 9600, &kbdq, &printq, kbdcr2nl);
.
89a
	if(already)
		return;
	already = 1;

.
88a
	static int already;
.
87a
	char *p;
.
84c
void
.
## diffname pc/ns16552.h 1994/1106
## diff -e /n/fornaxdump/1994/1007/sys/src/brazil/pc/ns16552.h /n/fornaxdump/1994/1106/sys/src/brazil/pc/ns16552.h
139a
			if(sc->freq == 0)
				sc->freq = UartFREQ;
.
134c
		} else if(strcmp(sc->type, "com") == 0 || strcmp(sc->type, "COM") == 0){
.
## diffname pc/ns16552.h 1994/1108
## diff -e /n/fornaxdump/1994/1106/sys/src/brazil/pc/ns16552.h /n/fornaxdump/1994/1108/sys/src/brazil/pc/ns16552.h
142c
			sprint(name, "eia%d00", i);
			ns16552setup(sc->port, sc->freq, name);
.
131c
				sprint(name, "eia%d%2.2d", i, j);
				ns16552setup(port, sc->freq, name);
.
99c
	ns16552setup(0x2F8, UartFREQ, "eia1");
.
97c
	ns16552setup(0x3F8, UartFREQ, "eia0");
.
89a
	char name[NAMELEN];
.
17c
void	ns16552setup(ulong, ulong, char*);
.
## diffname pc/ns16552.h 1994/1118
## diff -e /n/fornaxdump/1994/1108/sys/src/brazil/pc/ns16552.h /n/fornaxdump/1994/1118/sys/src/brazil/pc/ns16552.h
147a

		nscard++;
.
144c
			sprint(name, "eia%d00", nscard);
.
132c
				sprint(name, "eia%d%2.2d", nscard, j);
.
113c
			scard[nscard] = 0;
			continue;
.
110c
		sc = scard[nscard] = xalloc(sizeof(Scard));
.
108a
	nscard = 0;
.
87c
	int i, j, port, nscard;
.
## diffname pc/ns16552.h 1995/0222
## diff -e /n/fornaxdump/1994/1118/sys/src/brazil/pc/ns16552.h /n/fornaxdump/1995/0222/sys/src/brazil/pc/ns16552.h
153,164d
150d
138c
		} else if(cistrcmp(sc->type, "com") == 0){
.
118c
		if(cistrcmp(sc->type, "MP008") == 0){
.
## diffname pc/ns16552.h 1997/0327
## diff -e /n/fornaxdump/1995/0222/sys/src/brazil/pc/ns16552.h /n/emeliedump/1997/0327/sys/src/brazil/pc/ns16552.h
148c
			intrenable(VectorPIC+sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN);
.
131c
			intrenable(VectorPIC+sc->irq, mp008intr, sc, BUSUNKNOWN);
.
104,106c
	if(p = getconf("console")){
		port = strtol(p, &q, 0);
		if(p != q && (port == 0 || port == 1))
			ns16552special(port, 9600, &kbdq, &printq, kbdcr2nl);
	}
.
101c
	intrenable(VectorUART1, ns16552intrx, (void*)1, BUSUNKNOWN);
	addclock0link(uartclock);
.
99c
	intrenable(VectorUART0, ns16552intrx, (void*)0, BUSUNKNOWN);
.
88c
	char *p, *q;
.
75c
				ns16552intrx(ureg, (void*)(mp->first+i));
.
67d
61c
mp008intr(Ureg* ureg, void* arg)
.
51,52d
49c
ns16552intrx(Ureg*, void* arg)
.
39c
		if((*arch->serialpower)(onoff) < 0)
.
35c
		if((*arch->modempower)(onoff) < 0)
.
18c
void	ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int));
void	uartclock(void);
.
## diffname pc/ns16552.h 1998/0221
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/pc/ns16552.h /n/emeliedump/1998/0221/sys/src/brazil/pc/ns16552.h
139c
		} else if(cistrcmp(sc->type, "com") == 0 && sc->port != 0x3F8 && sc->port != 0x2F8){
.
## diffname pc/ns16552.h 1998/0910
## diff -e /n/emeliedump/1998/0221/sys/src/brazil/pc/ns16552.h /n/emeliedump/1998/0910/sys/src/brazil/pc/ns16552.h
99c
	intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN);
.
97c
	intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN);
.
## diffname pc/ns16552.h 1998/0918
## diff -e /n/emeliedump/1998/0910/sys/src/brazil/pc/ns16552.h /n/emeliedump/1998/0918/sys/src/brazil/pc/ns16552.h
149c
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN);
.
132c
			intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN);
.
## diffname pc/ns16552.h 1999/0513
## diff -e /n/emeliedump/1998/0918/sys/src/brazil/pc/ns16552.h /n/emeliedump/1999/0513/sys/src/brazil/pc/ns16552.h
148c
			ns16552setup(sc->port, sc->freq, name, Ns550);
.
138a
		} else if(cistrcmp(sc->type, "turbo650") == 0){
			/*
			 *  port gives base port address for the uart
			 *  irq is interrupt
			 *  freq is the baud rate generator frequency
			 */
			if(sc->freq == 0)
				sc->freq = UartFREQ*4;
			sprint(name, "eia%d00", nscard);
			ns16552setup(sc->port, sc->freq, name, Ns650);

			/*
			 *  multiply clock speed by 4
			 */
			if(sc->mem == 0)
				outb(0x2c8, 0);
			else
				outb(sc->mem, 0);

			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN);
.
136c
				ns16552setup(port, sc->freq, name, Ns550);
.
98c
	ns16552setup(0x2F8, UartFREQ, "eia1", Ns550);
.
96c
	ns16552setup(0x3F8, UartFREQ, "eia0", Ns550);
.
17c
void	ns16552setup(ulong, ulong, char*, int);
.
## diffname pc/ns16552.h 1999/0714
## diff -e /n/emeliedump/1999/0513/sys/src/brazil/pc/ns16552.h /n/emeliedump/1999/0714/sys/src/brazil/pc/ns16552.h
167a
			if(ioalloc(sc->port, 8, 0, name) < 0){
				print("%s: port %lud in use\n", name, sc->port);
				xfree(sc);
				scard[nscard] = 0;
				continue;
			}
.
147a
			if(ioalloc(sc->port, 8, 0, name) < 0){
				print("%s: port %lud in use\n", name, sc->port);
				xfree(sc);
				scard[nscard] = 0;
				continue;
			}
.
131a
			if(ioalloc(sc->port, 8*sc->size, 0, "mp008") < 0){
				print("mp008: port %lud in use\n", sc->port);
				xfree(sc);
				scard[nscard] = 0;
				continue;
			}
.
97a
	if(ioalloc(0x2F8, 8, 0, "eia1") < 0)
		print("eia1: port %d in use\n", 0x2F8);
.
95a
	if(ioalloc(0x3f8, 8, 0, "eia0") < 0)
		print("eia0: port %d in use\n", 0x3f8);
.
## diffname pc/ns16552.h 1999/0819
## diff -e /n/emeliedump/1999/0714/sys/src/brazil/pc/ns16552.h /n/emeliedump/1999/0819/sys/src/brazil/pc/ns16552.h
191c
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name);
.
183d
174c
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name);
.
157d
142c
			intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN, name);
.
136c
			if(ioalloc(sc->port, 8*sc->size, 0, name) < 0){
.
122a
		snprint(name, sizeof name, "eia%d00", nscard);
.
103c
	intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN, "eia1");
.
99c
	intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN, "eia0");
.
## diffname pc/ns16552.h 2000/0613
## diff -e /n/emeliedump/1999/0819/sys/src/brazil/pc/ns16552.h /n/emeliedump/2000/0613/sys/src/9/pc/ns16552.h
95,103c
	/* first two ports are usually there and always the normal frequency */
	ns16552default("eia0", 0x3F8, IrqUART0);
	ns16552default("eia1", 0x2F8, IrqUART1);

.
79a
 * install a default serial port on a PC unless 
 * name=disabled is set in plan9.ini
 */
void
ns16552default(char *name, int port, int irq)
{
	char *p;

	if((p = getconf(name)) && strncmp(p, "disabled", 8) == 0)
		return;

	if(ioalloc(port, 8, 0, name) < 0) {
		print("%s: port %x in use\n", name, port);
		return;
	}

	ns16552setup(port, UartFREQ, name, Ns550);
	intrenable(irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name);
}


/*
.
## diffname pc/ns16552.h 2000/1011
## diff -e /n/emeliedump/2000/0613/sys/src/9/pc/ns16552.h /n/emeliedump/2000/1011/sys/src/9/pc/ns16552.h
126,127c
		if(p != q && (port == 0 || port == 1)) {
			baud = 0;
			if(p = getconf("baud"))
				baud = strtoul(p, 0, 0);
			if(baud == 0)
				baud = 9600;
			ns16552special(port, baud, &kbdq, &printq, kbdcr2nl);
		}
.
107c
	int i, j, port, nscard, baud;
.
## diffname pc/ns16552.h 2001/0527 # deleted
## diff -e /n/emeliedump/2000/1011/sys/src/9/pc/ns16552.h /n/emeliedump/2001/0527/sys/src/9/pc/ns16552.h
1,217d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].