xref: /xv6-public/uart.c (revision 4f14d8d1)
174afa70dSrsc // Intel 8250 serial port (UART).
274afa70dSrsc 
374afa70dSrsc #include "types.h"
474afa70dSrsc #include "defs.h"
574afa70dSrsc #include "param.h"
674afa70dSrsc #include "traps.h"
774afa70dSrsc #include "spinlock.h"
8*dec637bcSFrans Kaashoek #include "sleeplock.h"
90aef8914SRuss Cox #include "fs.h"
100aef8914SRuss Cox #include "file.h"
1174afa70dSrsc #include "mmu.h"
1274afa70dSrsc #include "proc.h"
1374afa70dSrsc #include "x86.h"
1474afa70dSrsc 
1574afa70dSrsc #define COM1    0x3f8
1674afa70dSrsc 
1774afa70dSrsc static int uart;    // is there a uart?
1874afa70dSrsc 
1974afa70dSrsc void
uartinit(void)2074afa70dSrsc uartinit(void)
2174afa70dSrsc {
2274afa70dSrsc   char *p;
2374afa70dSrsc 
2474afa70dSrsc   // Turn off the FIFO
2574afa70dSrsc   outb(COM1+2, 0);
2674afa70dSrsc 
2774afa70dSrsc   // 9600 baud, 8 data bits, 1 stop bit, parity off.
2874afa70dSrsc   outb(COM1+3, 0x80);    // Unlock divisor
2974afa70dSrsc   outb(COM1+0, 115200/9600);
3074afa70dSrsc   outb(COM1+1, 0);
3174afa70dSrsc   outb(COM1+3, 0x03);    // Lock divisor, 8 data bits.
3274afa70dSrsc   outb(COM1+4, 0);
3374afa70dSrsc   outb(COM1+1, 0x01);    // Enable receive interrupts.
3474afa70dSrsc 
3574afa70dSrsc   // If status is 0xFF, no serial port.
3674afa70dSrsc   if(inb(COM1+5) == 0xFF)
3774afa70dSrsc     return;
3874afa70dSrsc   uart = 1;
3974afa70dSrsc 
4074afa70dSrsc   // Acknowledge pre-existing interrupt conditions;
4174afa70dSrsc   // enable interrupts.
4274afa70dSrsc   inb(COM1+2);
4374afa70dSrsc   inb(COM1+0);
4474afa70dSrsc   ioapicenable(IRQ_COM1, 0);
4574afa70dSrsc 
4674afa70dSrsc   // Announce that we're here.
4774afa70dSrsc   for(p="xv6...\n"; *p; p++)
4874afa70dSrsc     uartputc(*p);
4974afa70dSrsc }
5074afa70dSrsc 
5174afa70dSrsc void
uartputc(int c)5274afa70dSrsc uartputc(int c)
5374afa70dSrsc {
5474afa70dSrsc   int i;
5574afa70dSrsc 
5674afa70dSrsc   if(!uart)
5774afa70dSrsc     return;
5874afa70dSrsc   for(i = 0; i < 128 && !(inb(COM1+5) & 0x20); i++)
5974afa70dSrsc     microdelay(10);
6074afa70dSrsc   outb(COM1+0, c);
6174afa70dSrsc }
6274afa70dSrsc 
6374afa70dSrsc static int
uartgetc(void)6474afa70dSrsc uartgetc(void)
6574afa70dSrsc {
6674afa70dSrsc   if(!uart)
6774afa70dSrsc     return -1;
6874afa70dSrsc   if(!(inb(COM1+5) & 0x01))
6974afa70dSrsc     return -1;
7074afa70dSrsc   return inb(COM1+0);
7174afa70dSrsc }
7274afa70dSrsc 
7374afa70dSrsc void
uartintr(void)7474afa70dSrsc uartintr(void)
7574afa70dSrsc {
7674afa70dSrsc   consoleintr(uartgetc);
7774afa70dSrsc }
78