All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: seabios@seabios.org
Cc: qemu-devel@nongnu.org, Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH 5/5] [wip] sercon: initial split-output implementation
Date: Thu, 14 Jul 2016 10:53:02 +0200	[thread overview]
Message-ID: <1468486382-21609-6-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1468486382-21609-1-git-send-email-kraxel@redhat.com>

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 src/optionroms.c |  2 ++
 src/romlayout.S  | 39 ++++++++++++++++++++++
 src/sercon.c     | 99 +++++++++++++++++++++++++++++++++++++++-----------------
 3 files changed, 111 insertions(+), 29 deletions(-)

diff --git a/src/optionroms.c b/src/optionroms.c
index f9e9593..f08fcb1 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -442,6 +442,8 @@ vgarom_setup(void)
     }
 
     VgaROM = (void*)BUILD_ROM_START;
+    if (romfile_loadint("etc/sercon-enable", 0))
+        sercon_enable();
     enable_vga_console();
 }
 
diff --git a/src/romlayout.S b/src/romlayout.S
index 53cc0f5..2a645eb 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -522,6 +522,45 @@ irqentry_arg:
         DECL_IRQ_ENTRY hwpic1
         DECL_IRQ_ENTRY hwpic2
 
+        // hooked int10, for sercon
+        DECLFUNC entry_10_hooked
+entry_10_hooked:
+	pushl $ handle_10
+#if CONFIG_ENTRY_EXTRASTACK
+	// FIXME: too much cut+paste
+        cli
+        cld
+        pushw %ds               // Set %ds:%eax to space on ExtraStack
+        pushl %eax
+        movl $_zonelow_seg, %eax
+        movl %eax, %ds
+        movl StackPos, %eax
+        subl $PUSHBREGS_size+16, %eax
+        SAVEBREGS_POP_DSEAX     // Save registers on extra stack
+        popl %ecx
+        movl %esp, PUSHBREGS_size+8(%eax)
+        movw %ss, PUSHBREGS_size+12(%eax)
+        popl BREGS_code(%eax)
+        popw BREGS_flags(%eax)
+
+        movw %ds, %dx           // Setup %ss/%esp and call function
+        movw %dx, %ss
+        movl %eax, %esp
+        calll *%ecx
+
+        movl %esp, %eax         // Restore registers and return
+        movw PUSHBREGS_size+12(%eax), %ss
+        movl PUSHBREGS_size+8(%eax), %esp
+        popl %edx
+        popw %dx
+        pushw BREGS_flags(%eax)
+        pushl BREGS_code(%eax)
+        RESTOREBREGS_DSEAX
+        ljmpw *%cs:sercon_int10_hook_resume
+#else
+#error FIXME: CONFIG_ENTRY_EXTRASTACK=n not supported yet
+#endif
+
         // int 18/19 are special - they reset stack and call into 32bit mode.
         DECLFUNC entry_19
 entry_19:
diff --git a/src/sercon.c b/src/sercon.c
index c1cc738..4be7441 100644
--- a/src/sercon.c
+++ b/src/sercon.c
@@ -9,6 +9,7 @@
 #include "stacks.h" // yield
 #include "output.h" // dprintf
 #include "util.h" // irqtimer_calc_ticks
+#include "string.h" // memcpy
 #include "hw/serialio.h" // SEROFF_IER
 #include "std/cp437.h"
 
@@ -45,6 +46,8 @@ static void cursor_pos_set(u8 row, u8 col)
  ****************************************************************/
 
 VARLOW u16 sercon_port;
