summaryrefslogtreecommitdiff
path: root/uart.c
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 /uart.c
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.
Diffstat (limited to 'uart.c')
-rw-r--r--uart.c76
1 files changed, 76 insertions, 0 deletions
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);
+}