All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/5] serial console support
@ 2016-07-14  8:52 Gerd Hoffmann
  2016-07-14  8:52 ` [Qemu-devel] [PATCH 1/5] std: add cp437 to unicode map Gerd Hoffmann
                   ` (4 more replies)
  0 siblings, 5 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2016-07-14  8:52 UTC (permalink / raw)
  To: seabios; +Cc: qemu-devel, Gerd Hoffmann

  Hi,

Next round of serial console patches,  Still not ready to merge.

Headline feature of this version is split mode (i.e. output on both vga
and serial).  Have a initial working implementation now, logic is
simliar to the vgabios timer hook (as suggested by Kevin).

Also changed the output logic, down to a one-cell buffer (char+attr) for
output.  Cursor updates are simply written to BDA now, with the actual
move being done lazily when printing the next character or checking for
keyboard input.  That is especially useful for splitmode as we can
simply skip the cursor position updates and let the vgabios do them
instead.

TODO list:
  * compile time (CONFIG_*) option.
  * input handling cleanups.
  * implement missing int10h functions.
  * more testing.

cheers,
  Gerd

Gerd Hoffmann (5):
  std: add cp437 to unicode map
  kbd: make enqueue_key public, add ascii_to_keycode
  paravirt: read QEMU_CFG_NOGRAPHIC, store in etc/sercon-enable romfile
  add serial console support
  [wip] sercon: initial split-output implementation

 Makefile          |   7 +-
 src/clock.c       |   1 +
 src/fw/paravirt.c |   2 +
 src/kbd.c         |  17 +-
 src/misc.c        |   2 +
 src/optionroms.c  |   9 +-
 src/romlayout.S   |  39 ++++
 src/sercon.c      | 621 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/std/cp437.c   | 275 ++++++++++++++++++++++++
 src/std/cp437.h   |   1 +
 src/util.h        |   5 +
 11 files changed, 974 insertions(+), 5 deletions(-)
 create mode 100644 src/sercon.c
 create mode 100644 src/std/cp437.c
 create mode 100644 src/std/cp437.h

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 1/5] std: add cp437 to unicode map
  2016-07-14  8:52 [Qemu-devel] [PATCH 0/5] serial console support Gerd Hoffmann
