[SerialICE] New patch to review for serialice: 679f87a Move SerialICE protocol support to separate file

Patrick Georgi (patrick@georgi-clan.de) gerrit at coreboot.org
Wed May 30 14:48:46 CEST 2012


Patrick Georgi (patrick at georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1066

-gerrit

commit 679f87ab165ba56906b0acc6db45fc1a61ac3478
Author: Patrick Georgi <patrick at georgi-clan.de>
Date:   Wed May 30 00:17:12 2012 +0200

    Move SerialICE protocol support to separate file
    
    serialice-com.c is responsible for the lowlevel details of
    communication. serialice.c does the hooks and lua coordination.
    
    No changes were made to functions operation. Two unused functions
    are #if 0'd out, and there's some reordering going on to make gcc
    happy, but any change inside a function is a bug.
    
    Change-Id: Ic3a308dfd434d48c67018227707f8022c2e40050
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
    [pg: Reorganized Kyösti's patch set]
    Signed-off-by: Patrick Georgi <patrick at georgi-clan.de>
---
 qemu-0.15.x/Makefile        |    2 +
 qemu-0.15.x/Makefile.target |    2 +-
 qemu-0.15.x/serialice-com.c |  496 +++++++++++++++++++++++++++++++++++++++++++
 qemu-0.15.x/serialice.c     |  460 +---------------------------------------
 qemu-0.15.x/serialice.h     |   17 ++
 5 files changed, 523 insertions(+), 454 deletions(-)

diff --git a/qemu-0.15.x/Makefile b/qemu-0.15.x/Makefile
index 076b0ec..0778994 100644
--- a/qemu-0.15.x/Makefile
+++ b/qemu-0.15.x/Makefile
@@ -121,9 +121,11 @@ version.o: $(SRC_PATH)/version.rc config-host.mak
 
 ifdef CONFIG_SERIALICE
 serialice.o: serialice.c serialice.h
+serialice-com.o: serialice-com.c serialice.h
 endif
 
 serialice.o: QEMU_CFLAGS += $(SERIALICE_CFLAGS)
+serialice-com.o: QEMU_CFLAGS += $(SERIALICE_CFLAGS)
 
 version-obj-$(CONFIG_WIN32) += version.o
 ######################################################################
diff --git a/qemu-0.15.x/Makefile.target b/qemu-0.15.x/Makefile.target
index 22c8ff1..9ae7a03 100644
--- a/qemu-0.15.x/Makefile.target
+++ b/qemu-0.15.x/Makefile.target
@@ -226,7 +226,7 @@ ifdef CONFIG_SERIALICE
 QEMU_CFLAGS += $(SERIALICE_CFLAGS)
 LIBS+=-lm
 endif
-obj-$(CONFIG_SERIALICE) += serialice.o
+obj-$(CONFIG_SERIALICE) += serialice.o serialice-com.o
 
 # Hardware support
 obj-i386-y += vga.o
diff --git a/qemu-0.15.x/serialice-com.c b/qemu-0.15.x/serialice-com.c
new file mode 100644
index 0000000..8883643
--- /dev/null
+++ b/qemu-0.15.x/serialice-com.c
@@ -0,0 +1,496 @@
+/*
+ * QEMU PC System Emulator
+ *
+ * Copyright (c) 2009 coresystems GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* System includes */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef WIN32
+#include <windows.h>
+#include <conio.h>
+#else
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#endif
+
+#include "console.h"
+#include "serialice.h"
+#include "sysemu.h"
+
+#define SERIALICE_BANNER 1
+#if SERIALICE_BANNER
+#include "serialice_banner.h"
+#endif
+
+#define SERIALICE_DEBUG 3
+#define BUFFER_SIZE 1024
+
+typedef struct {
+#ifdef WIN32
+    HANDLE fd;
+#else
+    int fd;
+#endif
+    DisplayState *ds;
+    char *buffer;
+    char *command;
+} SerialICEState;
+
+static SerialICEState *s;
+const char *serialice_mainboard = NULL;
+
+/* we need the screen stuff here since it uses SerialICEState */
+static int screen_invalid = 1;
+
+static void serialice_refresh(void *opaque)
+{
+    uint8_t *dest;
+    int bpp, linesize;
+
+    if (!screen_invalid) {
+        return;
+    }
+
+    dest = ds_get_data(s->ds);
+    bpp = (ds_get_bits_per_pixel(s->ds) + 7) >> 3;
+    linesize = ds_get_linesize(s->ds);
+
+    memset(dest, 0x00, linesize * ds_get_height(s->ds));
+#if SERIALICE_BANNER
+    int x, y;
+    if (bpp == 4) {
+        for (y = 0; y < 240; y++) {
+            for (x = 0; x < 320; x++) {
+                int doff = (y * linesize) + (x * bpp);
+                int soff = (y * (320 * 3)) + (x * 3);
+                dest[doff + 0] = serialice_banner[soff + 2];    // blue
+                dest[doff + 1] = serialice_banner[soff + 1];    // green
+                dest[doff + 2] = serialice_banner[soff + 0];    // red
+            }
+        }
+    } else {
+        printf("Banner enabled and BPP = %d (line size = %d)\n", bpp, linesize);
+    }
+#endif
+
+    dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
+    screen_invalid = 0;
+}
+
+static void serialice_invalidate(void *opaque)
+{
+    screen_invalid = 1;
+}
+
+#ifndef WIN32
+static struct termios options;
+#endif
+
+static int handshake_mode = 0;
+
+static int serialice_read(SerialICEState * state, void *buf, size_t nbyte)
+{
+    int bytes_read = 0;
+
+    while (1) {
+#ifdef WIN32
+        int ret = 0;
+        ReadFile(state->fd, buf, nbyte - bytes_read, &ret, NULL);
+        if (!ret) {
+            break;
+        }
+#else
+        int ret = read(state->fd, buf, nbyte - bytes_read);
+
+        if (ret == -1 && errno == EINTR) {
+            continue;
+        }
+
+        if (ret == -1) {
+            break;
+        }
+#endif
+
+        bytes_read += ret;
+        buf += ret;
+
+        if (bytes_read >= (int)nbyte) {
+            break;
+        }
+    }
+
+    return bytes_read;
+}
+
+static int serialice_write(SerialICEState * state, const void *buf,
+                           size_t nbyte)
+{
+    char *buffer = (char *)buf;
+    char c;
+    int i;
+
+    for (i = 0; i < (int)nbyte; i++) {
+#ifdef WIN32
+        int ret = 0;
+        while (ret == 0) {
+            WriteFile(state->fd, buffer + i, 1, &ret, NULL);
+        }
+        ret = 0;
+        while (ret == 0) {
+            ReadFile(state->fd, &c, 1, &ret, NULL);
+        }
+#else
+        while (write(state->fd, buffer + i, 1) != 1) ;
+        while (read(state->fd, &c, 1) != 1) ;
+#endif
+        if (c != buffer[i] && !handshake_mode) {
+            printf("Readback error! %x/%x\n", c, buffer[i]);
+        }
+    }
+
+    return nbyte;
+}
+
+static int serialice_wait_prompt(void)
+{
+    char buf[3];
+    int l;
+
+    l = serialice_read(s, buf, 3);
+
+    if (l == -1) {
+        perror("SerialICE: Could not read from target");
+        exit(1);
+    }
+
+    while (buf[0] != '\n' || buf[1] != '>' || buf[2] != ' ') {
+        buf[0] = buf[1];
+        buf[1] = buf[2];
+        l = serialice_read(s, buf + 2, 1);
+        if (l == -1) {
+            perror("SerialICE: Could not read from target");
+            exit(1);
+        }
+    }
+
+    return 0;
+}
+
+void serialice_serial_init(void)
+{
+    s = qemu_mallocz(sizeof(SerialICEState));
+
+    s->ds = graphic_console_init(serialice_refresh, serialice_invalidate,
+                                 NULL, NULL, s);
+    qemu_console_resize(s->ds, 320, 240);
+
+    if (serialice_device == NULL) {
+        printf("You need to specify a serial device to use SerialICE.\n");
+        exit(1);
+    }
+#ifdef WIN32
+    s->fd = CreateFile(serialice_device, GENERIC_READ | GENERIC_WRITE,
+                       0, NULL, OPEN_EXISTING, 0, NULL);
+
+    if (s->fd == INVALID_HANDLE_VALUE) {
+        perror("SerialICE: Could not connect to target TTY");
+        exit(1);
+    }
+
+    DCB dcb;
+    if (!GetCommState(s->fd, &dcb)) {
+        perror("SerialICE: Could not load config for target TTY");
+        exit(1);
+    }
+
+    dcb.BaudRate = CBR_115200;
+    dcb.ByteSize = 8;
+    dcb.Parity = NOPARITY;
+    dcb.StopBits = ONESTOPBIT;
+
+    if (!SetCommState(s->fd, &dcb)) {
+        perror("SerialICE: Could not store config for target TTY");
+        exit(1);
+    }
+#else
+    s->fd = open(serialice_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
+
+    if (s->fd == -1) {
+        perror("SerialICE: Could not connect to target TTY");
+        exit(1);
+    }
+
+    if (ioctl(s->fd, TIOCEXCL) == -1) {
+        perror("SerialICE: TTY not exclusively available");
+        exit(1);
+    }
+
+    if (fcntl(s->fd, F_SETFL, 0) == -1) {
+        perror("SerialICE: Could not switch to blocking I/O");
+        exit(1);
+    }
+
+    if (tcgetattr(s->fd, &options) == -1) {
+        perror("SerialICE: Could not get TTY attributes");
+        exit(1);
+    }
+
+    cfsetispeed(&options, B115200);
+    cfsetospeed(&options, B115200);
+
+    /* set raw input, 1 second timeout */
+    options.c_cflag |= (CLOCAL | CREAD);
+    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+    options.c_oflag &= ~OPOST;
+    options.c_iflag |= IGNCR;
+    options.c_cc[VMIN] = 0;
+    options.c_cc[VTIME] = 100;
+
+    tcsetattr(s->fd, TCSANOW, &options);
+
+    tcflush(s->fd, TCIOFLUSH);
+#endif
+
+    s->buffer = qemu_mallocz(BUFFER_SIZE);
+    s->command = qemu_mallocz(BUFFER_SIZE);
+
+    printf("SerialICE: Waiting for handshake with target... ");
+
+    handshake_mode = 1;         // Readback errors are to be expected in this phase.
+
+    /* Trigger a prompt */
+    serialice_write(s, "@", 1);
+
+    /* ... and wait for it to appear */
+    if (serialice_wait_prompt() == 0) {
+        printf("target alive!\n");
+    } else {
+        printf("target not ok!\n");
+        exit(1);
+    }
+
+    /* Each serialice_command() waits for a prompt, so trigger one for the
+     * first command, as we consumed the last one for the handshake
+     */
+    serialice_write(s, "@", 1);
+
+    handshake_mode = 0;         // from now on, warn about readback errors.
+
+    serialice_get_version();
+
+    serialice_get_mainboard();
+}
+
+void serialice_command(const char *command, int reply_len)
+{
+#if SERIALICE_DEBUG > 5
+    int i;
+#endif
+    int l;
+
+    serialice_wait_prompt();
+
+    serialice_write(s, command, strlen(command));
+
+    memset(s->buffer, 0, reply_len + 1);        // clear enough of the buffer
+
+    l = serialice_read(s, s->buffer, reply_len);
+
+    if (l == -1) {
+        perror("SerialICE: Could not read from target");
+        exit(1);
+    }
+    // compensate for CR on the wire. Needed on Win32
+    if (s->buffer[0] == '\r') {
+        memmove(s->buffer, s->buffer + 1, reply_len);
+        serialice_read(s, s->buffer + reply_len - 1, 1);
+    }
+
+    if (l != reply_len) {
+        printf("SerialICE: command was not answered sufficiently: "
+               "(%d/%d bytes)\n'%s'\n", l, reply_len, s->buffer);
+        exit(1);
+    }
+#if SERIALICE_DEBUG > 5
+    for (i = 0; i < reply_len; i++) {
+        printf("%02x ", s->buffer[i]);
+    }
+    printf("\n");
+#endif
+}
+
+void serialice_get_version(void)
+{
+    int len = 0;
+    printf("SerialICE: Version.....: ");
+    serialice_command("*vi", 0);
+
+    memset(s->buffer, 0, BUFFER_SIZE);
+    serialice_read(s, s->buffer, 1);
+    serialice_read(s, s->buffer, 1);
+    while (s->buffer[len++] != '\n') {
+        serialice_read(s, s->buffer + len, 1);
+    }
+    s->buffer[len - 1] = '\0';
+
+    printf("%s\n", s->buffer);
+}
+
+void serialice_get_mainboard(void)
+{
+    int len = 31;
+
+    printf("SerialICE: Mainboard...: ");
+    serialice_command("*mb", 32);
+    while (len && s->buffer[len] == ' ') {
+        s->buffer[len--] = '\0';
+    }
+    serialice_mainboard = strdup(s->buffer + 1);
+    printf("%s\n", serialice_mainboard);
+}
+
+uint32_t serialice_io_read_wrapper(uint16_t port, unsigned int size)
+{
+    switch (size) {
+    case 1:
+        sprintf(s->command, "*ri%04x.b", port);
+        // command read back: "\n00" (3 characters)
+        serialice_command(s->command, 3);
+        return (uint8_t) strtoul(s->buffer + 1, (char **)NULL, 16);
+    case 2:
+        sprintf(s->command, "*ri%04x.w", port);
+        // command read back: "\n0000" (5 characters)
+        serialice_command(s->command, 5);
+        return (uint16_t) strtoul(s->buffer + 1, (char **)NULL, 16);
+    case 4:
+        sprintf(s->command, "*ri%04x.l", port);
+        // command read back: "\n00000000" (9 characters)
+        serialice_command(s->command, 9);
+        return strtoul(s->buffer + 1, (char **)NULL, 16);
+    default:
+        printf("WARNING: unknown read access size %d @%08x\n", size, port);
+        return -1;
+    }
+}
+
+void serialice_io_write_wrapper(uint16_t port, unsigned int size, uint32_t data)
+{
+    switch (size) {
+    case 1:
+        sprintf(s->command, "*wi%04x.b=%02x", port, (uint8_t) data);
+        serialice_command(s->command, 0);
+        return;
+    case 2:
+        sprintf(s->command, "*wi%04x.w=%04x", port, (uint16_t) data);
+        serialice_command(s->command, 0);
+        return;
+    case 4:
+        sprintf(s->command, "*wi%04x.l=%08x", port, data);
+        serialice_command(s->command, 0);
+        return;
+    default:
+        printf("WARNING: unknown write access size %d @%08x\n", size, port);
+    }
+    return;
+}
+
+uint32_t serialice_load_wrapper(uint32_t addr, unsigned int size)
+{
+    switch (size) {
+    case 1:
+        sprintf(s->command, "*rm%08x.b", addr);
+        // command read back: "\n00" (3 characters)
+        serialice_command(s->command, 3);
+        return (uint8_t) strtoul(s->buffer + 1, (char **)NULL, 16);
+    case 2:
+        sprintf(s->command, "*rm%08x.w", addr);
+        // command read back: "\n0000" (5 characters)
+        serialice_command(s->command, 5);
+        return (uint16_t) strtoul(s->buffer + 1, (char **)NULL, 16);
+    case 4:
+        sprintf(s->command, "*rm%08x.l", addr);
+        // command read back: "\n00000000" (9 characters)
+        serialice_command(s->command, 9);
+        return (uint32_t) strtoul(s->buffer + 1, (char **)NULL, 16);
+    default:
+        printf("WARNING: unknown read access size %d @%08x\n", size, addr);
+    }
+    return 0;
+}
+
+void serialice_store_wrapper(uint32_t addr, unsigned int size, uint32_t data)
+{
+    switch (size) {
+    case 1:
+        sprintf(s->command, "*wm%08x.b=%02x", addr, (uint8_t) data);
+        serialice_command(s->command, 0);
+        break;
+    case 2:
+        sprintf(s->command, "*wm%08x.w=%04x", addr, (uint16_t) data);
+        serialice_command(s->command, 0);
+        break;
+    case 4:
+        sprintf(s->command, "*wm%08x.l=%08x", addr, data);
+        serialice_command(s->command, 0);
+        break;
+    default:
+        printf("WARNING: unknown write access size %d @%08x\n", size, addr);
+    }
+}
+
+void serialice_rdmsr_wrapper(uint32_t addr, uint32_t key,
+                             uint32_t * hi, uint32_t * lo)
+{
+    sprintf(s->command, "*rc%08x.%08x", addr, key);
+    // command read back: "\n00000000.00000000" (18 characters)
+    serialice_command(s->command, 18);
+    s->buffer[9] = 0;           // . -> \0
+    *hi = (uint32_t) strtoul(s->buffer + 1, (char **)NULL, 16);
+    *lo = (uint32_t) strtoul(s->buffer + 10, (char **)NULL, 16);
+}
+
+void serialice_wrmsr_wrapper(uint32_t addr, uint32_t key,
+                             uint32_t hi, uint32_t lo)
+{
+    sprintf(s->command, "*wc%08x.%08x=%08x.%08x", addr, key, hi, lo);
+    serialice_command(s->command, 0);
+}
+
+void serialice_cpuid_wrapper(uint32_t eax, uint32_t ecx, cpuid_regs_t * ret)
+{
+    sprintf(s->command, "*ci%08x.%08x", eax, ecx);
+    // command read back: "\n000006f2.00000000.00001234.12340324"
+    // (36 characters)
+    serialice_command(s->command, 36);
+    s->buffer[9] = 0;           // . -> \0
+    s->buffer[18] = 0;          // . -> \0
+    s->buffer[27] = 0;          // . -> \0
+    ret->eax = (uint32_t) strtoul(s->buffer + 1, (char **)NULL, 16);
+    ret->ebx = (uint32_t) strtoul(s->buffer + 10, (char **)NULL, 16);
+    ret->ecx = (uint32_t) strtoul(s->buffer + 19, (char **)NULL, 16);
+    ret->edx = (uint32_t) strtoul(s->buffer + 28, (char **)NULL, 16);
+}
diff --git a/qemu-0.15.x/serialice.c b/qemu-0.15.x/serialice.c
index 3813a1f..8bdcf88 100644
--- a/qemu-0.15.x/serialice.c
+++ b/qemu-0.15.x/serialice.c
@@ -55,37 +55,13 @@
 #include "serialice.h"
 #include "sysemu.h"
 
-#define SERIALICE_BANNER 1
-#if SERIALICE_BANNER
-#include "serialice_banner.h"
-#endif
-
 #define DEFAULT_RAM_SIZE 128
 #define BIOS_FILENAME "bios.bin"
 
-#define SERIALICE_DEBUG 3
-#define BUFFER_SIZE 1024
-typedef struct {
-#ifdef WIN32
-    HANDLE fd;
-#else
-    int fd;
-#endif
-    DisplayState *ds;
-    char *buffer;
-    char *command;
-} SerialICEState;
-
-static SerialICEState *s;
-
 int serialice_active = 0;
 const char *serialice_lua_script = "serialice.lua";
 
-const char *serialice_mainboard = NULL;
-
-#ifndef WIN32
-static struct termios options;
-#endif
+extern const char *serialice_mainboard;
 
 static lua_State *L;
 
@@ -270,11 +246,14 @@ static int serialice_lua_init(void)
     return 0;
 }
 
+#if 0
+/* not used yet */
 static int serialice_lua_exit(void)
 {
     lua_close(L);
     return 0;
 }
+#endif
 
 const char *serialice_lua_execute(const char *cmd)
 {
@@ -546,212 +525,9 @@ static void serialice_cpuid_log(uint32_t eax, uint32_t ecx, cpuid_regs_t res,
 // **************************************************************************
 // low level communication with the SerialICE shell (serial communication)
 
-static int serialice_read(SerialICEState * state, void *buf, size_t nbyte)
-{
-    int bytes_read = 0;
-
-    while (1) {
-#ifdef WIN32
-        int ret = 0;
-        ReadFile(state->fd, buf, nbyte - bytes_read, &ret, NULL);
-        if (!ret) {
-            break;
-        }
-#else
-        int ret = read(state->fd, buf, nbyte - bytes_read);
-
-        if (ret == -1 && errno == EINTR) {
-            continue;
-        }
-
-        if (ret == -1) {
-            break;
-        }
-#endif
-
-        bytes_read += ret;
-        buf += ret;
-
-        if (bytes_read >= (int)nbyte) {
-            break;
-        }
-    }
-
-    return bytes_read;
-}
-
-static int handshake_mode = 0;
-
-static int serialice_write(SerialICEState * state, const void *buf,
-                           size_t nbyte)
-{
-    char *buffer = (char *)buf;
-    char c;
-    int i;
-
-    for (i = 0; i < (int)nbyte; i++) {
-#ifdef WIN32
-        int ret = 0;
-        while (ret == 0) {
-            WriteFile(state->fd, buffer + i, 1, &ret, NULL);
-        }
-        ret = 0;
-        while (ret == 0) {
-            ReadFile(state->fd, &c, 1, &ret, NULL);
-        }
-#else
-        while (write(state->fd, buffer + i, 1) != 1) ;
-        while (read(state->fd, &c, 1) != 1) ;
-#endif
-        if (c != buffer[i] && !handshake_mode) {
-            printf("Readback error! %x/%x\n", c, buffer[i]);
-        }
-    }
-
-    return nbyte;
-}
-
-static int serialice_wait_prompt(void)
-{
-    char buf[3];
-    int l;
-
-    l = serialice_read(s, buf, 3);
-
-    if (l == -1) {
-        perror("SerialICE: Could not read from target");
-        exit(1);
-    }
-
-    while (buf[0] != '\n' || buf[1] != '>' || buf[2] != ' ') {
-        buf[0] = buf[1];
-        buf[1] = buf[2];
-        l = serialice_read(s, buf + 2, 1);
-        if (l == -1) {
-            perror("SerialICE: Could not read from target");
-            exit(1);
-        }
-    }
-
-    return 0;
-}
-
-static void serialice_command(const char *command, int reply_len)
-{
-#if SERIALICE_DEBUG > 5
-    int i;
-#endif
-    int l;
-
-    serialice_wait_prompt();
-
-    serialice_write(s, command, strlen(command));
-
-    memset(s->buffer, 0, reply_len + 1);        // clear enough of the buffer
-
-    l = serialice_read(s, s->buffer, reply_len);
-
-    if (l == -1) {
-        perror("SerialICE: Could not read from target");
-        exit(1);
-    }
-    // compensate for CR on the wire. Needed on Win32
-    if (s->buffer[0] == '\r') {
-        memmove(s->buffer, s->buffer + 1, reply_len);
-        serialice_read(s, s->buffer + reply_len - 1, 1);
-    }
-
-    if (l != reply_len) {
-        printf("SerialICE: command was not answered sufficiently: "
-               "(%d/%d bytes)\n'%s'\n", l, reply_len, s->buffer);
-        exit(1);
-    }
-#if SERIALICE_DEBUG > 5
-    for (i = 0; i < reply_len; i++) {
-        printf("%02x ", s->buffer[i]);
-    }
-    printf("\n");
-#endif
-}
-
 // **************************************************************************
 // high level communication with the SerialICE shell
 
-static void serialice_get_version(void)
-{
-    int len = 0;
-    printf("SerialICE: Version.....: ");
-    serialice_command("*vi", 0);
-
-    memset(s->buffer, 0, BUFFER_SIZE);
-    serialice_read(s, s->buffer, 1);
-    serialice_read(s, s->buffer, 1);
-    while (s->buffer[len++] != '\n') {
-        serialice_read(s, s->buffer + len, 1);
-    }
-    s->buffer[len - 1] = '\0';
-
-    printf("%s\n", s->buffer);
-}
-
-static void serialice_get_mainboard(void)
-{
-    int len = 31;
-
-    printf("SerialICE: Mainboard...: ");
-    serialice_command("*mb", 32);
-    while (len && s->buffer[len] == ' ') {
-        s->buffer[len--] = '\0';
-    }
-    serialice_mainboard = strdup(s->buffer + 1);
-    printf("%s\n", serialice_mainboard);
-}
-
-static uint32_t serialice_io_read_wrapper(uint16_t port, unsigned int size)
-{
-    switch (size) {
-    case 1:
-        sprintf(s->command, "*ri%04x.b", port);
-        // command read back: "\n00" (3 characters)
-        serialice_command(s->command, 3);
-        return (uint8_t) strtoul(s->buffer + 1, (char **)NULL, 16);
-    case 2:
-        sprintf(s->command, "*ri%04x.w", port);
-        // command read back: "\n0000" (5 characters)
-        serialice_command(s->command, 5);
-        return (uint16_t) strtoul(s->buffer + 1, (char **)NULL, 16);
-    case 4:
-        sprintf(s->command, "*ri%04x.l", port);
-        // command read back: "\n00000000" (9 characters)
-        serialice_command(s->command, 9);
-        return strtoul(s->buffer + 1, (char **)NULL, 16);
-    default:
-        printf("WARNING: unknown read access size %d @%08x\n", size, port);
-        return -1;
-    }
-}
-
-static void serialice_io_write_wrapper(uint16_t port, unsigned int size, uint32_t data)
-{
-    switch (size) {
-    case 1:
-        sprintf(s->command, "*wi%04x.b=%02x", port, (uint8_t) data);
-        serialice_command(s->command, 0);
-        return;
-    case 2:
-        sprintf(s->command, "*wi%04x.w=%04x", port, (uint16_t) data);
-        serialice_command(s->command, 0);
-        return;
-    case 4:
-        sprintf(s->command, "*wi%04x.l=%08x", port, data);
-        serialice_command(s->command, 0);
-        return;
-    default:
-        printf("WARNING: unknown write access size %d @%08x\n", size, port);
-    }
-    return;
-}
-
 uint8_t serialice_inb(uint16_t port)
 {
     uint8_t ret;
@@ -860,17 +636,6 @@ void serialice_outl(uint32_t data, uint16_t port)
     serialice_log(LOG_WRITE | LOG_IO, data, port, 4);
 }
 
-static void serialice_rdmsr_wrapper(uint32_t addr, uint32_t key,
-                             uint32_t * hi, uint32_t * lo)
-{
-    sprintf(s->command, "*rc%08x.%08x", addr, key);
-    // command read back: "\n00000000.00000000" (18 characters)
-    serialice_command(s->command, 18);
-    s->buffer[9] = 0;           // . -> \0
-    *hi = (uint32_t) strtoul(s->buffer + 1, (char **)NULL, 16);
-    *lo = (uint32_t) strtoul(s->buffer + 10, (char **)NULL, 16);
-}
-
 uint64_t serialice_rdmsr(uint32_t addr, uint32_t key)
 {
     uint32_t hi, lo;
@@ -891,13 +656,6 @@ uint64_t serialice_rdmsr(uint32_t addr, uint32_t key)
     return ret;
 }
 
-static void serialice_wrmsr_wrapper(uint32_t addr, uint32_t key,
-                             uint32_t hi, uint32_t lo)
-{
-    sprintf(s->command, "*wc%08x.%08x=%08x.%08x", addr, key, hi, lo);
-    serialice_command(s->command, 0);
-}
-
 void serialice_wrmsr(uint64_t data, uint32_t addr, uint32_t key)
 {
     uint32_t hi, lo;
@@ -915,21 +673,6 @@ void serialice_wrmsr(uint64_t data, uint32_t addr, uint32_t key)
     serialice_msr_log(LOG_WRITE, addr, hi, lo, filtered);
 }
 
-static void serialice_cpuid_wrapper(uint32_t eax, uint32_t ecx, cpuid_regs_t * ret)
-{
-    sprintf(s->command, "*ci%08x.%08x", eax, ecx);
-    // command read back: "\n000006f2.00000000.00001234.12340324"
-    // (36 characters)
-    serialice_command(s->command, 36);
-    s->buffer[9] = 0;           // . -> \0
-    s->buffer[18] = 0;          // . -> \0
-    s->buffer[27] = 0;          // . -> \0
-    ret->eax = (uint32_t) strtoul(s->buffer + 1, (char **)NULL, 16);
-    ret->ebx = (uint32_t) strtoul(s->buffer + 10, (char **)NULL, 16);
-    ret->ecx = (uint32_t) strtoul(s->buffer + 19, (char **)NULL, 16);
-    ret->edx = (uint32_t) strtoul(s->buffer + 28, (char **)NULL, 16);
-}
-
 cpuid_regs_t serialice_cpuid(uint32_t eax, uint32_t ecx)
 {
     cpuid_regs_t ret;
@@ -947,30 +690,6 @@ cpuid_regs_t serialice_cpuid(uint32_t eax, uint32_t ecx)
 // **************************************************************************
 // memory load handling
 
-static uint32_t serialice_load_wrapper(uint32_t addr, unsigned int size)
-{
-    switch (size) {
-    case 1:
-        sprintf(s->command, "*rm%08x.b", addr);
-        // command read back: "\n00" (3 characters)
-        serialice_command(s->command, 3);
-        return (uint8_t) strtoul(s->buffer + 1, (char **)NULL, 16);
-    case 2:
-        sprintf(s->command, "*rm%08x.w", addr);
-        // command read back: "\n0000" (5 characters)
-        serialice_command(s->command, 5);
-        return (uint16_t) strtoul(s->buffer + 1, (char **)NULL, 16);
-    case 4:
-        sprintf(s->command, "*rm%08x.l", addr);
-        // command read back: "\n00000000" (9 characters)
-        serialice_command(s->command, 9);
-        return (uint32_t) strtoul(s->buffer + 1, (char **)NULL, 16);
-    default:
-        printf("WARNING: unknown read access size %d @%08x\n", size, addr);
-    }
-    return 0;
-}
-
 /**
  * This function is called by the softmmu engine to update the status
  * of a load cycle
@@ -1014,27 +733,6 @@ int serialice_handle_load(uint32_t addr, uint32_t * result,
 // **************************************************************************
 // memory store handling
 
-static void serialice_store_wrapper(uint32_t addr, unsigned int size,
-                                    uint32_t data)
-{
-    switch (size) {
-    case 1:
-        sprintf(s->command, "*wm%08x.b=%02x", addr, (uint8_t) data);
-        serialice_command(s->command, 0);
-        break;
-    case 2:
-        sprintf(s->command, "*wm%08x.w=%04x", addr, (uint16_t) data);
-        serialice_command(s->command, 0);
-        break;
-    case 4:
-        sprintf(s->command, "*wm%08x.l=%08x", addr, data);
-        serialice_command(s->command, 0);
-        break;
-    default:
-        printf("WARNING: unknown write access size %d @%08x\n", size, addr);
-    }
-}
-
 static void serialice_log_store(int caught, uint32_t addr, uint32_t val,
                                 unsigned int data_size)
 {
@@ -1071,158 +769,11 @@ int serialice_handle_store(uint32_t addr, uint32_t val, unsigned int data_size)
     return (write_to_qemu == 0);
 }
 
-static int screen_invalid = 1;
-
-static void serialice_refresh(void *opaque)
-{
-    uint8_t *dest;
-    int bpp, linesize;
-
-    if (!screen_invalid) {
-        return;
-    }
-
-    dest = ds_get_data(s->ds);
-    bpp = (ds_get_bits_per_pixel(s->ds) + 7) >> 3;
-    linesize = ds_get_linesize(s->ds);
-
-    memset(dest, 0x00, linesize * ds_get_height(s->ds));
-#if SERIALICE_BANNER
-    int x, y;
-    if (bpp == 4) {
-        for (y = 0; y < 240; y++) {
-            for (x = 0; x < 320; x++) {
-                int doff = (y * linesize) + (x * bpp);
-                int soff = (y * (320 * 3)) + (x * 3);
-                dest[doff + 0] = serialice_banner[soff + 2];    // blue
-                dest[doff + 1] = serialice_banner[soff + 1];    // green
-                dest[doff + 2] = serialice_banner[soff + 0];    // red
-            }
-        }
-    } else {
-        printf("Banner enabled and BPP = %d (line size = %d)\n", bpp, linesize);
-    }
-#endif
-
-    dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
-    screen_invalid = 0;
-}
-
-static void serialice_invalidate(void *opaque)
-{
-    screen_invalid = 1;
-}
-
 // **************************************************************************
 // initialization and exit
 
-static void serialice_serial_init(void)
-{
-    if (serialice_device == NULL) {
-        printf("You need to specify a serial device to use SerialICE.\n");
-        exit(1);
-    }
-#ifdef WIN32
-    s->fd = CreateFile(serialice_device, GENERIC_READ | GENERIC_WRITE,
-                       0, NULL, OPEN_EXISTING, 0, NULL);
-
-    if (s->fd == INVALID_HANDLE_VALUE) {
-        perror("SerialICE: Could not connect to target TTY");
-        exit(1);
-    }
-
-    DCB dcb;
-    if (!GetCommState(s->fd, &dcb)) {
-        perror("SerialICE: Could not load config for target TTY");
-        exit(1);
-    }
-
-    dcb.BaudRate = CBR_115200;
-    dcb.ByteSize = 8;
-    dcb.Parity = NOPARITY;
-    dcb.StopBits = ONESTOPBIT;
-
-    if (!SetCommState(s->fd, &dcb)) {
-        perror("SerialICE: Could not store config for target TTY");
-        exit(1);
-    }
-#else
-    s->fd = open(serialice_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
-
-    if (s->fd == -1) {
-        perror("SerialICE: Could not connect to target TTY");
-        exit(1);
-    }
-
-    if (ioctl(s->fd, TIOCEXCL) == -1) {
-        perror("SerialICE: TTY not exclusively available");
-        exit(1);
-    }
-
-    if (fcntl(s->fd, F_SETFL, 0) == -1) {
-        perror("SerialICE: Could not switch to blocking I/O");
-        exit(1);
-    }
-
-    if (tcgetattr(s->fd, &options) == -1) {
-        perror("SerialICE: Could not get TTY attributes");
-        exit(1);
-    }
-
-    cfsetispeed(&options, B115200);
-    cfsetospeed(&options, B115200);
-
-    /* set raw input, 1 second timeout */
-    options.c_cflag |= (CLOCAL | CREAD);
-    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
-    options.c_oflag &= ~OPOST;
-    options.c_iflag |= IGNCR;
-    options.c_cc[VMIN] = 0;
-    options.c_cc[VTIME] = 100;
-
-    tcsetattr(s->fd, TCSANOW, &options);
-
-    tcflush(s->fd, TCIOFLUSH);
-#endif
-
-    s->buffer = qemu_mallocz(BUFFER_SIZE);
-    s->command = qemu_mallocz(BUFFER_SIZE);
-
-    printf("SerialICE: Waiting for handshake with target... ");
-
-    handshake_mode = 1;         // Readback errors are to be expected in this phase.
-
-    /* Trigger a prompt */
-    serialice_write(s, "@", 1);
-
-    /* ... and wait for it to appear */
-    if (serialice_wait_prompt() == 0) {
-        printf("target alive!\n");
-    } else {
-        printf("target not ok!\n");
-        exit(1);
-    }
-
-    /* Each serialice_command() waits for a prompt, so trigger one for the
-     * first command, as we consumed the last one for the handshake
-     */
-    serialice_write(s, "@", 1);
-
-    handshake_mode = 0;         // from now on, warn about readback errors.
-
-    serialice_get_version();
-
-    serialice_get_mainboard();
-}
-
 static void serialice_init(void)
 {
-    s = qemu_mallocz(sizeof(SerialICEState));
-
-    s->ds = graphic_console_init(serialice_refresh, serialice_invalidate,
-                                 NULL, NULL, s);
-    qemu_console_resize(s->ds, 320, 240);
-
     printf("SerialICE: Open connection to target hardware...\n");
     serialice_serial_init();
 
@@ -1233,6 +784,8 @@ static void serialice_init(void)
     serialice_active = 1;
 }
 
+#if 0
+/* no one actually uses this */
 static void serialice_exit(void)
 {
     serialice_lua_exit();
@@ -1240,6 +793,7 @@ static void serialice_exit(void)
     qemu_free(s->buffer);
     qemu_free(s);
 }
+#endif
 
 static void pc_init_serialice(ram_addr_t ram_size,
                               const char *boot_device,
diff --git a/qemu-0.15.x/serialice.h b/qemu-0.15.x/serialice.h
index a13d64b..20b0e52 100644
--- a/qemu-0.15.x/serialice.h
+++ b/qemu-0.15.x/serialice.h
@@ -37,6 +37,12 @@ extern int serialice_active;
 
 const char *serialice_lua_execute(const char *cmd);
 
+void serialice_serial_init(void);
+void serialice_command(const char *command, int reply_len);
+
+void serialice_get_version(void);
+void serialice_get_mainboard(void);
+
 uint8_t serialice_inb(uint16_t port);
 uint16_t serialice_inw(uint16_t port);
 uint32_t serialice_inl(uint16_t port);
@@ -60,4 +66,15 @@ void serialice_log_load(int caught, uint32_t addr, uint32_t result,
                         unsigned int data_size);
 int serialice_handle_store(uint32_t addr, uint32_t val, unsigned int data_size);
 
+/* serialice protocol */
+uint32_t serialice_io_read_wrapper(uint16_t port, unsigned int size);
+void serialice_io_write_wrapper(uint16_t port, unsigned int size, uint32_t data);
+
+uint32_t serialice_load_wrapper(uint32_t addr, unsigned int size);
+void serialice_store_wrapper(uint32_t addr, unsigned int size, uint32_t data);
+
+void serialice_rdmsr_wrapper(uint32_t addr, uint32_t key, uint32_t *hi, uint32_t *lo);
+void serialice_wrmsr_wrapper(uint32_t addr, uint32_t key, uint32_t hi, uint32_t lo);
+void serialice_cpuid_wrapper(uint32_t eax, uint32_t ecx, cpuid_regs_t * ret);
+
 #endif



More information about the SerialICE mailing list