]> xenbits.xensource.com Git - osstest/rumprun.git/commitdiff
Serial console support for hw (x86) platform
authorMartin Lucina <martin@lucina.net>
Tue, 29 Sep 2015 10:13:23 +0000 (12:13 +0200)
committerMartin Lucina <martin@lucina.net>
Tue, 29 Sep 2015 14:54:42 +0000 (16:54 +0200)
Implement basic serial console (output-only, without interrupts) for
hw/x86. Console output defaults to VGA, serial console is only used when
the BIOS claims VGA is not present and a serial port is present.

platform/hw/arch/amd64/Makefile.inc
platform/hw/arch/i386/Makefile.inc
platform/hw/arch/x86/boot.c
platform/hw/arch/x86/cons.c [new file with mode: 0644]
platform/hw/arch/x86/serialcons.c [new file with mode: 0644]
platform/hw/arch/x86/vgacons.c
platform/hw/include/arch/x86/cons.h [new file with mode: 0644]
platform/hw/include/arch/x86/reg.h
platform/hw/include/hw/kernel.h

index c42dc6f9ac0ec53d94859c766e6fe063e9859e11..fc383854bd1bb231a6b52cb8424fd0056c45f279 100644 (file)
@@ -2,7 +2,7 @@ OBJS_BMK+=      arch/amd64/locore.o arch/amd64/intr.o
 OBJS_BMK+=     arch/amd64/machdep.o
 
 OBJS_BMK+=     arch/x86/boot.o
-OBJS_BMK+=     arch/x86/vgacons.o
+OBJS_BMK+=     arch/x86/cons.o arch/x86/vgacons.o arch/x86/serialcons.o
 OBJS_BMK+=     arch/x86/cpu_subr.o
 OBJS_BMK+=     arch/x86/x86_subr.o
 OBJS_BMK+=     arch/x86/clock.o
index 6f77f983c05cfa3d2788dc8e06ffb86854e5d216..f66720c9ff196aac3ab9047bc90c4f5325770c68 100644 (file)
@@ -1,7 +1,7 @@
 OBJS_BMK+=     arch/i386/locore.o arch/i386/machdep.o
 
 OBJS_BMK+=     arch/x86/boot.o
-OBJS_BMK+=     arch/x86/vgacons.o
+OBJS_BMK+=     arch/x86/cons.o arch/x86/vgacons.o arch/x86/serialcons.o
 OBJS_BMK+=     arch/x86/cpu_subr.o
 OBJS_BMK+=     arch/x86/x86_subr.o
 OBJS_BMK+=     arch/x86/clock.o