@ 2016-07-14  8:52 ` 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
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2016-07-14  8:52 UTC (permalink / raw)
  To: seabios; +Cc: qemu-devel, Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile        |   5 +-
 src/std/cp437.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/std/cp437.h |   1 +
 3 files changed, 279 insertions(+), 2 deletions(-)
 create mode 100644 src/std/cp437.c
 create mode 100644 src/std/cp437.h

diff --git a/Makefile b/Makefile
index 4930b3a..c11efe6 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,8 @@ SRCBOTH=misc.c stacks.c output.c string.c block.c cdrom.c disk.c mouse.c kbd.c \
     hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \
     hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \
     hw/blockcmd.c hw/floppy.c hw/ata.c hw/ramdisk.c \
-    hw/lsi-scsi.c hw/esp-scsi.c hw/megasas.c hw/mpt-scsi.c
+    hw/lsi-scsi.c hw/esp-scsi.c hw/megasas.c hw/mpt-scsi.c \
+    std/cp437.c
 SRC16=$(SRCBOTH)
 SRC32FLAT=$(SRCBOTH) post.c e820map.c malloc.c romfile.c x86.c optionroms.c \
     pmm.c font.c boot.c bootsplash.c jpeg.c bmp.c tcgbios.c sha1.c \
@@ -45,7 +46,7 @@ SRC32FLAT=$(SRCBOTH) post.c e820map.c malloc.c romfile.c x86.c optionroms.c \
     hw/virtio-ring.c hw/virtio-pci.c hw/virtio-blk.c hw/virtio-scsi.c \
     hw/tpm_drivers.c
 SRC32SEG=string.c output.c pcibios.c apm.c stacks.c hw/pci.c hw/serialio.c
-DIRS=src src/hw src/fw vgasrc
+DIRS=src src/hw src/fw src/std vgasrc
 
 # Default compiler flags
 cc-option=$(shell if test -z "`$(1) $(2) -S -o /dev/null -xc /dev/null 2>&1`" \
diff --git a/src/std/cp437.c b/src/std/cp437.c
new file mode 100644
index 0000000..3918eaa
--- /dev/null
+++ b/src/std/cp437.c
@@ -0,0 +1,275 @@
+/*
+ * code page 437 to unicode map
+ */
+
+#include "types.h"
+#include "biosvar.h"
+#include "std/cp437.h"
+
+static VAR16 u16 cp437_to_unicode_map[256] = {
+
+    /* https://en.wikipedia.org/wiki/Code_page_437 */
+    [ 0x00 ] = 0x0000,
+    [ 0x01 ] = 0x263A,
+    [ 0x02 ] = 0x263B,
+    [ 0x03 ] = 0x2665,
+    [ 0x04 ] = 0x2666,
+    [ 0x05 ] = 0x2663,
+    [ 0x06 ] = 0x2660,
+    [ 0x07 ] = 0x2022,
+    [ 0x08 ] = 0x25D8,
+    [ 0x09 ] = 0x25CB,
+    [ 0x0a ] = 0x25D9,
+    [ 0x0b ] = 0x2642,
+    [ 0x0c ] = 0x2640,
+    [ 0x0d ] = 0x266A,
+    [ 0x0e ] = 0x266B,
+    [ 0x0f ] = 0x263C,
+    [ 0x10 ] = 0x25BA,
+    [ 0x11 ] = 0x25C4,
+    [ 0x12 ] = 0x2195,
+    [ 0x13 ] = 0x203C,
+    [ 0x14 ] = 0x00B6,
+    [ 0x15 ] = 0x00A7,
+    [ 0x16 ] = 0x25AC,
+    [ 0x17 ] = 0x21A8,
+    [ 0x18 ] = 0x2191,
+    [ 0x19 ] = 0x2193,
+    [ 0x1a ] = 0x2192,
+    [ 0x1b ] = 0x2190,
+    [ 0x1c ] = 0x221F,
+    [ 0x1d ] = 0x2194,
+    [ 0x1e ] = 0x25B2,
+    [ 0x1f ] = 0x25BC,
+    [ 0x7f ] = 0x2302,
+
+    /* http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT */
+    [ 0x20 ] = 0x0020, //  SPACE
+    [ 0x21 ] = 0x0021, //  EXCLAMATION MARK
+    [ 0x22 ] = 0x0022, //  QUOTATION MARK
+    [ 0x23 ] = 0x0023, //  NUMBER SIGN
+    [ 0x24 ] = 0x0024, //  DOLLAR SIGN
+    [ 0x25 ] = 0x0025, //  PERCENT SIGN
+    [ 0x26 ] = 0x0026, //  AMPERSAND
+    [ 0x27 ] = 0x0027, //  APOSTROPHE
+    [ 0x28 ] = 0x0028, //  LEFT PARENTHESIS
+    [ 0x29 ] = 0x0029, //  RIGHT PARENTHESIS
+    [ 0x2a ] = 0x002a, //  ASTERISK
+    [ 0x2b ] = 0x002b, //  PLUS SIGN
+    [ 0x2c ] = 0x002c, //  COMMA
+    [ 0x2d ] = 0x002d, //  HYPHEN-MINUS
+    [ 0x2e ] = 0x002e, //  FULL STOP
+    [ 0x2f ] = 0x002f, //  SOLIDUS
+    [ 0x30 ] = 0x0030, //  DIGIT ZERO
+    [ 0x31 ] = 0x0031, //  DIGIT ONE
+    [ 0x32 ] = 0x0032, //  DIGIT TWO
+    [ 0x33 ] = 0x0033, //  DIGIT THREE
+    [ 0x34 ] = 0x0034, //  DIGIT FOUR
+    [ 0x35 ] = 0x0035, //  DIGIT FIVE
+    [ 0x36 ] = 0x0036, //  DIGIT SIX
+    [ 0x37 ] = 0x0037, //  DIGIT SEVEN
+    [ 0x38 ] = 0x0038, //  DIGIT EIGHT
+    [ 0x39 ] = 0x0039, //  DIGIT NINE
+    [ 0x3a ] = 0x003a, //  COLON
+    [ 0x3b ] = 0x003b, //  SEMICOLON
+    [ 0x3c ] = 0x003c, //  LESS-THAN SIGN
+    [ 0x3d ] = 0x003d, //  EQUALS SIGN
+    [ 0x3e ] = 0x003e, //  GREATER-THAN SIGN
+    [ 0x3f ] = 0x003f, //  QUESTION MARK
+    [ 0x40 ] = 0x0040, //  COMMERCIAL AT
+    [ 0x41 ] = 0x0041, //  LATIN CAPITAL LETTER A
+    [ 0x42 ] = 0x0042, //  LATIN CAPITAL LETTER B
+    [ 0x43 ] = 0x0043, //  LATIN CAPITAL LETTER C
+    [ 0x44 ] = 0x0044, //  LATIN CAPITAL LETTER D
+    [ 0x45 ] = 0x0045, //  LATIN CAPITAL LETTER E
+    [ 0x46 ] = 0x0046, //  LATIN CAPITAL LETTER F
+    [ 0x47 ] = 0x0047, //  LATIN CAPITAL LETTER G
+    [ 0x48 ] = 0x0048, //  LATIN CAPITAL LETTER H
+    [ 0x49 ] = 0x0049, //  LATIN CAPITAL LETTER I
+    [ 0x4a ] = 0x004a, //  LATIN CAPITAL LETTER J
+    [ 0x4b ] = 0x004b, //  LATIN CAPITAL LETTER K
+    [ 0x4c ] = 0x004c, //  LATIN CAPITAL LETTER L
+    [ 0x4d ] = 0x004d, //  LATIN CAPITAL LETTER M
+    [ 0x4e ] = 0x004e, //  LATIN CAPITAL LETTER N
+    [ 0x4f ] = 0x004f, //  LATIN CAPITAL LETTER O
+    [ 0x50 ] = 0x0050, //  LATIN CAPITAL LETTER P
+    [ 0x51 ] = 0x0051, //  LATIN CAPITAL LETTER Q
+    [ 0x52 ] = 0x0052, //  LATIN CAPITAL LETTER R
+    [ 0x53 ] = 0x0053, //  LATIN CAPITAL LETTER S
+    [ 0x54 ] = 0x0054, //  LATIN CAPITAL LETTER T
+    [ 0x55 ] = 0x0055, //  LATIN CAPITAL LETTER U
+    [ 0x56 ] = 0x0056, //  LATIN CAPITAL LETTER V
+    [ 0x57 ] = 0x0057, //  LATIN CAPITAL LETTER W
+    [ 0x58 ] = 0x0058, //  LATIN CAPITAL LETTER X
+    [ 0x59 ] = 0x0059, //  LATIN CAPITAL LETTER Y
+    [ 0x5a ] = 0x005a, //  LATIN CAPITAL LETTER Z
+    [ 0x5b ] = 0x005b, //  LEFT SQUARE BRACKET
+    [ 0x5c ] = 0x005c, //  REVERSE SOLIDUS
+    [ 0x5d ] = 0x005d, //  RIGHT SQUARE BRACKET
+    [ 0x5e ] = 0x005e, //  CIRCUMFLEX ACCENT
+    [ 0x5f ] = 0x005f, //  LOW LINE
+    [ 0x60 ] = 0x0060, //  GRAVE ACCENT
+    [ 0x61 ] = 0x0061, //  LATIN SMALL LETTER A
+    [ 0x62 ] = 0x0062, //  LATIN SMALL LETTER B
+    [ 0x63 ] = 0x0063, //  LATIN SMALL LETTER C
+    [ 0x64 ] = 0x0064, //  LATIN SMALL LETTER D
+    [ 0x65 ] = 0x0065, //  LATIN SMALL LETTER E
+    [ 0x66 ] = 0x0066, //  LATIN SMALL LETTER F
+    [ 0x67 ] = 0x0067, //  LATIN SMALL LETTER G
+    [ 0x68 ] = 0x0068, //  LATIN SMALL LETTER H
+    [ 0x69 ] = 0x0069, //  LATIN SMALL LETTER I
+    [ 0x6a ] = 0x006a, //  LATIN SMALL LETTER J
+    [ 0x6b ] = 0x006b, //  LATIN SMALL LETTER K
+    [ 0x6c ] = 0x006c, //  LATIN SMALL LETTER L
+    [ 0x6d ] = 0x006d, //  LATIN SMALL LETTER M
+    [ 0x6e ] = 0x006e, //  LATIN SMALL LETTER N
+    [ 0x6f ] = 0x006f, //  LATIN SMALL LETTER O
+    [ 0x70 ] = 0x0070, //  LATIN SMALL LETTER P
+    [ 0x71 ] = 0x0071, //  LATIN SMALL LETTER Q
+    [ 0x72 ] = 0x0072, //  LATIN SMALL LETTER R
+    [ 0x73 ] = 0x0073, //  LATIN SMALL LETTER S
+    [ 0x74 ] = 0x0074, //  LATIN SMALL LETTER T
+    [ 0x75 ] = 0x0075, //  LATIN SMALL LETTER U
+    [ 0x76 ] = 0x0076, //  LATIN SMALL LETTER V
+    [ 0x77 ] = 0x0077, //  LATIN SMALL LETTER W
+    [ 0x78 ] = 0x0078, //  LATIN SMALL LETTER X
+    [ 0x79 ] = 0x0079, //  LATIN SMALL LETTER Y
+    [ 0x7a ] = 0x007a, //  LATIN SMALL LETTER Z
+    [ 0x7b ] = 0x007b, //  LEFT CURLY BRACKET
+    [ 0x7c ] = 0x007c, //  VERTICAL LINE
+    [ 0x7d ] = 0x007d, //  RIGHT CURLY BRACKET
+    [ 0x7e ] = 0x007e, //  TILDE
+    [ 0x80 ] = 0x00c7, //  LATIN CAPITAL LETTER C WITH CEDILLA
+    [ 0x81 ] = 0x00fc, //  LATIN SMALL LETTER U WITH DIAERESIS
+    [ 0x82 ] = 0x00e9, //  LATIN SMALL LETTER E WITH ACUTE
+    [ 0x83 ] = 0x00e2, //  LATIN SMALL LETTER A WITH CIRCUMFLEX
+    [ 0x84 ] = 0x00e4, //  LATIN SMALL LETTER A WITH DIAERESIS
+    [ 0x85 ] = 0x00e0, //  LATIN SMALL LETTER A WITH GRAVE
+    [ 0x86 ] = 0x00e5, //  LATIN SMALL LETTER A WITH RING ABOVE
+    [ 0x87 ] = 0x00e7, //  LATIN SMALL LETTER C WITH CEDILLA
+    [ 0x88 ] = 0x00ea, //  LATIN SMALL LETTER E WITH CIRCUMFLEX
+    [ 0x89 ] = 0x00eb, //  LATIN SMALL LETTER E WITH DIAERESIS
+    [ 0x8a ] = 0x00e8, //  LATIN SMALL LETTER E WITH GRAVE
+    [ 0x8b ] = 0x00ef, //  LATIN SMALL LETTER I WITH DIAERESIS
+    [ 0x8c ] = 0x00ee, //  LATIN SMALL LETTER I WITH CIRCUMFLEX
+    [ 0x8d ] = 0x00ec, //  LATIN SMALL LETTER I WITH GRAVE
+    [ 0x8e ] = 0x00c4, //  LATIN CAPITAL LETTER A WITH DIAERESIS
+    [ 0x8f ] = 0x00c5, //  LATIN CAPITAL LETTER A WITH RING ABOVE
+    [ 0x90 ] = 0x00c9, //  LATIN CAPITAL LETTER E WITH ACUTE
+    [ 0x91 ] = 0x00e6, //  LATIN SMALL LIGATURE AE
+    [ 0x92 ] = 0x00c6, //  LATIN CAPITAL LIGATURE AE
+    [ 0x93 ] = 0x00f4, //  LATIN SMALL LETTER O WITH CIRCUMFLEX
+    [ 0x94 ] = 0x00f6, //  LATIN SMALL LETTER O WITH DIAERESIS
+    [ 0x95 ] = 0x00f2, //  LATIN SMALL LETTER O WITH GRAVE
+    [ 0x96 ] = 0x00fb, //  LATIN SMALL LETTER U WITH CIRCUMFLEX
+    [ 0x97 ] = 0x00f9, //  LATIN SMALL LETTER U WITH GRAVE
+    [ 0x98 ] = 0x00ff, //  LATIN SMALL LETTER Y WITH DIAERESIS
+    [ 0x99 ] = 0x00d6, //  LATIN CAPITAL LETTER O WITH DIAERESIS
+    [ 0x9a ] = 0x00dc, //  LATIN CAPITAL LETTER U WITH DIAERESIS
+    [ 0x9b ] = 0x00a2, //  CENT SIGN
+    [ 0x9c ] = 0x00a3, //  POUND SIGN
+    [ 0x9d ] = 0x00a5, //  YEN SIGN
+    [ 0x9e ] = 0x20a7, //  PESETA SIGN
+    [ 0x9f ] = 0x0192, //  LATIN SMALL LETTER F WITH HOOK
+    [ 0xa0 ] = 0x00e1, //  LATIN SMALL LETTER A WITH ACUTE
+    [ 0xa1 ] = 0x00ed, //  LATIN SMALL LETTER I WITH ACUTE
+    [ 0xa2 ] = 0x00f3, //  LATIN SMALL LETTER O WITH ACUTE
+    [ 0xa3 ] = 0x00fa, //  LATIN SMALL LETTER U WITH ACUTE
+    [ 0xa4 ] = 0x00f1, //  LATIN SMALL LETTER N WITH TILDE
+    [ 0xa5 ] = 0x00d1, //  LATIN CAPITAL LETTER N WITH TILDE
+    [ 0xa6 ] = 0x00aa, //  FEMININE ORDINAL INDICATOR
+    [ 0xa7 ] = 0x00ba, //  MASCULINE ORDINAL INDICATOR
+    [ 0xa8 ] = 0x00bf, //  INVERTED QUESTION MARK
+    [ 0xa9 ] = 0x2310, //  REVERSED NOT SIGN
+    [ 0xaa ] = 0x00ac, //  NOT SIGN
+    [ 0xab ] = 0x00bd, //  VULGAR FRACTION ONE HALF
+    [ 0xac ] = 0x00bc, //  VULGAR FRACTION ONE QUARTER
+    [ 0xad ] = 0x00a1, //  INVERTED EXCLAMATION MARK
+    [ 0xae ] = 0x00ab, //  LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    [ 0xaf ] = 0x00bb, //  RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    [ 0xb0 ] = 0x2591, //  LIGHT SHADE
+    [ 0xb1 ] = 0x2592, //  MEDIUM SHADE
+    [ 0xb2 ] = 0x2593, //  DARK SHADE
+    [ 0xb3 ] = 0x2502, //  BOX DRAWINGS LIGHT VERTICAL
+    [ 0xb4 ] = 0x2524, //  BOX DRAWINGS LIGHT VERTICAL AND LEFT
+    [ 0xb5 ] = 0x2561, //  BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+    [ 0xb6 ] = 0x2562, //  BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+    [ 0xb7 ] = 0x2556, //  BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+    [ 0xb8 ] = 0x2555, //  BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+    [ 0xb9 ] = 0x2563, //  BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+    [ 0xba ] = 0x2551, //  BOX DRAWINGS DOUBLE VERTICAL
+    [ 0xbb ] = 0x2557, //  BOX DRAWINGS DOUBLE DOWN AND LEFT
+    [ 0xbc ] = 0x255d, //  BOX DRAWINGS DOUBLE UP AND LEFT
+    [ 0xbd ] = 0x255c, //  BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+    [ 0xbe ] = 0x255b, //  BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+    [ 0xbf ] = 0x2510, //  BOX DRAWINGS LIGHT DOWN AND LEFT
+    [ 0xc0 ] = 0x2514, //  BOX DRAWINGS LIGHT UP AND RIGHT
+    [ 0xc1 ] = 0x2534, //  BOX DRAWINGS LIGHT UP AND HORIZONTAL
+    [ 0xc2 ] = 0x252c, //  BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+    [ 0xc3 ] = 0x251c, //  BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+    [ 0xc4 ] = 0x2500, //  BOX DRAWINGS LIGHT HORIZONTAL
+    [ 0xc5 ] = 0x253c, //  BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+    [ 0xc6 ] = 0x255e, //  BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+    [ 0xc7 ] = 0x255f, //  BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+    [ 0xc8 ] = 0x255a, //  BOX DRAWINGS DOUBLE UP AND RIGHT
+    [ 0xc9 ] = 0x2554, //  BOX DRAWINGS DOUBLE DOWN AND RIGHT
+    [ 0xca ] = 0x2569, //  BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+    [ 0xcb ] = 0x2566, //  BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+    [ 0xcc ] = 0x2560, //  BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+    [ 0xcd ] = 0x2550, //  BOX DRAWINGS DOUBLE HORIZONTAL
+    [ 0xce ] = 0x256c, //  BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+    [ 0xcf ] = 0x2567, //  BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+    [ 0xd0 ] = 0x2568, //  BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+    [ 0xd1 ] = 0x2564, //  BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+    [ 0xd2 ] = 0x2565, //  BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+    [ 0xd3 ] = 0x2559, //  BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+    [ 0xd4 ] = 0x2558, //  BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+    [ 0xd5 ] = 0x2552, //  BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+    [ 0xd6 ] = 0x2553, //  BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+    [ 0xd7 ] = 0x256b, //  BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+    [ 0xd8 ] = 0x256a, //  BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+    [ 0xd9 ] = 0x2518, //  BOX DRAWINGS LIGHT UP AND LEFT
+    [ 0xda ] = 0x250c, //  BOX DRAWINGS LIGHT DOWN AND RIGHT
+    [ 0xdb ] = 0x2588, //  FULL BLOCK
+    [ 0xdc ] = 0x2584, //  LOWER HALF BLOCK
+    [ 0xdd ] = 0x258c, //  LEFT HALF BLOCK
+    [ 0xde ] = 0x2590, //  RIGHT HALF BLOCK
+    [ 0xdf ] = 0x2580, //  UPPER HALF BLOCK
+    [ 0xe0 ] = 0x03b1, //  GREEK SMALL LETTER ALPHA
+    [ 0xe1 ] = 0x00df, //  LATIN SMALL LETTER SHARP S
+    [ 0xe2 ] = 0x0393, //  GREEK CAPITAL LETTER GAMMA
+    [ 0xe3 ] = 0x03c0, //  GREEK SMALL LETTER PI
+    [ 0xe4 ] = 0x03a3, //  GREEK CAPITAL LETTER SIGMA
+    [ 0xe5 ] = 0x03c3, //  GREEK SMALL LETTER SIGMA
+    [ 0xe6 ] = 0x00b5, //  MICRO SIGN
+    [ 0xe7 ] = 0x03c4, //  GREEK SMALL LETTER TAU
+    [ 0xe8 ] = 0x03a6, //  GREEK CAPITAL LETTER PHI
+    [ 0xe9 ] = 0x0398, //  GREEK CAPITAL LETTER THETA
+    [ 0xea ] = 0x03a9, //  GREEK CAPITAL LETTER OMEGA
+    [ 0xeb ] = 0x03b4, //  GREEK SMALL LETTER DELTA
+    [ 0xec ] = 0x221e, //  INFINITY
+    [ 0xed ] = 0x03c6, //  GREEK SMALL LETTER PHI
+    [ 0xee ] = 0x03b5, //  GREEK SMALL LETTER EPSILON
+    [ 0xef ] = 0x2229, //  INTERSECTION
+    [ 0xf0 ] = 0x2261, //  IDENTICAL TO
+    [ 0xf1 ] = 0x00b1, //  PLUS-MINUS SIGN
+    [ 0xf2 ] = 0x2265, //  GREATER-THAN OR EQUAL TO
+    [ 0xf3 ] = 0x2264, //  LESS-THAN OR EQUAL TO
+    [ 0xf4 ] = 0x2320, //  TOP HALF INTEGRAL
+    [ 0xf5 ] = 0x2321, //  BOTTOM HALF INTEGRAL
+    [ 0xf6 ] = 0x00f7, //  DIVISION SIGN
+    [ 0xf7 ] = 0x2248, //  ALMOST EQUAL TO
+    [ 0xf8 ] = 0x00b0, //  DEGREE SIGN
+    [ 0xf9 ] = 0x2219, //  BULLET OPERATOR
+    [ 0xfa ] = 0x00b7, //  MIDDLE DOT
+    [ 0xfb ] = 0x221a, //  SQUARE ROOT
+    [ 0xfc ] = 0x207f, //  SUPERSCRIPT LATIN SMALL LETTER N
+    [ 0xfd ] = 0x00b2, //  SUPERSCRIPT TWO
+    [ 0xfe ] = 0x25a0, //  BLACK SQUARE
+    [ 0xff ] = 0x00a0, //  NO-BREAK SPACE
+};
+
+u16 cp437_to_unicode(u8 cp437)
+{
+    return GET_GLOBAL(cp437_to_unicode_map[cp437]);
+}
diff --git a/src/std/cp437.h b/src/std/cp437.h
new file mode 100644
index 0000000..7bd1ef1
--- /dev/null
+++ b/src/std/cp437.h
@@ -0,0 +1 @@
+u16 cp437_to_unicode(u8 cp437);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 2/5] kbd: make enqueue_key public, add ascii_to_keycode
  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  8:52 ` 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
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2016-07-14  8:52 UTC (permalink / raw)
  To: seabios; +Cc: qemu-devel, Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 src/kbd.c  | 17 ++++++++++++++++-
 src/util.h |  2 ++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/kbd.c b/src/kbd.c
