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); +} | 
