Author: stepan Date: 2009-11-18 19:57:14 +0100 (Wed, 18 Nov 2009) New Revision: 44
Modified: trunk/qemu-0.11.0/serialice.c Log: * read the prompt _before_ sending a command, not after. * when reading the prompt, read until there is a valid prompt
These changes might slightly speed up emulation, but the real benefit is that SerialICE should survive all kinds of reset scenarios now without changing the shell.
Modified: trunk/qemu-0.11.0/serialice.c =================================================================== --- trunk/qemu-0.11.0/serialice.c 2009-11-18 17:51:02 UTC (rev 43) +++ trunk/qemu-0.11.0/serialice.c 2009-11-18 18:57:14 UTC (rev 44) @@ -333,7 +333,6 @@ { int result;
- lua_getfield(L, LUA_GLOBALSINDEX, "SerialICE_cpuid_log");
lua_pushinteger(L, eax); // input: eax @@ -360,7 +359,7 @@ int bytes_read = 0;
while (1) { - int ret = read(state->fd, buf, nbyte); + int ret = read(state->fd, buf, nbyte - bytes_read);
if (ret == -1 && errno == EINTR) continue; @@ -395,6 +394,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 @@ -402,6 +426,8 @@ #endif int l;
+ serialice_wait_prompt(); + serialice_write(s, command, strlen(command)); memset(s->buffer, 0, reply_len + 1); // clear enough of the buffer @@ -440,8 +466,8 @@ return data & 0xff;
sprintf(command, "*ri%04x.b", port); - // command read back: "\n00\n> " (6 characters) - serialice_command(command, 6); + // command read back: "\n00" (3 characters) + serialice_command(command, 3); ret = (uint8_t)strtoul(s->buffer + 1, (char **)NULL, 16);
serialice_log(LOG_READ|LOG_IO, ret, port, 1); @@ -459,8 +485,8 @@ return data & 0xffff;
sprintf(command, "*ri%04x.w", port); - // command read back: "\n0000\n> " (8 characters) - serialice_command(command, 8); + // command read back: "\n0000" (5 characters) + serialice_command(command, 5); ret = (uint16_t)strtoul(s->buffer + 1, (char **)NULL, 16);
serialice_log(LOG_READ|LOG_IO, ret, port, 2); @@ -478,8 +504,8 @@ return data;
sprintf(command, "*ri%04x.l", port); - // command read back: "\n00000000\n> " (12 characters) - serialice_command(command, 12); + // command read back: "\n00000000" (9 characters) + serialice_command(command, 9); ret = (uint32_t)strtoul(s->buffer + 1, (char **)NULL, 16);
serialice_log(LOG_READ|LOG_IO, ret, port, 4); @@ -500,8 +526,7 @@
data = (uint8_t)filtered_data; sprintf(command, "*wi%04x.b=%02x", port, data); - // command read back: "\n> " (3 characters) - serialice_command(command, 3); + serialice_command(command, 0); }
void serialice_outw(uint16_t data, uint16_t port) @@ -517,8 +542,7 @@
data = (uint16_t)filtered_data; sprintf(command, "*wi%04x.w=%04x", port, data); - // command read back: "\n> " (3 characters) - serialice_command(command, 3); + serialice_command(command, 0); }
void serialice_outl(uint32_t data, uint16_t port) @@ -534,8 +558,7 @@
data = filtered_data; sprintf(command, "*wi%04x.l=%08x", port, data); - // command read back: "\n> " (3 characters) - serialice_command(command, 3); + serialice_command(command, 0); }
uint8_t serialice_readb(uint32_t addr) @@ -543,8 +566,8 @@ uint8_t ret; char command[20]; sprintf(command, "*rm%08x.b", addr); - // command read back: "\n00\n> " (6 characters) - serialice_command(command, 6); + // command read back: "\n00" (3 characters) + serialice_command(command, 3); ret = (uint8_t)strtoul(s->buffer + 1, (char **)NULL, 16); return ret; } @@ -554,8 +577,8 @@ uint16_t ret; char command[20]; sprintf(command, "*rm%08x.w", addr); - // command read back: "\n0000\n> " (8 characters) - serialice_command(command, 8); + // command read back: "\n0000" (5 characters) + serialice_command(command, 5); ret = (uint16_t)strtoul(s->buffer + 1, (char **)NULL, 16); return ret; } @@ -565,8 +588,8 @@ uint32_t ret; char command[20]; sprintf(command, "*rm%08x.l", addr); - // command read back: "\n00000000\n> " (12 characters) - serialice_command(command, 12); + // command read back: "\n00000000" (9 characters) + serialice_command(command, 9); ret = (uint32_t)strtoul(s->buffer + 1, (char **)NULL, 16); return ret; } @@ -575,24 +598,21 @@ { char command[24]; sprintf(command, "*wm%08x.b=%02x", addr, data); - // command read back: "\n> " (3 characters) - serialice_command(command, 3); + serialice_command(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); + serialice_command(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); + serialice_command(command, 0); }
uint64_t serialice_rdmsr(uint32_t addr) @@ -607,8 +627,8 @@
sprintf(command, "*rc%08x", addr);
- // command read back: "\n00000000.00000000\n> " (21 characters) - serialice_command(command, 21); + // command read back: "\n00000000.00000000" (18 characters) + serialice_command(command, 18);
s->buffer[9] = 0; // . -> \0 hi = (uint32_t)strtoul(s->buffer + 1, (char **)NULL, 16); @@ -637,8 +657,7 @@ if (!filtered) { char command[30]; sprintf(command, "*wc%08x=%08x.%08x", addr, hi, lo); - // command read back: "\n> " (3 characters) - serialice_command(command, 3); + serialice_command(command, 0); }
serialice_msr_log(LOG_WRITE, addr, hi, lo, filtered); @@ -660,9 +679,9 @@
sprintf(command, "*ci%08x.%08x", eax, ecx);
- // command read back: "\n000006f2.00000000.00001234.12340324\n> " - // (39 characters) - serialice_command(command, 39); + // command read back: "\n000006f2.00000000.00001234.12340324" + // (36 characters) + serialice_command(command, 36);
s->buffer[9] = 0; // . -> \0 s->buffer[18] = 0; // . -> \0 @@ -827,15 +846,23 @@ s->buffer = 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(); }