index 61d9df0..7c43129 100644
--- a/src/kbd.c
+++ b/src/kbd.c
@@ -51,7 +51,7 @@ kbd_init(void)
             , x + FIELD_SIZEOF(struct bios_data_area_s, kbd_buf));
 }
 
-static u8
+u8
 enqueue_key(u16 keycode)
 {
     u16 buffer_start = GET_BDA(kbd_buf_start_offset);
@@ -376,6 +376,21 @@ static struct scaninfo {
     { 0x8600, 0x8800, 0x8a00, 0x8c00 }, /* F12 */
 };
 
+u16 ascii_to_keycode(u8 ascii)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(scan_to_keycode); i++) {
+        if ((GET_GLOBAL(scan_to_keycode[i].normal) & 0xff) == ascii)
+            return GET_GLOBAL(scan_to_keycode[i].normal);
+        if ((GET_GLOBAL(scan_to_keycode[i].shift) & 0xff) == ascii)
+            return GET_GLOBAL(scan_to_keycode[i].shift);
+        if ((GET_GLOBAL(scan_to_keycode[i].control) & 0xff) == ascii)
+            return GET_GLOBAL(scan_to_keycode[i].control);
+    }
+    return 0;
+}
+
 // Handle a ps2 style scancode read from the keyboard.
 static void
 __process_key(u8 scancode)
