Author: stepan
Date: 2009-11-21 16:29:14 +0100 (Sat, 21 Nov 2009)
New Revision: 64
Modified:
trunk/SerialICE/Makefile
trunk/SerialICE/patches/serialice-qemu-0.11.0.diff
Log:
update patch against Qemu and push version number to 1.5
Modified: trunk/SerialICE/Makefile
===================================================================
--- trunk/SerialICE/Makefile 2009-11-21 14:53:59 UTC (rev 63)
+++ trunk/SerialICE/Makefile 2009-11-21 15:29:14 UTC (rev 64)
@@ -17,7 +17,7 @@
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
##
-VERSION="1.4"
+VERSION="1.5"
_OS=$(shell uname -s |cut -c-7)
STACK=
Modified: trunk/SerialICE/patches/serialice-qemu-0.11.0.diff
===================================================================
--- trunk/SerialICE/patches/serialice-qemu-0.11.0.diff 2009-11-21 14:53:59 UTC (rev 63)
+++ trunk/SerialICE/patches/serialice-qemu-0.11.0.diff 2009-11-21 15:29:14 UTC (rev 64)
@@ -10,19 +10,19 @@
build.sh | 5
configure | 45 ++
exec-all.h | 4
- hw/pc.c | 43 ++
+ hw/pc.c | 13
qemu-char.c | 4
qemu-options.hx | 11
- serialice.c | 847 ++++++++++++++++++++++++++++++++++++++++++++++++
- serialice.h | 42 ++
+ serialice.c | 927 ++++++++++++++++++++++++++++++++++++++++++++++++
+ serialice.h | 66 +++
softmmu_template.h | 28 +
target-i386/op_helper.c | 62 +++
vl.c | 8
- 13 files changed, 1108 insertions(+), 2 deletions(-)
+ 13 files changed, 1182 insertions(+), 2 deletions(-)
--- qemu-0.11.0/serialice.c
+++ qemu-0.11.0/serialice.c
-@@ -0,0 +1,847 @@
+@@ -0,0 +1,927 @@
+/*
+ * QEMU PC System Emulator
+ *
@@ -53,9 +53,14 @@
+#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
+
+/* LUA includes */
+#include <lua.h>
@@ -71,8 +76,13 @@
+#define SERIALICE_DEBUG 3
+#define BUFFER_SIZE 1024
+typedef struct {
++#ifdef WIN32
++ HANDLE fd;
++#else
+ int fd;
++#endif
+ char *buffer;
++ char *command;
+} SerialICEState;
+
+static SerialICEState *s;
@@ -80,7 +90,9 @@
+int serialice_active = 0;
+const char *serialice_lua_script="serialice.lua";
+
++#ifndef WIN32
+static struct termios options;
++#endif
+
+static lua_State *L;
+
@@ -358,7 +370,6 @@
+{
+ int result;
+
-+
+ lua_getfield(L, LUA_GLOBALSINDEX, "SerialICE_cpuid_log");
+
+ lua_pushinteger(L, eax); // input: eax
@@ -380,18 +391,25 @@
+// **************************************************************************
+// low level communication with the SerialICE shell (serial communication)
+
-+static int serialice_read(int fd, void *buf, size_t nbyte)
++static int serialice_read(SerialICEState *state, void *buf, size_t nbyte)
+{
+ int bytes_read = 0;
+
+ while (1) {
-+ int ret = read(fd, buf, nbyte);
++#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;
@@ -403,15 +421,24 @@
+ return bytes_read;
+}
+
-+static int serialice_write(int fd, const void *buf, size_t nbyte)
++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++) {
-+ while (write(fd, buffer + i, 1) != 1) ;
-+ while (read(fd, &c, 1) != 1) ;
++#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]) {
+ printf("Readback error! %x/%x\n", c, buffer[i]);
+ }
@@ -420,6 +447,31 @@
+ 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
@@ -427,17 +479,25 @@
+#endif
+ int l;
+
-+ serialice_write(s->fd, command, strlen(command));
++ 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->fd, s->buffer, reply_len);
++ 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);
@@ -458,15 +518,14 @@
+uint8_t serialice_inb(uint16_t port)
+{
+ uint8_t ret;
-+ char command[16];
++ uint32_t data;
+
-+ uint32_t data;
+ if (serialice_io_read_filter(&data, port, 1))
+ return data & 0xff;
+
-+ sprintf(command, "*ri%04x.b", port);
-+ // command read back: "\n00\n> " (6 characters)
-+ serialice_command(command, 6);
++ sprintf(s->command, "*ri%04x.b", port);
++ // command read back: "\n00" (3 characters)
++ serialice_command(s->command, 3);
+ ret = (uint8_t)strtoul(s->buffer + 1, (char **)NULL, 16);
+
+ serialice_log(LOG_READ|LOG_IO, ret, port, 1);
@@ -477,15 +536,14 @@
+uint16_t serialice_inw(uint16_t port)
+{
+ uint16_t ret;
-+ char command[16];
++ uint32_t data;
+
-+ uint32_t data;
+ if (serialice_io_read_filter(&data, port, 1))
+ return data & 0xffff;
+
-+ sprintf(command, "*ri%04x.w", port);
-+ // command read back: "\n0000\n> " (8 characters)
-+ serialice_command(command, 8);
++ sprintf(s->command, "*ri%04x.w", port);
++ // command read back: "\n0000" (5 characters)
++ serialice_command(s->command, 5);
+ ret = (uint16_t)strtoul(s->buffer + 1, (char **)NULL, 16);
+
+ serialice_log(LOG_READ|LOG_IO, ret, port, 2);
@@ -496,15 +554,14 @@
+uint32_t serialice_inl(uint16_t port)
+{
+ uint32_t ret;
-+ char command[16];
++ uint32_t data;
+
-+ uint32_t data;
+ if (serialice_io_read_filter(&data, port, 1))
+ return data;
+
-+ sprintf(command, "*ri%04x.l", port);
-+ // command read back: "\n00000000\n> " (12 characters)
-+ serialice_command(command, 12);
++ sprintf(s->command, "*ri%04x.l", port);
++ // command read back: "\n00000000" (9 characters)
++ serialice_command(s->command, 9);
+ ret = (uint32_t)strtoul(s->buffer + 1, (char **)NULL, 16);
+
+ serialice_log(LOG_READ|LOG_IO, ret, port, 4);
@@ -514,7 +571,6 @@
+
+void serialice_outb(uint8_t data, uint16_t port)
+{
-+ char command[19];
+ uint32_t filtered_data = (uint32_t)data;
+
+ serialice_log(LOG_WRITE|LOG_IO, data, port, 1);
@@ -524,14 +580,12 @@
+ }
+
+ data = (uint8_t)filtered_data;
-+ sprintf(command, "*wi%04x.b=%02x", port, data);
-+ // command read back: "\n> " (3 characters)
-+ serialice_command(command, 3);
++ sprintf(s->command, "*wi%04x.b=%02x", port, data);
++ serialice_command(s->command, 0);
+}
+
+void serialice_outw(uint16_t data, uint16_t port)
+{
-+ char command[21];
+ uint32_t filtered_data = (uint32_t)data;
+
+ serialice_log(LOG_WRITE|LOG_IO, data, port, 2);
@@ -541,14 +595,12 @@
+ }
+
+ data = (uint16_t)filtered_data;
-+ sprintf(command, "*wi%04x.w=%04x", port, data);
-+ // command read back: "\n> " (3 characters)
-+ serialice_command(command, 3);
++ sprintf(s->command, "*wi%04x.w=%04x", port, data);
++ serialice_command(s->command, 0);
+}
+
+void serialice_outl(uint32_t data, uint16_t port)
+{
-+ char command[25];
+ uint32_t filtered_data = data;
+
+ serialice_log(LOG_WRITE|LOG_IO, data, port, 4);
@@ -558,18 +610,16 @@
+ }
+
+ data = filtered_data;
-+ sprintf(command, "*wi%04x.l=%08x", port, data);
-+ // command read back: "\n> " (3 characters)
-+ serialice_command(command, 3);
++ sprintf(s->command, "*wi%04x.l=%08x", port, data);
++ serialice_command(s->command, 0);
+}
+
+uint8_t serialice_readb(uint32_t addr)
+{
+ uint8_t ret;
-+ char command[20];
-+ sprintf(command, "*rm%08x.b", addr);
-+ // command read back: "\n00\n> " (6 characters)
-+ serialice_command(command, 6);
++ sprintf(s->command, "*rm%08x.b", addr);
++ // command read back: "\n00" (3 characters)
++ serialice_command(s->command, 3);
+ ret = (uint8_t)strtoul(s->buffer + 1, (char **)NULL, 16);
+ return ret;
+}
@@ -577,10 +627,9 @@
+uint16_t serialice_readw(uint32_t addr)
+{
+ uint16_t ret;
-+ char command[20];
-+ sprintf(command, "*rm%08x.w", addr);
-+ // command read back: "\n0000\n> " (8 characters)
-+ serialice_command(command, 8);
++ sprintf(s->command, "*rm%08x.w", addr);
++ // command read back: "\n0000" (5 characters)
++ serialice_command(s->command, 5);
+ ret = (uint16_t)strtoul(s->buffer + 1, (char **)NULL, 16);
+ return ret;
+}
@@ -588,39 +637,32 @@
+uint32_t serialice_readl(uint32_t addr)
+{
+ uint32_t ret;
-+ char command[20];
-+ sprintf(command, "*rm%08x.l", addr);
-+ // command read back: "\n00000000\n> " (12 characters)
-+ serialice_command(command, 12);
++ sprintf(s->command, "*rm%08x.l", addr);
++ // command read back: "\n00000000" (9 characters)
++ serialice_command(s->command, 9);
+ ret = (uint32_t)strtoul(s->buffer + 1, (char **)NULL, 16);
+ return ret;
+}
+
+void serialice_writeb(uint8_t data, uint32_t addr)
+{
-+ char command[24];
-+ sprintf(command, "*wm%08x.b=%02x", addr, data);
-+ // command read back: "\n> " (3 characters)
-+ serialice_command(command, 3);
++ sprintf(s->command, "*wm%08x.b=%02x", addr, data);
++ serialice_command(s->command, 0);
+}
+
+void serialice_writew(uint16_t data, uint32_t addr)
+{
-+ char command[25];
-+ sprintf(command, "*wm%08x.w=%04x", addr, data);
-+ // command read back: "\n> " (3 characters)
-+ serialice_command(command, 3);
++ sprintf(s->command, "*wm%08x.w=%04x", addr, data);
++ serialice_command(s->command, 0);
+}
+
+void serialice_writel(uint32_t data, uint32_t addr)
+{
-+ char command[29];
-+ sprintf(command, "*wm%08x.l=%08x", addr, data);
-+ // command read back: "\n> " (3 characters)
-+ serialice_command(command, 3);
++ sprintf(s->command, "*wm%08x.l=%08x", addr, data);
++ serialice_command(s->command, 0);
+}
+
-+uint64_t serialice_rdmsr(uint32_t addr)
++uint64_t serialice_rdmsr(uint32_t addr, uint32_t key)
+{
+ uint32_t hi, lo;
+ uint64_t ret;
@@ -628,13 +670,11 @@
+
+ filtered = serialice_msr_filter(FILTER_READ, addr, &hi, &lo);
+ if (!filtered) {
-+ char command[18];
++ sprintf(s->command, "*rc%08x.%08x", addr, key);
+
-+ sprintf(command, "*rc%08x", addr);
++ // command read back: "\n00000000.00000000" (18 characters)
++ serialice_command(s->command, 18);
+
-+ // command read back: "\n00000000.00000000\n> " (21 characters)
-+ serialice_command(command, 21);
-+
+ 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);
@@ -649,7 +689,7 @@
+ return ret;
+}
+
-+void serialice_wrmsr(uint64_t data, uint32_t addr)
++void serialice_wrmsr(uint64_t data, uint32_t addr, uint32_t key)
+{
+ uint32_t hi, lo;
+ int filtered;
@@ -660,10 +700,8 @@
+ filtered = serialice_msr_filter(FILTER_WRITE, addr, &hi, &lo);
+
+ if (!filtered) {
-+ char command[30];
-+ sprintf(command, "*wc%08x=%08x.%08x", addr, hi, lo);
-+ // command read back: "\n> " (3 characters)
-+ serialice_command(command, 3);
++ sprintf(s->command, "*wc%08x.%08x=%08x.%08x", addr, key, hi, lo);
++ serialice_command(s->command, 0);
+ }
+
+ serialice_msr_log(LOG_WRITE, addr, hi, lo, filtered);
@@ -681,14 +719,12 @@
+
+ filtered = serialice_cpuid_filter(&ret);
+ if (!filtered) {
-+ char command[27];
++ sprintf(s->command, "*ci%08x.%08x", eax, ecx);
+
-+ sprintf(command, "*ci%08x.%08x", eax, ecx);
++ // command read back: "\n000006f2.00000000.00001234.12340324"
++ // (36 characters)
++ serialice_command(s->command, 36);
+
-+ // command read back: "\n000006f2.00000000.00001234.12340324\n> "
-+ // (39 characters)
-+ serialice_command(command, 39);
-+
+ s->buffer[9] = 0; // . -> \0
+ s->buffer[18] = 0; // . -> \0
+ s->buffer[27] = 0; // . -> \0
@@ -799,7 +835,7 @@
+}
+
+// **************************************************************************
-+// external initialization and exit
++// initialization and exit
+
+void serialice_init(void)
+{
@@ -811,7 +847,32 @@
+ }
+
+ s = qemu_mallocz(sizeof(SerialICEState));
++#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) {
@@ -848,34 +909,77 @@
+ 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... ");
-+ serialice_command("\n", 3);
+
-+ if (!strncmp("\n> ", s->buffer, 3)) {
++ /* Trigger a prompt */
++ serialice_write(s, "\n", 1);
++
++ /* ... and wait for it to appear */
++ if (serialice_wait_prompt() == 0) {
+ printf("target alife!\n");
+ } else {
-+ printf("target not ok! (%s)\n", s->buffer );
++ 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, "\n", 1);
++
+ printf("SerialICE: LUA init...\n");
+ serialice_lua_init();
++
++ /* Let the rest of Qemu know we're alife */
++ serialice_active = 1;
+}
+
+void serialice_exit(void)
+{
+ serialice_lua_exit();
++ qemu_free(s->command);
++ qemu_free(s->buffer);
++ qemu_free(s);
+}
+
++device_init(serialice_init)
++// no exit function
++
--- qemu-0.11.0/serialice.h
+++ qemu-0.11.0/serialice.h
-@@ -0,0 +1,42 @@
-+#ifndef HW_SERIALICE_H
-+#define HW_SERIALICE_H
+@@ -0,0 +1,66 @@
++/*
++ * 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.
++ */
+
++#ifndef SERIALICE_H
++#define SERIALICE_H
++
+#include "config-host.h"
+
+extern const char *serialice_device;
@@ -900,8 +1004,8 @@
+void serialice_writew(uint16_t data, uint32_t addr);
+void serialice_writel(uint32_t data, uint32_t addr);
+
-+uint64_t serialice_rdmsr(uint32_t addr);
-+void serialice_wrmsr(uint64_t data, uint32_t addr);
++uint64_t serialice_rdmsr(uint32_t addr, uint32_t key);
++void serialice_wrmsr(uint64_t data, uint32_t addr, uint32_t key);
+
+typedef struct {
+ uint32_t eax, ebx, ecx, edx;
@@ -1280,7 +1384,7 @@
+#ifdef CONFIG_SERIALICE
+ if (serialice_active) {
-+ serialice_wrmsr(val, (uint32_t)ECX);
++ serialice_wrmsr(val, (uint32_t)ECX, (uint32_t)EDI);
+ return;
+ }
+#endif
@@ -1294,7 +1398,7 @@
+#ifdef CONFIG_SERIALICE
+ if (serialice_active) {
-+ val = serialice_rdmsr((uint32_t)ECX);
++ val = serialice_rdmsr((uint32_t)ECX, (uint32_t)EDI);
+ EAX = (uint32_t)(val);
+ EDX = (uint32_t)(val >> 32);
+ return;
@@ -1347,52 +1451,3 @@
cpu_register_physical_memory(0x100000000ULL,
above_4g_mem_size,
ram_addr);
-@@ -1468,6 +1481,24 @@
- initrd_filename, cpu_model, 0);
- }
-
-+#ifdef CONFIG_SERIALICE
-+static void serialice_init_pci(ram_addr_t ram_size,
-+ const char *boot_device,
-+ const char *kernel_filename,
-+ const char *kernel_cmdline,
-+ const char *initrd_filename,
-+ const char *cpu_model)
-+{
-+ serialice_active = 1;
-+
-+ pc_init1(ram_size, boot_device,
-+ kernel_filename, kernel_cmdline,
-+ initrd_filename, cpu_model, 1);
-+
-+ serialice_init();
-+}
-+#endif
-+
- /* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
- BIOS will read it and start S3 resume at POST Entry */
- void cmos_set_s3_resume(void)
-@@ -1515,11 +1546,23 @@
- .max_cpus = 1,
- };
-
-+#ifdef CONFIG_SERIALICE
-+static QEMUMachine serialice_machine = {
-+ .name = "serialice",
-+ .desc = "SerialICE",
-+ .init = serialice_init_pci,
-+ .max_cpus = 255,
-+};
-+#endif
-+
- static void pc_machine_init(void)
- {
- qemu_register_machine(&pc_machine);
- qemu_register_machine(&pc_machine_v0_10);
- qemu_register_machine(&isapc_machine);
-+#ifdef CONFIG_SERIALICE
-+ qemu_register_machine(&serialice_machine);
-+#endif
- }
-
- machine_init(pc_machine_init);