[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/7] sercon: split-output implementation
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH 5/7] sercon: split-output implementation |
Date: |
Wed, 28 Sep 2016 11:07:18 +0200 |
Allows to run the serial console in parallel with a vga display.
Output will show up on both vga and serial line.
Input will be accepted from both keyboard and serial line.
Signed-off-by: Gerd Hoffmann <address@hidden>
---
src/optionroms.c | 2 ++
src/romlayout.S | 14 +++++++++
src/sercon.c | 95 ++++++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 91 insertions(+), 20 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 89b3784..a968e62 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -524,6 +524,20 @@ irqentry_arg:
DECL_IRQ_ENTRY hwpic1
DECL_IRQ_ENTRY hwpic2
+ // hooked int10, for sercon
+ DECLFUNC entry_10_hooked
+entry_10_hooked:
+ // Setup for iretw in irqentry_arg
+ pushfw
+ pushl %cs:sercon_int10_hook_resume
+
+ pushl $sercon_10_splitmode
+#if CONFIG_ENTRY_EXTRASTACK
+ jmp irqentry_arg_extrastack
+#else
+ jmp irqentry_arg
+#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 69b0c63..d9b6143 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 "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)
@@ -326,10 +347,7 @@ static void sercon_1001(struct bregs *regs)
/* 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 */
@@ -456,10 +474,47 @@ sercon_10(struct bregs *regs)
}
}
+void VISIBLE16
+sercon_10_splitmode(struct bregs *regs)
+{
+ if (!GET_LOW(sercon_port))
+ return;
+
+ switch (regs->ah) {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x08:
+ case 0x0f:
+ case 0x4f:
+ /* nothing, vgabios did all work */
+ break;
+ case 0x00: sercon_1000(regs); break;
+ case 0x06: sercon_1006(regs); break;
+ case 0x09: sercon_1009(regs); break;
+ case 0x0e: sercon_100e(regs); break;
+ default: sercon_10XX(regs); break;
+ }
+}
+
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
- [Qemu-devel] [PATCH 0/7] serial console support, Gerd Hoffmann, 2016/09/28
- [Qemu-devel] [PATCH 7/7] [hack] ignore sgabios, enable sercon instead, Gerd Hoffmann, 2016/09/28
- [Qemu-devel] [PATCH 6/7] sercon: add compile time option, Gerd Hoffmann, 2016/09/28
- [Qemu-devel] [PATCH 3/7] paravirt: read QEMU_CFG_NOGRAPHIC, store in etc/sercon-enable romfile, Gerd Hoffmann, 2016/09/28
- [Qemu-devel] [PATCH 1/7] std: add cp437 to unicode map, Gerd Hoffmann, 2016/09/28
- [Qemu-devel] [PATCH 4/7] add serial console support, Gerd Hoffmann, 2016/09/28
- [Qemu-devel] [PATCH 2/7] kbd: make enqueue_key public, add ascii_to_keycode, Gerd Hoffmann, 2016/09/28
- [Qemu-devel] [PATCH 5/7] sercon: split-output implementation,
Gerd Hoffmann <=