diff --git a/src/util.h b/src/util.h
index 7bfd2b8..f461795 100644
--- a/src/util.h
+++ b/src/util.h
@@ -185,6 +185,8 @@ int jpeg_show(struct jpeg_decdata *jpeg, unsigned char *pic, int width
 void kbd_init(void);
 void handle_15c2(struct bregs *regs);
 void process_key(u8 key);
+u8 enqueue_key(u16 keycode);
+u16 ascii_to_keycode(u8 ascii);
 
 // misc.c
 extern int HaveRunPost;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 3/5] paravirt: read QEMU_CFG_NOGRAPHIC, store in etc/sercon-enable romfile
  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  8:52 ` [Qemu-devel] [PATCH 2/5] kbd: make enqueue_key public, add ascii_to_keycode Gerd Hoffmann
@ 2016-07-14  8:53 ` Gerd Hoffmann
  2016-07-14  8:53 ` [Qemu-devel] [PATCH 4/5] add serial console support Gerd Hoffmann
  2016-07-14  8:53 ` [Qemu-devel] [PATCH 5/5] [wip] sercon: initial split-output implementation Gerd Hoffmann
  4 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2016-07-14  8:53 UTC (permalink / raw)
  To: seabios; +Cc: qemu-devel, Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 src/fw/paravirt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c
index 73a08f0..d18d247 100644
--- a/src/fw/paravirt.c
+++ b/src/fw/paravirt.c
@@ -201,6 +201,7 @@ qemu_platform_setup(void)
 #define QEMU_CFG_SIGNATURE              0x00
 #define QEMU_CFG_ID                     0x01
 #define QEMU_CFG_UUID                   0x02
+#define QEMU_CFG_NOGRAPHIC              0x04
 #define QEMU_CFG_NUMA                   0x0d
 #define QEMU_CFG_BOOT_MENU              0x0e
 #define QEMU_CFG_MAX_CPUS               0x0f
@@ -418,6 +419,7 @@ qemu_cfg_legacy(void)
     qemu_romfile_add("etc/show-boot-menu", QEMU_CFG_BOOT_MENU, 0, 2);
     qemu_romfile_add("etc/irq0-override", QEMU_CFG_IRQ0_OVERRIDE, 0, 1);
     qemu_romfile_add("etc/max-cpus", QEMU_CFG_MAX_CPUS, 0, 2);
