uart.c (1345B)
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 uartearlyinit(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 // Announce that we're here. 40 for(p="xv6...\n"; *p; p++) 41 uartputc(*p); 42 } 43 44 void 45 uartinit(void) 46 { 47 if (!uart) 48 return; 49 50 // Acknowledge pre-existing interrupt conditions; 51 // enable interrupts. 52 inb(COM1+2); 53 inb(COM1+0); 54 picenable(IRQ_COM1); 55 ioapicenable(IRQ_COM1, 0); 56 } 57 58 void 59 uartputc(int c) 60 { 61 int i; 62 63 if(!uart) 64 return; 65 for(i = 0; i < 128 && !(inb(COM1+5) & 0x20); i++) 66 microdelay(10); 67 outb(COM1+0, c); 68 } 69 70 static int 71 uartgetc(void) 72 { 73 if(!uart) 74 return -1; 75 if(!(inb(COM1+5) & 0x01)) 76 return -1; 77 return inb(COM1+0); 78 } 79 80 void 81 uartintr(void) 82 { 83 consoleintr(uartgetc); 84 }