diff --git a/console.c b/console.c index c1c66b2..8f89b49 100644 --- a/console.c +++ b/console.c @@ -1,6 +1,6 @@ // Console input and output. -// Input is from the keyboard only. -// Output is written to the screen and the printer port. +// Input is from the keyboard or serial port. +// Output is written to the screen and serial port. #include "types.h" #include "defs.h" @@ -13,31 +13,13 @@ #include "x86.h" #define CRTPORT 0x3d4 -#define LPTPORT 0x378 #define BACKSPACE 0x100 static ushort *crt = (ushort*)0xb8000; // CGA memory static struct spinlock console_lock; int panicked = 0; -int use_console_lock = 0; - -// Copy console output to parallel port, which you can tell -// .bochsrc to copy to the stdout: -// parport1: enabled=1, file="/dev/stdout" -static void -lptputc(int c) -{ - int i; - - for(i = 0; !(inb(LPTPORT+1) & 0x80) && i < 12800; i++) - ; - if(c == BACKSPACE) - c = '\b'; - outb(LPTPORT+0, c); - outb(LPTPORT+2, 0x08|0x04|0x01); - outb(LPTPORT+2, 0x08); -} +volatile int use_console_lock = 0; static void cgaputc(int c) @@ -80,14 +62,14 @@ consputc(int c) ; } - lptputc(c); + uartputc(c); cgaputc(c); } void printint(int xx, int base, int sgn) { - static char digits[] = "0123456789ABCDEF"; + static char digits[] = "0123456789abcdef"; char buf[16]; int i = 0, neg = 0; uint x; diff --git a/trap.c b/trap.c index f35f8de..f95e563 100644 --- a/trap.c +++ b/trap.c @@ -62,6 +62,11 @@ trap(struct trapframe *tf) kbdintr(); lapiceoi(); break; + case IRQ_OFFSET + IRQ_COM1: + uartintr(); + lapiceoi(); + break; + case IRQ_OFFSET + 7: case IRQ_OFFSET + IRQ_SPURIOUS: cprintf("cpu%d: spurious interrupt at %x:%x\n", cpu(), tf->cs, tf->eip); diff --git a/traps.h b/traps.h index b69edd2..6476bbe 100644 --- a/traps.h +++ b/traps.h @@ -31,6 +31,7 @@ #define IRQ_TIMER 0 #define IRQ_KBD 1 +#define IRQ_COM1 4 #define IRQ_IDE 14 #define IRQ_ERROR 19 #define IRQ_SPURIOUS 31 diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..298066f --- /dev/null +++ b/uart.c @@ -0,0 +1,76 @@ +// Intel 8250 serial port (UART). + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "traps.h" +#include "spinlock.h" +#include "dev.h" +#include "mmu.h" +#include "proc.h" +#include "x86.h" + +#define COM1 0x3f8 + +static int uart; // is there a uart? + +void +uartinit(void) +{ + char *p; + + // Turn off the FIFO + outb(COM1+2, 0); + + // 9600 baud, 8 data bits, 1 stop bit, parity off. + outb(COM1+3, 0x80); // Unlock divisor + outb(COM1+0, 115200/9600); + outb(COM1+1, 0); + outb(COM1+3, 0x03); // Lock divisor, 8 data bits. + outb(COM1+4, 0); + outb(COM1+1, 0x01); // Enable receive interrupts. + + // If status is 0xFF, no serial port. + if(inb(COM1+5) == 0xFF) + return; + uart = 1; + + // Acknowledge pre-existing interrupt conditions; + // enable interrupts. + inb(COM1+2); + inb(COM1+0); + picenable(IRQ_COM1); + ioapicenable(IRQ_COM1, 0); + + // Announce that we're here. + for(p="xv6...\n"; *p; p++) + uartputc(*p); +} + +void +uartputc(int c) +{ + int i; + + if(!uart) + return; + for(i = 0; i < 128 && !(inb(COM1+5) & 0x20); i++) + microdelay(10); + outb(COM1+0, c); +} + +static int +uartgetc(void) +{ + if(!uart) + return -1; + if(!(inb(COM1+5) & 0x01)) + return -1; + return inb(COM1+0); +} + +void +uartintr(void) +{ + consoleintr(uartgetc); +}