+    qemu_romfile_add("etc/sercon-enable", QEMU_CFG_NOGRAPHIC, 0, 2);
 
     // NUMA data
     u64 numacount;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 4/5] add serial console support
  2016-07-14  8:52 [Qemu-devel] [PATCH 0/5] serial console support Gerd Hoffmann
                   ` (2 preceding siblings ...)
  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 ` Gerd Hoffmann
  2016-07-14  8:53 ` [Qemu-devel] [PATCH 5/5] [wip] sercon: initial split-output implementation Gerd Hoffmann
  4 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2016-07-14  8:53 UTC (permalink / raw)
  To: seabios; +Cc: qemu-devel, Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile         |   2 +-
 src/clock.c      |   1 +
 src/misc.c       |   2 +
 src/optionroms.c |   7 +-
 src/sercon.c     | 580 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/util.h       |   3 +
 6 files changed, 593 insertions(+), 2 deletions(-)
 create mode 100644 src/sercon.c

diff --git a/Makefile b/Makefile
index c11efe6..62b323f 100644
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,7 @@ LD32BIT_FLAG:=-melf_i386
 
 # Source files
 SRCBOTH=misc.c stacks.c output.c string.c block.c cdrom.c disk.c mouse.c kbd.c \
-    system.c serial.c clock.c resume.c pnpbios.c vgahooks.c pcibios.c apm.c \
+    system.c serial.c sercon.c clock.c resume.c pnpbios.c vgahooks.c pcibios.c apm.c \
     hw/pci.c hw/timer.c hw/rtc.c hw/dma.c hw/pic.c hw/ps2port.c hw/serialio.c \
     hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \
     hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \
diff --git a/src/clock.c b/src/clock.c
index e83e0f3..e44e112 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -295,6 +295,7 @@ clock_update(void)
     floppy_tick();
     usb_check_event();
     ps2_check_event();
+    sercon_check_event();
 }
 
 // INT 08h System Timer ISR Entry Point
diff --git a/src/misc.c b/src/misc.c
index f02237c..f4b656d 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -11,6 +11,7 @@
 #include "output.h" // debug_enter
 #include "stacks.h" // call16_int
 #include "string.h" // memset
+#include "util.h" // serial_10
 
 #define PORT_MATH_CLEAR        0x00f0
 
@@ -57,6 +58,7 @@ handle_10(struct bregs *regs)
 {
     debug_enter(regs, DEBUG_HDL_10);
     // don't do anything, since the VGA BIOS handles int10h requests
+    sercon_10(regs);
 }
 
 // NMI handler
diff --git a/src/optionroms.c b/src/optionroms.c
index 65f7fe0..f9e9593 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -432,9 +432,14 @@ vgarom_setup(void)
     run_file_roms("vgaroms/", 1, NULL);
     rom_reserve(0);
 
-    if (rom_get_last() == BUILD_ROM_START)
+    if (rom_get_last() == BUILD_ROM_START) {
         // No VGA rom found
+        if (romfile_loadint("etc/sercon-enable", 0)) {
+            sercon_enable();
+            enable_vga_console();
+        }
         return;
+    }
 
     VgaROM = (void*)BUILD_ROM_START;
     enable_vga_console();
diff --git a/src/sercon.c b/src/sercon.c
new file mode 100644
index 0000000..c1cc738
--- /dev/null
+++ b/src/sercon.c
@@ -0,0 +1,580 @@
+// serial console support
+//
+// Copyright (C) 2016 Gerd Hoffmann <kraxel@redhat.com>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // SET_BDA
+#include "bregs.h" // struct bregs
+#include "stacks.h" // yield
+#include "output.h" // dprintf
+#include "util.h" // irqtimer_calc_ticks
+#include "hw/serialio.h" // SEROFF_IER
+#include "std/cp437.h"
+
+static u8 video_rows(void)
+{
+    return GET_BDA(video_rows)+1;
+}
+
+static u8 video_cols(void)
+{
+    return GET_BDA(video_cols);
+}
+
+static u8 cursor_pos_col(void)
+{
+    u16 pos = GET_BDA(cursor_pos[0]);
+    return pos & 0xff;
+}
+
+static u8 cursor_pos_row(void)
+{
+    u16 pos = GET_BDA(cursor_pos[0]);
+    return (pos >> 8) & 0xff;
+}
+
+static void cursor_pos_set(u8 row, u8 col)
+{
+    u16 pos = ((u16)row << 8) | col;
+    SET_BDA(cursor_pos[0], pos);
+}
+
+/****************************************************************
+ * serial console output
+ ****************************************************************/
+
+VARLOW u16 sercon_port;
+
+/*
+ * We have a small output buffer here, for lazy output.  That allows
+ * to avoid a whole bunch of control sequences for pointless cursor
+ * moves, so when logging the output it'll be *alot* less cluttered.
+ *
+ * sercon_char/attr  is the actual output buffer.
+ * sercon_attr_last  is the most recent attribute sent to the terminal.
+ * sercon_col_last   is the most recent column sent to the terminal.
+ * sercon_row_last   is the most recent row sent to the terminal.
+ */
+VARLOW u8 sercon_attr_last;
+VARLOW u8 sercon_col_last;
+VARLOW u8 sercon_row_last;
+VARLOW u8 sercon_char;
+VARLOW u8 sercon_attr = 0x07;
+
+static VAR16 u8 sercon_cmap[8] = { '0', '4', '2', '6', '1', '5', '3', '7' };
+
+static void sercon_putchar(u8 chr)
+{
+    u16 addr = GET_LOW(sercon_port);
+    u32 end = irqtimer_calc_ticks(0x0a);
+
+#if 0
+    /* for visual control sequence debugging */
+    if (chr == '\x1b')
+        chr = '*';
+#endif
+
+    for (;;) {
+        u8 lsr = inb(addr+SEROFF_LSR);
+        if ((lsr & 0x60) == 0x60) {
+            // Success - can write data
+            outb(chr, addr+SEROFF_DATA);
+            break;
+        }
+        if (irqtimer_check(end)) {
+            break;
+        }
+        yield();
+    }
+}
+
+static void sercon_term_reset(void)
+{
+    sercon_putchar('\x1b');
+    sercon_putchar('c');
+}
+
+static void sercon_term_clear_screen(void)
+{
+    sercon_putchar('\x1b');
+    sercon_putchar('[');
+    sercon_putchar('2');
+    sercon_putchar('J');
+}
+
+static void sercon_term_no_linewrap(void)
+{
+    sercon_putchar('\x1b');
+    sercon_putchar('[');
+    sercon_putchar('?');
+    sercon_putchar('7');
+    sercon_putchar('l');
+}
+
+static void sercon_term_cursor_goto(u8 row, u8 col)
+{
+    row++; col++;
+    sercon_putchar('\x1b');
+    sercon_putchar('[');
+    sercon_putchar('0' + row / 10);
+    sercon_putchar('0' + row % 10);
+    sercon_putchar(';');
+    sercon_putchar('0' + col / 10);
+    sercon_putchar('0' + col % 10);
+    sercon_putchar('H');
+}
+
+static void sercon_term_set_color(u8 fg, u8 bg, u8 bold)
+{
+    sercon_putchar('\x1b');
+    sercon_putchar('[');
+    sercon_putchar('0');
+    if (fg != 7) {
+        sercon_putchar(';');
+        sercon_putchar('3');
+        sercon_putchar(GET_GLOBAL(sercon_cmap[fg & 7]));
+    }
+    if (bg != 0) {
+        sercon_putchar(';');
+        sercon_putchar('4');
+        sercon_putchar(GET_GLOBAL(sercon_cmap[bg & 7]));
+    }
+    if (bold) {
+        sercon_putchar(';');
+        sercon_putchar('1');
+    }
+    sercon_putchar('m');
+}
+
+static void sercon_set_attr(u8 attr)
+{
+    if (attr == GET_LOW(sercon_attr_last))
+        return;
+
+    SET_LOW(sercon_attr_last, attr);
+    sercon_term_set_color((attr >> 0) & 7,
+                          (attr >> 4) & 7,
+                          attr & 0x08);
+}
+
+static void sercon_print_utf8(u8 chr)
+{
+    u16 unicode = cp437_to_unicode(chr);
+
+    if (unicode < 0x7f) {
+        sercon_putchar(unicode);
+    } else if (unicode < 0x7ff) {
+        sercon_putchar(0xc0 | ((unicode >>  6) & 0x1f));
+        sercon_putchar(0x80 | ((unicode >>  0) & 0x3f));
+    } else {
+        sercon_putchar(0xe0 | ((unicode >> 12) & 0x0f));
+        sercon_putchar(0x80 | ((unicode >>  6) & 0x3f));
+        sercon_putchar(0x80 | ((unicode >>  0) & 0x3f));
+    }
+}
+
+static void sercon_lazy_cursor_sync(void)
+{
+    u8 row = cursor_pos_row();
+    u8 col = cursor_pos_col();
+
+    if (GET_LOW(sercon_row_last) == row &&
+        GET_LOW(sercon_col_last) == col)
+        return;
+
+    if (col == 0 && GET_LOW(sercon_row_last) <= row) {
+        if (GET_LOW(sercon_col_last) != 0) {
+            sercon_putchar('\r');
+            SET_LOW(sercon_col_last, 0);
+        }
+        while (GET_LOW(sercon_row_last) < row) {
+            sercon_putchar('\n');
+            SET_LOW(sercon_row_last, GET_LOW(sercon_row_last)+1);
+        }
+        if (GET_LOW(sercon_row_last) == row &&
+            GET_LOW(sercon_col_last) == col)
+            return;
+    }
+
+    sercon_term_cursor_goto(row, col);
+    SET_LOW(sercon_row_last, row);
+    SET_LOW(sercon_col_last, col);
+}
+
+static void sercon_lazy_flush(void)
+{
+    u8 chr, attr;
+
+    chr = GET_LOW(sercon_char);
+    attr = GET_LOW(sercon_attr);
+    if (chr) {
+        sercon_set_attr(attr);
+        sercon_print_utf8(chr);
+        SET_LOW(sercon_col_last, GET_LOW(sercon_col_last) + 1);
+    }
+
+    sercon_lazy_cursor_sync();
+
+    SET_LOW(sercon_attr, 0x07);
+    SET_LOW(sercon_char, 0x00);
+}
+
+static void sercon_lazy_cursor_update(u8 row, u8 col)
+{
+    cursor_pos_set(row, col);
+    SET_LOW(sercon_row_last, row);
+    SET_LOW(sercon_col_last, col);
+}
+
+static void sercon_lazy_backspace(void)
+{
+    u8 col;
+
+    sercon_lazy_flush();
+    col = cursor_pos_col();
+    if (col > 0) {
+        sercon_putchar(8);
+        sercon_lazy_cursor_update(cursor_pos_row(), col-1);
+    }
+}
+
+static void sercon_lazy_cr(void)
+{
+    cursor_pos_set(cursor_pos_row(), 0);
+}
+
+static void sercon_lazy_lf(void)
+{
+    u8 row;
+
+    row = cursor_pos_row() + 1;
+    if (row >= video_rows()) {
+        /* scrolling up */
+        row = video_rows()-1;
+        if (GET_LOW(sercon_row_last) > 0) {
+            SET_LOW(sercon_row_last, GET_LOW(sercon_row_last) - 1);
+        }
+    }
+    cursor_pos_set(row, cursor_pos_col());
+}
+
+static void sercon_lazy_move_cursor(void)
+{
+    u8 col;
+
+    col = cursor_pos_col() + 1;
+    if (col >= video_cols()) {
+        sercon_lazy_cr();
+        sercon_lazy_lf();
+    } else {
+        cursor_pos_set(cursor_pos_row(), col);
+    }
+}
+
+static void sercon_lazy_putchar(u8 chr, u8 attr, u8 teletype)
+{
+    if (cursor_pos_row() != GET_LOW(sercon_row_last) ||
+        cursor_pos_col() != GET_LOW(sercon_col_last)) {
+        sercon_lazy_flush();
+    }
+
+    SET_LOW(sercon_char, chr);
+    if (teletype)
+        sercon_lazy_move_cursor();
+    else
+        SET_LOW(sercon_attr, attr);
+}
+
+/* Set video mode */
+static void sercon_1000(struct bregs *regs)
+{
+    u8 clearscreen = !(regs->al & 0x80);
+    u8 mode = regs->al & 0x7f;
+    u8 rows, cols;
+
+    switch (mode) {
+    case 0x03:
+    default:
+        cols = 80;
+        rows = 25;
+        regs->al = 0x30;
+    }
+    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)
+        sercon_term_clear_screen();
+}
+
+/* Set text-mode cursor shape */
+static void sercon_1001(struct bregs *regs)
+{
+    /* show/hide cursor? */
+    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);
+}
+
+/* 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();
+}
+
+/* Scroll up window */
+static void sercon_1006(struct bregs *regs)
+{
+    sercon_lazy_flush();
+    if (regs->al == 0) {
+        /* clear rect, do only in case this looks like a fullscreen clear */
+        if (regs->ch == 0 &&
+            regs->cl == 0 &&
+            regs->dh == video_rows()-1 &&
+            regs->dl == video_cols()-1) {
+            sercon_set_attr(regs->bh);
+            sercon_term_clear_screen();
+        }
+    } else {
+        sercon_putchar('\r');
+        sercon_putchar('\n');
+    }
+}
+
+/* Read character and attribute at cursor position */
+static void sercon_1008(struct bregs *regs)
+{
+    regs->ah = 0x07;
+    regs->bh = ' ';
+}
+
+/* Write character and attribute at cursor position */
+static void sercon_1009(struct bregs *regs)
+{
+    u16 count = regs->cx;
+
+    if (count == 1) {
+        sercon_lazy_putchar(regs->al, regs->bl, 0);
+
+    } else if (regs->al == 0x20 &&
+               video_rows() * video_cols() == count &&
+               cursor_pos_row() == 0 &&
+               cursor_pos_col() == 0) {
+        /* override everything with spaces -> this is clear screen */
+        sercon_lazy_flush();
+        sercon_set_attr(regs->bl);
+        sercon_term_clear_screen();
+
+    } else {
+        sercon_lazy_flush();
+        sercon_set_attr(regs->bl);
+        while (count) {
+            sercon_print_utf8(regs->al);
+            count--;
+        }
+        sercon_term_cursor_goto(cursor_pos_row(),
+                                cursor_pos_col());
+    }
+}
+
+/* Teletype output */
+static void sercon_100e(struct bregs *regs)
+{
+    switch (regs->al) {
+    case 7:
+        sercon_putchar(0x07);
+        break;
+    case 8:
+        sercon_lazy_backspace();
+        break;
+    case '\r':
+        sercon_lazy_cr();
+        break;
+    case '\n':
+        sercon_lazy_lf();
+        break;
+    default:
+        sercon_lazy_putchar(regs->al, 0, 1);
+        break;
+    }
+}
+
+/* Get current video mode */
+static void sercon_100f(struct bregs *regs)
+{
+    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;
+}
+
+static void sercon_10XX(struct bregs *regs)
+{
+    warn_unimplemented(regs);
+}
+
+void VISIBLE16
+sercon_10(struct bregs *regs)
+{
+    if (!GET_LOW(sercon_port))
+        return;
+
+    switch (regs->ah) {
+    case 0x00: sercon_1000(regs); break;
+    case 0x01: sercon_1001(regs); break;
+    case 0x02: sercon_1002(regs); break;
+    case 0x03: sercon_1003(regs); break;
+    case 0x06: sercon_1006(regs); break;
+    case 0x08: sercon_1008(regs); break;
+    case 0x09: sercon_1009(regs); break;
+    case 0x0e: sercon_100e(regs); break;
+    case 0x0f: sercon_100f(regs); break;
+    case 0x4f: sercon_104f(regs); break;
+    default:   sercon_10XX(regs); break;
+    }
+}
+
+void sercon_enable(void)
+{
+    u16 addr = PORT_SERIAL1;
+
+    SET_LOW(sercon_port, addr);
+    outb(0x03, addr + SEROFF_LCR); // 8N1
+    outb(0x01, addr + 0x02);       // enable fifo
+}
+
+/****************************************************************
+ * serial input
+ ****************************************************************/
+
+VARLOW u8 rx_buf[16];
+VARLOW u8 rx_bytes;
+
+static VAR16 struct {
+    char seq[4];
+    u8   len;
+    u16  keycode;
+} termseq[] = {
+    { .seq = "OP",   .len = 2, .keycode = 0x3b00 },    // F1
+    { .seq = "OQ",   .len = 2, .keycode = 0x3c00 },    // F2
+    { .seq = "OR",   .len = 2, .keycode = 0x3d00 },    // F3
+    { .seq = "OS",   .len = 2, .keycode = 0x3e00 },    // F4
+
+    { .seq = "[15~", .len = 4, .keycode = 0x3f00 },    // F5
+    { .seq = "[17~", .len = 4, .keycode = 0x4000 },    // F6
+    { .seq = "[18~", .len = 4, .keycode = 0x4100 },    // F7
+    { .seq = "[19~", .len = 4, .keycode = 0x4200 },    // F8
+    { .seq = "[20~", .len = 4, .keycode = 0x4300 },    // F9
+    { .seq = "[21~", .len = 4, .keycode = 0x4400 },    // F10
+    { .seq = "[23~", .len = 4, .keycode = 0x5700 },    // F11
+    { .seq = "[24~", .len = 4, .keycode = 0x5800 },    // F12
+
+    { .seq = "[2~",  .len = 3, .keycode = 0x52e0 },    // insert
+    { .seq = "[3~",  .len = 3, .keycode = 0x53e0 },    // delete
+    { .seq = "[5~",  .len = 3, .keycode = 0x49e0 },    // page up
+    { .seq = "[6~",  .len = 3, .keycode = 0x51e0 },    // page down
+
+    { .seq = "[A",   .len = 2, .keycode = 0x48e0 },    // up
+    { .seq = "[B",   .len = 2, .keycode = 0x50e0 },    // down
+    { .seq = "[C",   .len = 2, .keycode = 0x4de0 },    // right
+    { .seq = "[D",   .len = 2, .keycode = 0x4be0 },    // left
+
+    { .seq = "[H",   .len = 2, .keycode = 0x47e0 },    // home
+    { .seq = "[F",   .len = 2, .keycode = 0x4fe0 },    // end
+};
+
+static void shiftbuf(int remove)
+{
+    int i, remaining;
+
+    remaining = GET_LOW(rx_bytes) - remove;
+    SET_LOW(rx_bytes, remaining);
+    for (i = 0; i < remaining; i++)
+        SET_LOW(rx_buf[i], GET_LOW(rx_buf[i + remove]));
+}
+
+void
+sercon_check_event(void)
+{
+    u16 addr = GET_LOW(sercon_port);
+    u16 keycode;
+    u8 byte, count = 0;
+    int seq, chr, len;
+
+    // check to see if there is a active serial port
+    if (!addr)
+        return;
+    if (inb(addr + SEROFF_LSR) == 0xFF)
+        return;
+
+    // flush pending output
+    sercon_lazy_flush();
+
+    // read all available data
+    while (inb(addr + SEROFF_LSR) & 0x01) {
+        byte = inb(addr + SEROFF_DATA);
+        if (GET_LOW(rx_bytes) < sizeof(rx_buf)) {
+            SET_LOW(rx_buf[rx_bytes], byte);
+            SET_LOW(rx_bytes, GET_LOW(rx_bytes) + 1);
+            count++;
+        }
+    }
+
+next_char:
+    // no (more) input data
+    if (!GET_LOW(rx_bytes))
+        return;
+
+    // lookup escape sequences
+    if (GET_LOW(rx_bytes) > 1 && GET_LOW(rx_buf[0]) == 0x1b) {
+        for (seq = 0; seq < ARRAY_SIZE(termseq); seq++) {
+            len = GET_GLOBAL(termseq[seq].len);
+            if (GET_LOW(rx_bytes) < len + 1)
+                continue;
+            for (chr = 0; chr < len; chr++) {
+                if (GET_GLOBAL(termseq[seq].seq[chr]) != GET_LOW(rx_buf[chr + 1]))
+                    break;
+            }
+            if (chr == len) {
+                enqueue_key(GET_GLOBAL(termseq[seq].keycode));
+                shiftbuf(len + 1);
+                goto next_char;
+            }
+        }
+    }
+
+    // Seems we got a escape sequence we didn't recognise.
+    //  -> If we received data wait for more, maybe it is just incomplete.
+    if (GET_LOW(rx_buf[0]) == 0x1b && count)
+        return;
+
+    // Handle input as individual chars.
+    chr = GET_LOW(rx_buf[0]);
+    keycode = ascii_to_keycode(chr);
+    if (keycode)
+        enqueue_key(keycode);
+    shiftbuf(1);
+    goto next_char;
+}
diff --git a/src/util.h b/src/util.h
index f461795..51df4ec 100644
--- a/src/util.h
+++ b/src/util.h
@@ -233,6 +233,9 @@ void code_mutable_preinit(void);
 // serial.c
 void serial_setup(void);
 void lpt_setup(void);
+void sercon_10(struct bregs *regs);
+void sercon_enable(void);
+void sercon_check_event(void);
 
 // vgahooks.c
 void handle_155f(struct bregs *regs);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 5/5] [wip] sercon: initial split-output implementation
  2016-07-14  8:52 [Qemu-devel] [PATCH 0/5] serial console support Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2016-07-14  8:53 ` [Qemu-devel] [PATCH 4/5] add serial console support Gerd Hoffmann
