diff options
author | rsc <rsc> | 2009-05-31 00:24:11 +0000 |
---|---|---|
committer | rsc <rsc> | 2009-05-31 00:24:11 +0000 |
commit | 74afa70d3051553df46d1ea0d76149a7a86c0a47 (patch) | |
tree | 593b7b00869b161597d2d8b5af76ee09d4cc7c12 | |
parent | 0ca9ca0c55922f72dbf324c4ac1aecf8069d1dbe (diff) | |
download | xv6-labs-74afa70d3051553df46d1ea0d76149a7a86c0a47.tar.gz xv6-labs-74afa70d3051553df46d1ea0d76149a7a86c0a47.tar.bz2 xv6-labs-74afa70d3051553df46d1ea0d76149a7a86c0a47.zip |
Add serial port input/output.
Delete parallel port output.
Works well with qemu -nographic mode.
-rw-r--r-- | console.c | 28 | ||||
-rw-r--r-- | trap.c | 5 | ||||
-rw-r--r-- | traps.h | 1 | ||||
-rw-r--r-- | uart.c | 76 |
4 files changed, 87 insertions, 23 deletions
@@ -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; @@ -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); @@ -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 @@ -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); +} |