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
17static int uart; // is there a uart?
18
19void
20uartinit(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 ioapicenable(IRQ_COM1, 0);
45
46 // Announce that we're here.
47 for(p="xv6...\n"; *p; p++)
48 uartputc(*p);
49}
50
51void
52uartputc(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
63static int
64uartgetc(void)
65{
66 if(!uart)
67 return -1;
68 if(!(inb(COM1+5) & 0x01))
69 return -1;
70 return inb(COM1+0);
71}
72
73void
74uartintr(void)
75{
76 consoleintr(uartgetc);
77}
78