@ 2016-07-14  8:53 ` Gerd Hoffmann
  2016-07-14 16:15   ` [Qemu-devel] [SeaBIOS] " Kevin O'Connor
  4 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2016-07-14  8:53 UTC (permalink / raw)
  To: seabios; +Cc: qemu-devel, Gerd Hoffmann

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

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  2016-07-14  8:53 ` [Qemu-devel] [PATCH 5/5] [wip] sercon: initial split-output implementation Gerd Hoffmann
@ 2016-07-14 16:15   ` Kevin O'Connor
  2016-07-15 11:49     ` Gerd Hoffmann
  0 siblings, 1 reply; 17+ messages in thread
From: Kevin O'Connor @ 2016-07-14 16:15 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: seabios, qemu-devel

On Thu, Jul 14, 2016 at 10:53:02AM +0200, Gerd Hoffmann wrote:
> 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();

Minor nit, but why not unconditionally call sercon_enable() and let
sercon_enable() check romfile_loadint().

[...]
> --- 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

I'm okay with the cut-and-paste.  But, another option would be to use
the iretw at the end of the existing irqentry_extrastack to implement
the ljmpw into the main vgabios.  Something like (totally untested):

entry_10_hooked:
        pushfw                          // Setup for iretw in irqentry_arg
        pushl %cs:sercon_int10_hook_resume

        pushl $handle_10
#if CONFIG_ENTRY_EXTRASTACK
        jmp irqentry_arg_extrastack
#else
        jmp irqentry_arg
#endif

Separately, have you considered choosing a separate entry point for
entry_10_hooked.  That is, changing the above pushl to
$handle_sercon_hooked and introducing that function in sercon.c.  It
seems it would reduce a number of "if (!sercon_splitmode())" checks in
the main code, as handle_sercon_hooked() could just use a smaller
switch statement and ignore requests it doesn't need to support.

Finally, one high level observation is that we know there are a number
of quirks in various vgabios emulators.  For example, we know some
emulators don't handle certain 32bit instructions when in 16bit mode
(hence scripts/vgafixup.py), we know some versions of Windows use an
emulator that doesn't like some stack relative instructions (hence the
vgabios is compiled without -fomit-frame-pointer), and we know Windows
Vista doesn't like the extra stack in high ram (the skifree bug).  Any
thoughts on what happens with these quirks if the main seabios code
hooks int10?

-Kevin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 1/5] std: add cp437 to unicode map
  2016-07-14  8:52 ` [Qemu-devel] [PATCH 1/5] std: add cp437 to unicode map Gerd Hoffmann