+VARLOW u8 sercon_split;
+VARFSEG struct segoff_s sercon_int10_hook_resume;
 
 /*
  * We have a small output buffer here, for lazy output.  That allows
@@ -64,6 +67,11 @@ VARLOW u8 sercon_attr = 0x07;
 
 static VAR16 u8 sercon_cmap[8] = { '0', '4', '2', '6', '1', '5', '3', '7' };
 
+static int sercon_splitmode(void)
+{
+    return GET_LOW(sercon_split);
+}
+
 static void sercon_putchar(u8 chr)
 {
     u16 addr = GET_LOW(sercon_port);
@@ -174,6 +182,15 @@ static void sercon_print_utf8(u8 chr)
     }
 }
 
+static void sercon_cursor_pos_set(u8 row, u8 col)
+{
+    if (!sercon_splitmode()) {
+        cursor_pos_set(row, col);
+    } else {
+        /* let vgabios update cursor */
+    }
+}
+
 static void sercon_lazy_cursor_sync(void)
 {
     u8 row = cursor_pos_row();
@@ -222,7 +239,7 @@ static void sercon_lazy_flush(void)
 
 static void sercon_lazy_cursor_update(u8 row, u8 col)
 {
-    cursor_pos_set(row, col);
+    sercon_cursor_pos_set(row, col);
     SET_LOW(sercon_row_last, row);
     SET_LOW(sercon_col_last, col);
 }
@@ -241,7 +258,7 @@ static void sercon_lazy_backspace(void)
 
 static void sercon_lazy_cr(void)
 {
-    cursor_pos_set(cursor_pos_row(), 0);
+    sercon_cursor_pos_set(cursor_pos_row(), 0);
 }
 
 static void sercon_lazy_lf(void)
@@ -256,7 +273,7 @@ static void sercon_lazy_lf(void)
             SET_LOW(sercon_row_last, GET_LOW(sercon_row_last) - 1);
         }
     }
-    cursor_pos_set(row, cursor_pos_col());
+    sercon_cursor_pos_set(row, cursor_pos_col());
 }
 
 static void sercon_lazy_move_cursor(void)
@@ -268,7 +285,7 @@ static void sercon_lazy_move_cursor(void)
         sercon_lazy_cr();
         sercon_lazy_lf();
     } else {
-        cursor_pos_set(cursor_pos_row(), col);
+        sercon_cursor_pos_set(cursor_pos_row(), col);
     }
 }
 
@@ -293,23 +310,27 @@ static void sercon_1000(struct bregs *regs)
     u8 mode = regs->al & 0x7f;
     u8 rows, cols;
 
