Patrick Georgi (patrick@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@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@gmail.com [pg: Reorganized Kyösti's patch set] Signed-off-by: Patrick Georgi patrick@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