@ 2016-07-14 16:17   ` Kevin O'Connor
  0 siblings, 0 replies; 17+ messages in thread
From: Kevin O'Connor @ 2016-07-14 16:17 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: seabios, qemu-devel

On Thu, Jul 14, 2016 at 10:52:58AM +0200, Gerd Hoffmann wrote:
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  Makefile        |   5 +-
>  src/std/cp437.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/std/cp437.h |   1 +
>  3 files changed, 279 insertions(+), 2 deletions(-)
>  create mode 100644 src/std/cp437.c
>  create mode 100644 src/std/cp437.h
> 
> diff --git a/Makefile b/Makefile
> index 4930b3a..c11efe6 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -34,7 +34,8 @@ SRCBOTH=misc.c stacks.c output.c string.c block.c cdrom.c disk.c mouse.c kbd.c \
>      hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \
>      hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \
>      hw/blockcmd.c hw/floppy.c hw/ata.c hw/ramdisk.c \
> -    hw/lsi-scsi.c hw/esp-scsi.c hw/megasas.c hw/mpt-scsi.c
> +    hw/lsi-scsi.c hw/esp-scsi.c hw/megasas.c hw/mpt-scsi.c \
> +    std/cp437.c

Lets put this file in src/ instead of src/std/.  (I think of std/ as a
location for published BIOS interface standards.)

Otherwise, looks good.

-Kevin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  2016-07-14 16:15   ` [Qemu-devel] [SeaBIOS] " Kevin O'Connor
@ 2016-07-15 11:49     ` Gerd Hoffmann
  2016-07-15 14:35       ` Kevin O'Connor
  0 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2016-07-15 11:49 UTC (permalink / raw)
  To: Kevin O'Connor; +Cc: seabios, qemu-devel

  Hi,

> I'm okay with the cut-and-paste.  But, another option would be to use
> the iretw at the end of the existing irqentry_extrastack to implement
> the ljmpw into the main vgabios.  Something like (totally untested):
> 
> entry_10_hooked:
>         pushfw                          // Setup for iretw in irqentry_arg
>         pushl %cs:sercon_int10_hook_resume
> 
>         pushl $handle_10
> #if CONFIG_ENTRY_EXTRASTACK
>         jmp irqentry_arg_extrastack
> #else
>         jmp irqentry_arg
> #endif

Good idea, I'll try it.

> Separately, have you considered choosing a separate entry point for
> entry_10_hooked.  That is, changing the above pushl to
> $handle_sercon_hooked and introducing that function in sercon.c.  It
> seems it would reduce a number of "if (!sercon_splitmode())" checks in
> the main code, as handle_sercon_hooked() could just use a smaller
> switch statement and ignore requests it doesn't need to support.

Makes sense indeed.  All functions which only return information are not
needed in the splitmode case.

> Finally, one high level observation is that we know there are a number
> of quirks in various vgabios emulators.  For example, we know some
> emulators don't handle certain 32bit instructions when in 16bit mode
> (hence scripts/vgafixup.py), we know some versions of Windows use an
> emulator that doesn't like some stack relative instructions (hence the
> vgabios is compiled without -fomit-frame-pointer), and we know Windows
> Vista doesn't like the extra stack in high ram (the skifree bug).  Any
> thoughts on what happens with these quirks if the main seabios code
> hooks int10?

Good question.  Do the emulators (both win, xorg) use the int10 vector
set by seabios in the first place?  Or go they load the vgabios and run
it, including the initialization, and use whatever entry point the init
code sets up?  I suspect it is the latter.  But needs investigation and
testing.

/me places the item on the todo list.

Also a serial console for windows guests isn't that useful, so I
wouldn't worry too much about windows emulator issues.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  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
  0 siblings, 2 replies; 17+ messages in thread
From: Kevin O'Connor @ 2016-07-15 14:35 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: seabios, qemu-devel

On Fri, Jul 15, 2016 at 01:49:49PM +0200, Gerd Hoffmann wrote:
> > Finally, one high level observation is that we know there are a number
> > of quirks in various vgabios emulators.  For example, we know some
> > emulators don't handle certain 32bit instructions when in 16bit mode
> > (hence scripts/vgafixup.py), we know some versions of Windows use an
> > emulator that doesn't like some stack relative instructions (hence the
> > vgabios is compiled without -fomit-frame-pointer), and we know Windows
> > Vista doesn't like the extra stack in high ram (the skifree bug).  Any
> > thoughts on what happens with these quirks if the main seabios code
> > hooks int10?
> 
> Good question.  Do the emulators (both win, xorg) use the int10 vector
> set by seabios in the first place?  Or go they load the vgabios and run
> it, including the initialization, and use whatever entry point the init
> code sets up?  I suspect it is the latter.  But needs investigation and
> testing.

I think they just call the existing int10 handler.  In general, it's
not safe to rerun the vga init code.  Also, if they did run the init
it would lead to extra copies of the SeaVGABIOS version banners in the
debug logs, which I don't recall seeing.

> Also a serial console for windows guests isn't that useful, so I
> wouldn't worry too much about windows emulator issues.

It's not uncommon (at least on real hardware) to add sgabios to a
system for the boot menus, but then use a regular OS at runtime.  The
problem with the vga emulation quirks is that they often result in
mysterious system failures.

Have you considered implementing the serial support as a kind of
"serial seavgabios" instead of directly in seabios?  That would have
the advantage of pulling in all the existing vgabios quirk handling.

-Kevin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  2016-07-15 14:35       ` Kevin O'Connor
@ 2016-08-08 13:14         ` Gerd Hoffmann
  2016-09-27 12:00         ` Gerd Hoffmann
  1 sibling, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2016-08-08 13:14 UTC (permalink / raw)
  To: Kevin O'Connor; +Cc: seabios, qemu-devel

  Hi,

Short status update:  Project isn't dead.  But I'm busy with other stuff
and that will not change in August due to holiday season and kvm forum,
so don't expect new patches from me before September.

For anyone who wants play with this:  Pushed my current devel branch to
https://www.kraxel.org/cgit/seabios/log/?h=serial (basically the most
recent patch series with some not-yet squashed incremental fixes on
top).

> Have you considered implementing the serial support as a kind of
> "serial seavgabios" instead of directly in seabios?  That would have
> the advantage of pulling in all the existing vgabios quirk handling.

Indeed, didn't consider that yet.

Briefly looked at this a while back, figured doing this as "serial
seavgabios" would allow the reuse of some vgabios code.  On the other
hand the keyboard handling is easier to do directly in seabios: can
queue key events using internal seabios interfaces, no need to hook
timer irq (or better serial irq?).

I've noticed you've cleaned up vgabios a bit, possibly with the
intention to make implementing a serial seavgabios easier?  In case you
want give it a try:  Feel free to grab my branch and run with it.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  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
  1 sibling, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2016-09-27 12:00 UTC (permalink / raw)
  To: Kevin O'Connor; +Cc: seabios, qemu-devel

On Fr, 2016-07-15 at 10:35 -0400, Kevin O'Connor wrote:
> On Fri, Jul 15, 2016 at 01:49:49PM +0200, Gerd Hoffmann wrote:
> > > Finally, one high level observation is that we know there are a number
> > > of quirks in various vgabios emulators.  For example, we know some
> > > emulators don't handle certain 32bit instructions when in 16bit mode
> > > (hence scripts/vgafixup.py), we know some versions of Windows use an
> > > emulator that doesn't like some stack relative instructions (hence the
> > > vgabios is compiled without -fomit-frame-pointer), and we know Windows
> > > Vista doesn't like the extra stack in high ram (the skifree bug).  Any
> > > thoughts on what happens with these quirks if the main seabios code
> > > hooks int10?
> > 
> > Good question.  Do the emulators (both win, xorg) use the int10 vector
> > set by seabios in the first place?  Or go they load the vgabios and run
> > it, including the initialization, and use whatever entry point the init
> > code sets up?  I suspect it is the latter.  But needs investigation and
> > testing.
> 
> I think they just call the existing int10 handler.  In general, it's
> not safe to rerun the vga init code.  Also, if they did run the init
> it would lead to extra copies of the SeaVGABIOS version banners in the
> debug logs, which I don't recall seeing.

Finally found the time to continue with this and ran a bunch of tests.
RHEL-5 (known to be affected by x86emu issue) continues to work fine.
Xorg server log looks like it goes scan memory for the vgabios instead
of depending on the int10 vector:

(II) VESA(0): initializing int10
(II) VESA(0): Primary V_BIOS segment is: 0xc000
(II) VESA(0): VESA BIOS detected
(II) VESA(0): VESA VBE Version 3.0
(II) VESA(0): VESA VBE Total Mem: 16384 kB
(II) VESA(0): VESA VBE OEM: SeaBIOS VBE(C) 2011
(II) VESA(0): VESA VBE OEM Software Rev: 0.0
(II) VESA(0): VESA VBE OEM Vendor: SeaBIOS Developers
(II) VESA(0): VESA VBE OEM Product: SeaBIOS VBE Adapter
(II) VESA(0): VESA VBE OEM Product Rev: Rev. 1

Running tests with win7 doesn't show any problems too, so I suspect they
are basically doing the same.

Given these results I think I'll stick to the current approach of
integrating this directly into seabios (instead of creating a
sgabios-like rom using the seavgabios sources).

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  2016-09-27 12:00         ` Gerd Hoffmann
@ 2016-10-04  3:03           ` Kevin O'Connor
  2016-10-04  8:49             ` Gerd Hoffmann
  0 siblings, 1 reply; 17+ messages in thread
