summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsc <rsc>2009-05-31 00:24:11 +0000
committerrsc <rsc>2009-05-31 00:24:11 +0000
commit74afa70d3051553df46d1ea0d76149a7a86c0a47 (patch)
tree593b7b00869b161597d2d8b5af76ee09d4cc7c12
parent0ca9ca0c55922f72dbf324c4ac1aecf8069d1dbe (diff)
downloadxv6-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.c28
-rw-r--r--trap.c5
-rw-r--r--traps.h1
-rw-r--r--uart.c76
4 files changed, 87 insertions, 23 deletions
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);
+}