diff mbox

[3/3] kvm-unit-tests: make I/O more friendly to existing QEMU hardware

Message ID 1298584085-13129-4-git-send-email-aliguori@us.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Anthony Liguori Feb. 24, 2011, 9:48 p.m. UTC
None
diff mbox

Patch

diff --git a/lib/x86/io.c b/lib/x86/io.c
index 894f398..edc9437 100644
--- a/lib/x86/io.c
+++ b/lib/x86/io.c
@@ -1,13 +1,53 @@ 
 #include "libcflat.h"
 #include "smp.h"
+#include "io.h"
 
 static struct spinlock lock;
+static int serial_iobase = 0x3f8;
+static int serial_inited = 0;
+
+static void serial_outb(char ch)
+{
+        u8 lsr;
+
+        do {
+                lsr = inb(serial_iobase + 0x05);
+        } while (!(lsr & 0x20));
+
+        outb(ch, serial_iobase + 0x00);
+}
+
+static void serial_init(void)
+{
+        u8 lcr;
+
+        /* set DLAB */
+        lcr = inb(serial_iobase + 0x03);
+        lcr |= 0x80;
+        outb(lcr, serial_iobase + 0x03);
+
+        /* set baud rate to 115200 */
+        outb(0x01, serial_iobase + 0x00);
+        outb(0x00, serial_iobase + 0x01);
+
+        /* clear DLAB */
+        lcr = inb(serial_iobase + 0x03);
+        lcr &= ~0x80;
+        outb(lcr, serial_iobase + 0x03);
+}
 
 static void print_serial(const char *buf)
 {
 	unsigned long len = strlen(buf);
+        unsigned long i;
 
-	asm volatile ("rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1));
+        if (!serial_inited) {
+            serial_init();
+        }
+
+        for (i = 0; i < len; i++) {
+            serial_outb(buf[i]);
+        }
 }
 
 void puts(const char *s)
@@ -19,5 +59,14 @@  void puts(const char *s)
 
 void exit(int code)
 {
-        asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4));
+        static const char shutdown_str[8] = "Shutdown";
+        int i;
+
+        /* test device exit (with status) */
+        outl(code, 0xf4);
+
+        /* if that failed, try the Bochs poweroff port */
+        for (i = 0; i < 8; i++) {
+                outb(shutdown_str[i], 0x8900);
+        }
 }