xref: /xv6-public/uart.c (revision 74afa70d)
1*74afa70dSrsc // Intel 8250 serial port (UART).
2*74afa70dSrsc 
3*74afa70dSrsc #include "types.h"
4*74afa70dSrsc #include "defs.h"
5*74afa70dSrsc #include "param.h"
6*74afa70dSrsc #include "traps.h"
7*74afa70dSrsc #include "spinlock.h"
8*74afa70dSrsc #include "dev.h"
9*74afa70dSrsc #include "mmu.h"
10*74afa70dSrsc #include "proc.h"
11*74afa70dSrsc #include "x86.h"
12*74afa70dSrsc 
13*74afa70dSrsc #define COM1	0x3f8
14*74afa70dSrsc 
15*74afa70dSrsc static int uart;	// is there a uart?
16*74afa70dSrsc 
17*74afa70dSrsc void
18*74afa70dSrsc uartinit(void)
19*74afa70dSrsc {
20*74afa70dSrsc 	char *p;
21*74afa70dSrsc 
22*74afa70dSrsc 	// Turn off the FIFO
23*74afa70dSrsc 	outb(COM1+2, 0);
24*74afa70dSrsc 
25*74afa70dSrsc 	// 9600 baud, 8 data bits, 1 stop bit, parity off.
26*74afa70dSrsc 	outb(COM1+3, 0x80);	// Unlock divisor
27*74afa70dSrsc 	outb(COM1+0, 115200/9600);
28*74afa70dSrsc 	outb(COM1+1, 0);
29*74afa70dSrsc 	outb(COM1+3, 0x03);	// Lock divisor, 8 data bits.
30*74afa70dSrsc 	outb(COM1+4, 0);
31*74afa70dSrsc 	outb(COM1+1, 0x01);	// Enable receive interrupts.
32*74afa70dSrsc 
33*74afa70dSrsc 	// If status is 0xFF, no serial port.
34*74afa70dSrsc 	if(inb(COM1+5) == 0xFF)
35*74afa70dSrsc 		return;
36*74afa70dSrsc 	uart = 1;
37*74afa70dSrsc 
38*74afa70dSrsc 	// Acknowledge pre-existing interrupt conditions;
39*74afa70dSrsc 	// enable interrupts.
40*74afa70dSrsc 	inb(COM1+2);
41*74afa70dSrsc 	inb(COM1+0);
42*74afa70dSrsc 	picenable(IRQ_COM1);
43*74afa70dSrsc 	ioapicenable(IRQ_COM1, 0);
44*74afa70dSrsc 
45*74afa70dSrsc 	// Announce that we're here.
46*74afa70dSrsc 	for(p="xv6...\n"; *p; p++)
47*74afa70dSrsc 		uartputc(*p);
48*74afa70dSrsc }
49*74afa70dSrsc 
50*74afa70dSrsc void
51*74afa70dSrsc uartputc(int c)
52*74afa70dSrsc {
53*74afa70dSrsc 	int i;
54*74afa70dSrsc 
55*74afa70dSrsc 	if(!uart)
56*74afa70dSrsc 		return;
57*74afa70dSrsc 	for(i = 0; i < 128 && !(inb(COM1+5) & 0x20); i++)
58*74afa70dSrsc 		microdelay(10);
59*74afa70dSrsc 	outb(COM1+0, c);
60*74afa70dSrsc }
61*74afa70dSrsc 
62*74afa70dSrsc static int
63*74afa70dSrsc uartgetc(void)
64*74afa70dSrsc {
65*74afa70dSrsc 	if(!uart)
66*74afa70dSrsc 		return -1;
67*74afa70dSrsc 	if(!(inb(COM1+5) & 0x01))
68*74afa70dSrsc 		return -1;
69*74afa70dSrsc 	return inb(COM1+0);
70*74afa70dSrsc }
71*74afa70dSrsc 
72*74afa70dSrsc void
73*74afa70dSrsc uartintr(void)
74*74afa70dSrsc {
75*74afa70dSrsc 	consoleintr(uartgetc);
76*74afa70dSrsc }
77