-    switch (mode) {
-    case 0x03:
-    default:
-        cols = 80;
-        rows = 25;
-        regs->al = 0x30;
+    if (!sercon_splitmode()) {
+        switch (mode) {
+        case 0x03:
+        default:
+            cols = 80;
+            rows = 25;
+            regs->al = 0x30;
+        }
+        cursor_pos_set(0, 0);
+        SET_BDA(video_mode, mode);
+        SET_BDA(video_cols, cols);
+        SET_BDA(video_rows, rows-1);
+        SET_BDA(cursor_type, 0x0007);
+    } else {
+        /* let vgabios handle mode init */;
     }
+
     SET_LOW(sercon_col_last, 0);
     SET_LOW(sercon_row_last, 0);
     SET_LOW(sercon_attr_last, 0);
 
-    cursor_pos_set(0, 0);
-    SET_BDA(video_mode, mode);
-    SET_BDA(video_cols, cols);
-    SET_BDA(video_rows, rows-1);
-    SET_BDA(cursor_type, 0x0007);
-
     sercon_term_reset();
     sercon_term_no_linewrap();
     if (clearscreen)
@@ -320,24 +341,24 @@ static void sercon_1000(struct bregs *regs)
 static void sercon_1001(struct bregs *regs)
 {
     /* show/hide cursor? */
-    SET_BDA(cursor_type, regs->cx);
+    if (!sercon_splitmode())
+        SET_BDA(cursor_type, regs->cx);
 }
 
 /* Set cursor position */
 static void sercon_1002(struct bregs *regs)
 {
-    u8 row = regs->dh;
-    u8 col = regs->dl;
-
-    cursor_pos_set(row, col);
+    sercon_cursor_pos_set(regs->dh, regs->dl);
 }
 
 /* Get cursor position */
 static void sercon_1003(struct bregs *regs)
 {
-    regs->cx = GET_BDA(cursor_type);
-    regs->dh = cursor_pos_row();
-    regs->dl = cursor_pos_col();
+    if (!sercon_splitmode()) {
+        regs->cx = GET_BDA(cursor_type);
+        regs->dh = cursor_pos_row();
+        regs->dl = cursor_pos_col();
+    }
 }
 
 /* Scroll up window */
@@ -362,8 +383,10 @@ static void sercon_1006(struct bregs *regs)
 /* Read character and attribute at cursor position */
 static void sercon_1008(struct bregs *regs)
 {
-    regs->ah = 0x07;
-    regs->bh = ' ';
+    if (!sercon_splitmode()) {
+        regs->ah = 0x07;
+        regs->bh = ' ';
+    }
 }
 
 /* Write character and attribute at cursor position */
@@ -420,14 +443,18 @@ static void sercon_100e(struct bregs *regs)
 /* Get current video mode */
 static void sercon_100f(struct bregs *regs)
 {
-    regs->al = GET_BDA(video_mode);
-    regs->ah = GET_BDA(video_cols);
+    if (!sercon_splitmode()) {
+        regs->al = GET_BDA(video_mode);
+        regs->ah = GET_BDA(video_cols);
+    }
 }
 
 /* VBE 2.0 */
 static void sercon_104f(struct bregs *regs)
 {
-    regs->ax = 0x0100;
+    if (!sercon_splitmode()) {
+        regs->ax = 0x0100;
+    }
 }
 
 static void sercon_10XX(struct bregs *regs)
@@ -458,8 +485,22 @@ sercon_10(struct bregs *regs)
 
 void sercon_enable(void)
 {
+    struct segoff_s seabios, vgabios;
     u16 addr = PORT_SERIAL1;
 
+    vgabios = GET_IVT(0x10);
+    seabios = FUNC16(entry_10);
+    if (vgabios.seg != seabios.seg ||
+        vgabios.offset != seabios.offset) {
+        dprintf(1, "%s:%d: using splitmode (vgabios %04x:%04x, hook %04x:%04x)\n",
+                __func__, __LINE__,
+                vgabios.seg, vgabios.offset,
+                seabios.seg, seabios.offset);
+        sercon_int10_hook_resume = vgabios;
+        SET_IVT(0x10, FUNC16(entry_10_hooked));
+        SET_LOW(sercon_split, 1);
+    }
+
     SET_LOW(sercon_port, addr);
     outb(0x03, addr + SEROFF_LCR); // 8N1
     outb(0x01, addr + 0x02);       // enable fifo
-- 
1.8.3.1

  parent reply	other threads:[~2016-07-14  8:53 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-14  8:52 [Qemu-devel] [PATCH 0/5] serial console support Gerd Hoffmann
2016-07-14  8:52 ` [Qemu-devel] [PATCH 1/5] std: add cp437 to unicode map Gerd Hoffmann
2016-07-14 16:17   ` [Qemu-devel] [SeaBIOS] " Kevin O'Connor
2016-07-14  8:52 ` [Qemu-devel] [PATCH 2/5] kbd: make enqueue_key public, add ascii_to_keycode Gerd Hoffmann
2016-07-14  8:53 ` [Qemu-devel] [PATCH 3/5] paravirt: read QEMU_CFG_NOGRAPHIC, store in etc/sercon-enable romfile Gerd Hoffmann
2016-07-14  8:53 ` [Qemu-devel] [PATCH 4/5] add serial console support Gerd Hoffmann
2016-07-14  8:53 ` Gerd Hoffmann [this message]
2016-07-14 16:15   ` [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation Kevin O'Connor
2016-07-15 11:49     ` Gerd Hoffmann
2016-07-15 14:35       ` Kevin O'Connor
2016-08-08 13:14         ` Gerd Hoffmann
2016-09-27 12:00         ` Gerd Hoffmann
2016-10-04  3:03           ` Kevin O'Connor
2016-10-04  8:49             ` Gerd Hoffmann
2016-10-04  9:21               ` Igor Mammedov
2016-10-13  7:17                 ` Gerd Hoffmann
2016-10-13  8:09                   ` Igor Mammedov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1468486382-21609-6-git-send-email-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=seabios@seabios.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.