From: Kevin O'Connor @ 2016-10-04  3:03 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: seabios, qemu-devel

On Tue, Sep 27, 2016 at 02:00:08PM +0200, Gerd Hoffmann wrote:
> On Fr, 2016-07-15 at 10:35 -0400, Kevin O'Connor wrote:
> > On Fri, Jul 15, 2016 at 01:49:49PM +0200, Gerd Hoffmann wrote:
> > > > Finally, one high level observation is that we know there are a number
> > > > of quirks in various vgabios emulators.  For example, we know some
> > > > emulators don't handle certain 32bit instructions when in 16bit mode
> > > > (hence scripts/vgafixup.py), we know some versions of Windows use an
> > > > emulator that doesn't like some stack relative instructions (hence the
> > > > vgabios is compiled without -fomit-frame-pointer), and we know Windows
> > > > Vista doesn't like the extra stack in high ram (the skifree bug).  Any
> > > > thoughts on what happens with these quirks if the main seabios code
> > > > hooks int10?
> > > 
> > > Good question.  Do the emulators (both win, xorg) use the int10 vector
> > > set by seabios in the first place?  Or go they load the vgabios and run
> > > it, including the initialization, and use whatever entry point the init
> > > code sets up?  I suspect it is the latter.  But needs investigation and
> > > testing.
> > 
> > I think they just call the existing int10 handler.  In general, it's
> > not safe to rerun the vga init code.  Also, if they did run the init
> > it would lead to extra copies of the SeaVGABIOS version banners in the
> > debug logs, which I don't recall seeing.
> 
> Finally found the time to continue with this and ran a bunch of tests.
> RHEL-5 (known to be affected by x86emu issue) continues to work fine.
> Xorg server log looks like it goes scan memory for the vgabios instead
> of depending on the int10 vector:

Interesting.  I'm curious how the memory scan works, because I didn't
think there was any way to find the vga entry point except from the
int10 vector.

Were you looking to include this series in SeaBIOS v1.10?  We can
either delay the release or push the changes into the next release.
Also not sure where Igor's patches stand wrt inclusion into QEMU.

-Kevin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  2016-10-04  3:03           ` Kevin O'Connor
@ 2016-10-04  8:49             ` Gerd Hoffmann
  2016-10-04  9:21               ` Igor Mammedov
  0 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2016-10-04  8:49 UTC (permalink / raw)
  To: Kevin O'Connor, Igor Mammedov; +Cc: seabios, qemu-devel

  Hi,

> Interesting.  I'm curious how the memory scan works, because I didn't
> think there was any way to find the vga entry point except from the
> int10 vector.

Run the init code in emulator?

> Were you looking to include this series in SeaBIOS v1.10?  We can
> either delay the release or push the changes into the next release.

1.10 release in october would be great for qemu as freeze for the 2.8
release is november 1st.  That doesn't leave much room to delay
things ...

I think that means either merge the current sercon version (posted to
the list last Wednesday, have you looked at it?) for 1.10 or move it
into the next release.

> Also not sure where Igor's patches stand wrt inclusion into QEMU.

Good question.  It isn't yet in the qemu master branch.
Igor?  Do you have a status update?

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  2016-10-04  8:49             ` Gerd Hoffmann
@ 2016-10-04  9:21               ` Igor Mammedov
  2016-10-13  7:17                 ` Gerd Hoffmann
  0 siblings, 1 reply; 17+ messages in thread
From: Igor Mammedov @ 2016-10-04  9:21 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Kevin O'Connor, seabios, qemu-devel

On Tue, 04 Oct 2016 10:49:41 +0200
Gerd Hoffmann <kraxel@redhat.com> wrote:

>   Hi,
> 
> > Interesting.  I'm curious how the memory scan works, because I
> > didn't think there was any way to find the vga entry point except
> > from the int10 vector.
> 
> Run the init code in emulator?
> 
> > Were you looking to include this series in SeaBIOS v1.10?  We can
> > either delay the release or push the changes into the next release.
> 
> 1.10 release in october would be great for qemu as freeze for the 2.8
> release is november 1st.  That doesn't leave much room to delay
> things ...
> 
> I think that means either merge the current sercon version (posted to
> the list last Wednesday, have you looked at it?) for 1.10 or move it
> into the next release.
> 
> > Also not sure where Igor's patches stand wrt inclusion into QEMU.
> 
> Good question.  It isn't yet in the qemu master branch.
> Igor?  Do you have a status update?

So far plan is merge it into QEMU 2.8.
I've amended QEMU counterpart according to Radim's and Paolo's reviews
and plan to respin it soon.
It will depend on Radim's https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg08292.html
though, so my series will be merged after that

> 
> cheers,
>   Gerd
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  2016-10-04  9:21               ` Igor Mammedov
@ 2016-10-13  7:17                 ` Gerd Hoffmann
  2016-10-13  8:09                   ` Igor Mammedov
  0 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2016-10-13  7:17 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: Kevin O'Connor, seabios, qemu-devel

  Hi,

> So far plan is merge it into QEMU 2.8.
> I've amended QEMU counterpart according to Radim's and Paolo's reviews
> and plan to respin it soon.

No respin yet on the list it seems.   What is the status?  Do you wait
for Radim's patches land upstream first?  Can you cc me if you post it?

> It will depend on Radim's https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg08292.html
> though, so my series will be merged after that

That series is at v5 now and seems to be ready for merge, even though it
didn't land in master yet.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [SeaBIOS] [PATCH 5/5] [wip] sercon: initial split-output implementation
  2016-10-13  7:17                 ` Gerd Hoffmann
@ 2016-10-13  8:09                   ` Igor Mammedov
  0 siblings, 0 replies; 17+ messages in thread
From: Igor Mammedov @ 2016-10-13  8:09 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Kevin O'Connor, seabios, qemu-devel

On Thu, 13 Oct 2016 09:17:51 +0200
Gerd Hoffmann <kraxel@redhat.com> wrote:

>   Hi,
> 
> > So far plan is merge it into QEMU 2.8.
> > I've amended QEMU counterpart according to Radim's and Paolo's reviews
> > and plan to respin it soon.  
> 
> No respin yet on the list it seems.   What is the status?  Do you wait
> for Radim's patches land upstream first?
yep, I'm was waiting on Radim's patches to be ready first.
By now they all have been reviewed and I don't expect to any changes in them.
So I'll respin v3 todayish as well as v6 of this series.

>  Can you cc me if you post it?
sure

> 
> > It will depend on Radim's https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg08292.html
> > though, so my series will be merged after that  
> 
> That series is at v5 now and seems to be ready for merge, even though it
> didn't land in master yet.
> 
> cheers,
>   Gerd
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2016-10-13  8:09 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [Qemu-devel] [PATCH 5/5] [wip] sercon: initial split-output implementation Gerd Hoffmann
2016-07-14 16:15   ` [Qemu-devel] [SeaBIOS] " 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

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.