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