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