index 6f7ea7fa992f0b7954268ca987f7ab80f491c41e..fcedee1feb504c608836fc44b3c52e09c0852f2d 100644 (file)
@@ -35,7 +35,7 @@ void
 x86_boot(struct multiboot_info *mbi)
 {
 
-       bmk_printf_init(cons_putc, NULL);
+       cons_init();
        bmk_printf("rump kernel bare metal bootstrap\n\n");
 
        cpu_init();
diff --git a/platform/hw/arch/x86/cons.c b/platform/hw/arch/x86/cons.c
new file mode 100644 (file)
index 0000000..ae106ba
--- /dev/null
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2015 Martin Lucina.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <hw/types.h>
+#include <hw/kernel.h>
+
+#include <arch/x86/cons.h>
+
+#include <bmk-core/printf.h>
+
+static void (*vcons_putc)(int) = vgacons_putc;
+static uint16_t *bios_com1_base = (uint16_t *)BIOS_COM1_BASE;
+static uint16_t *bios_crtc_base = (uint16_t *)BIOS_CRTC_BASE;
+
+void
+cons_init(void)
+{
+
+       /*
+        * If the BIOS says no CRTC is present and a serial port is present,
+        * use the serial console. Otherwise use the VGA console.
+        */
+       if (*bios_crtc_base == 0 && *bios_com1_base != 0) {
+               serialcons_init(*bios_com1_base, 115200);
+               vcons_putc = serialcons_putc;
+       }
+       bmk_printf_init(vcons_putc, NULL);
+}
+
+void
+cons_putc(int c)
+{
+
+       vcons_putc(c);
+}
+
+void
+cons_puts(const char *s)
+{
+       int c;
+
+       while ((c = *s++) != 0)
+               vcons_putc(c);
+}
diff --git a/platform/hw/arch/x86/serialcons.c b/platform/hw/arch/x86/serialcons.c
new file mode 100644 (file)
index 0000000..d068182
--- /dev/null
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2015 Martin Lucina.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <hw/types.h>
+#include <hw/kernel.h>
+
+#include <arch/x86/cons.h>
+
+static uint16_t combase = 0;
+
+void
+serialcons_init(uint16_t combase_init, int speed)
+{
+       uint16_t divisor = 115200 / speed;
+
+       combase = combase_init;
+       outb(combase + COM_IER, 0x00);
+       outb(combase + COM_LCTL, 0x80);
+       outb(combase + COM_DLBL, divisor & 0xff);
+       outb(combase + COM_DLBH, divisor >> 8);
+       outb(combase + COM_LCTL, 0x03);
+       outb(combase + COM_FIFO, 0xc7);
+}
+
+void
+serialcons_putc(int c)
+{
+
+       if (!combase)
+               return;
+
+       /*
+        * Write a single character at a time, while the output FIFO has space.
+        */
+       while ((inb(combase + COM_LSR) & 0x20) == 0)
+               ;
+       outb(combase + COM_DATA, c);
+}
index 38d8ac22ee2517e11c5b40decf934c4855aedb96..11d7f603c48a895b3b5a1f3ccbef993b1e2b2cc6 100644 (file)
@@ -26,6 +26,8 @@
 #include <hw/types.h>
 #include <hw/kernel.h>
 
+#include <arch/x86/cons.h>
+
 #define CONS_MAGENTA 0x500
 static volatile uint16_t *cons_buf = (volatile uint16_t *)CONS_ADDRESS;
 
@@ -38,7 +40,7 @@ cons_putat(int c, int x, int y)
 
 /* display a character in the next available slot */
 void
-cons_putc(int c)
+vgacons_putc(int c)
 {
        static int cons_x;
        static int cons_y;
@@ -72,12 +74,3 @@ cons_putc(int c)
                        cons_putat(' ', x, cons_y);
        }
 }
-
-void
-cons_puts(const char *s)
-{
-       int c;
-
-       while ((c = *s++) != 0)
-               cons_putc(c);
-}
diff --git a/platform/hw/include/arch/x86/cons.h b/platform/hw/include/arch/x86/cons.h
new file mode 100644 (file)
index 0000000..152cdf2
--- /dev/null
@@ -0,0 +1,4 @@
+void serialcons_init(uint16_t, int);
+void serialcons_putc(int);
+void vgacons_putc(int);
+
index 63ca9c944261810065472565353fcd7c0c18d4fd..9a26b0a1cce92c9f1ec3045170c8d04f99f2fdd2 100644 (file)
 #define CONS_WIDTH     80
 #define CONS_HEIGHT    25
 #define CONS_ADDRESS   0xb8000
+
+#define COM_DATA       0
+#define COM_DLBL       0
+#define COM_DLBH       1
+#define COM_IER                1
+#define COM_FIFO       2
+#define COM_LCTL       3
+#define COM_LSR                5
+
+#define BIOS_COM1_BASE 0x400
+#define BIOS_CRTC_BASE 0x463
index e3a78960e3452276f5285805e972e5dfc22a8e44..7fc0012bcc3c83d7c4d124caf11ecf56991d1f72 100644 (file)
@@ -7,6 +7,7 @@
 struct multiboot_info;
 void multiboot(struct multiboot_info *);
 
+void cons_init(void);
 void cons_putc(int);
 void cons_puts(const char *);