diff --git a/frontpanel/FrontPanelTest.c b/frontpanel/FrontPanelTest.c index abbe1e8b..8506e7e9 100644 --- a/frontpanel/FrontPanelTest.c +++ b/frontpanel/FrontPanelTest.c @@ -62,6 +62,7 @@ unsigned int PCQ[32]; int PSL_bits[32]; int PC_bits[32]; int PC_indirect_bits[32]; +int PCQ_3_bits[32]; int update_display = 1; @@ -422,7 +423,7 @@ if (sim_panel_set_sampling_parameters_ex (panel, 500, 10, 100)) { goto Done; } if (sim_panel_add_register_indirect_bits (panel, "PC", NULL, 32, PC_indirect_bits)) { - printf ("Error adding register 'PSL' bits: %s\n", sim_panel_get_error()); + printf ("Error adding register 'PC' indirect bits: %s\n", sim_panel_get_error()); goto Done; } if (sim_panel_add_register_bits (panel, "PSL", NULL, 32, PSL_bits)) { @@ -433,6 +434,10 @@ if (sim_panel_add_register_bits (panel, "PC", NULL, 32, PC_bits)) { printf ("Error adding register 'PSL' bits: %s\n", sim_panel_get_error()); goto Done; } +if (sim_panel_add_register_bits (panel, "PCQ[3]", NULL, 32, PCQ_3_bits)) { + printf ("Error adding register 'PCQ[3]' bits: %s\n", sim_panel_get_error()); + goto Done; + } if (1) { unsigned int noop_noop_noop_halt = 0x00010101, addr400 = 0x00000400, pc_value; int mstime = 0; @@ -464,7 +469,24 @@ if (1) { goto Done; } if (pc_value != addr400 + 4) { - printf ("Unexpected error getting PC value: %08X, expected: %08X\n", pc_value, addr400 + 4); + printf ("Unexpected PC value after HALT: %08X, expected: %08X\n", pc_value, addr400 + 4); + goto Done; + } + if (sim_panel_gen_deposit (panel, "PC", sizeof(addr400), &addr400)) { + printf ("Error setting PC to %08X: %s\n", addr400, sim_panel_get_error()); + goto Done; + } + if (sim_panel_exec_step (panel)) { + printf ("Error executing a single step: %s\n", sim_panel_get_error()); + goto Done; + } + pc_value = 0; + if (sim_panel_gen_examine (panel, "PC", sizeof(pc_value), &pc_value)) { + printf ("Unexpected error getting PC value: %s\n", sim_panel_get_error()); + goto Done; + } + if (pc_value != addr400 + 1) { + printf ("Unexpected PC value after STEP: %08X, expected: %08X\n", pc_value, addr400 + 1); goto Done; } } diff --git a/sim_frontpanel.c b/sim_frontpanel.c index d111fca0..d0ac070b 100644 --- a/sim_frontpanel.c +++ b/sim_frontpanel.c @@ -217,8 +217,10 @@ static const char *register_collect_mid1 = " samples every "; static const char *register_collect_mid2 = " cycles dither "; static const char *register_collect_mid3 = " percent "; static const char *register_get_postfix = "sampleout"; -static const char *register_get_echo = "# REGISTERS-DONE"; -static const char *register_repeat_echo = "# REGISTERS-REPEAT-DONE"; +static const char *register_get_start = "# REGISTERS-START"; +static const char *register_get_end = "# REGISTERS-DONE"; +static const char *register_repeat_start = "# REGISTERS-REPEAT-START\r"; +static const char *register_repeat_end = "# REGISTERS-REPEAT-DONE"; static const char *register_dev_echo = "# REGISTERS-FOR-DEVICE:"; static const char *register_ind_echo = "# REGISTER-INDIRECT:"; static const char *command_status = "ECHO Status:%STATUS%-%TSTATUS%"; @@ -451,7 +453,9 @@ size_t i, j, buf_data, buf_needed = 0, reg_count = 0, bit_reg_count = 0; const char *dev; pthread_mutex_lock (&panel->io_lock); -buf_needed = 2 + strlen (register_get_prefix); /* SHOW TIME */ +buf_needed = 3 + + strlen (register_get_start) + /* # REGISTERS-START */ + strlen (register_get_prefix); /* SHOW TIME */ for (i=0; ireg_count; i++) { if (panel->regs[i].bits) ++bit_reg_count; @@ -466,7 +470,7 @@ for (i=0; ireg_count; i++) { } if (bit_reg_count) buf_needed += 2 + strlen (register_get_postfix); -buf_needed += 10 + strlen (register_get_echo); /* # REGISTERS-DONE */ +buf_needed += 10 + strlen (register_get_end); /* # REGISTERS-DONE */ if (buf_needed > *buf_size) { free (*buf); *buf = (char *)_panel_malloc (buf_needed); @@ -479,7 +483,7 @@ if (buf_needed > *buf_size) { } buf_data = 0; if (reg_count) { - sprintf (*buf + buf_data, "%s\r", register_get_prefix); + sprintf (*buf + buf_data, "%s\r%s\r", register_get_start, register_get_prefix); buf_data += strlen (*buf + buf_data); } dev = ""; @@ -540,7 +544,7 @@ if (bit_reg_count) { strcpy (*buf + buf_data, "\r"); buf_data += strlen (*buf + buf_data); } -strcpy (*buf + buf_data, register_get_echo); +strcpy (*buf + buf_data, register_get_end); buf_data += strlen (*buf + buf_data); strcpy (*buf + buf_data, "\r"); buf_data += strlen (*buf + buf_data); @@ -1435,7 +1439,7 @@ if (_panel_sendf (panel, &cmd_stat, NULL, "SHOW TIME\r")) panel->simulation_time_base += panel->simulation_time; if (_panel_sendf (panel, NULL, NULL, "BOOT %s\r", device)) return -1; -panel->State = Run; +msleep (100); /* Allow Run/Hslt state to settle */ return 0; } @@ -1464,7 +1468,7 @@ if (_panel_sendf (panel, &cmd_stat, NULL, "SHOW TIME\r")) panel->simulation_time_base += panel->simulation_time; if (_panel_sendf (panel, NULL, NULL, "RUN -Q\r", 5)) return -1; -panel->State = Run; +msleep (100); /* Allow Run/Hslt state to settle */ return 0; } @@ -1485,7 +1489,7 @@ if (panel->State == Run) { } if (_panel_sendf (panel, NULL, NULL, "CONT\r", 5)) return -1; -panel->State = Run; +msleep (100); /* Allow Run/Hslt state to settle */ return 0; } @@ -1507,7 +1511,6 @@ if (panel->State == Run) { if (5 != _panel_send (panel, "STEP\r", 5)) return -1; -panel->State = Run; return 0; } @@ -1951,11 +1954,12 @@ static void * _panel_reader(void *arg) { PANEL *p = (PANEL*)arg; -REG *r; +REG *r = NULL; int sched_policy; struct sched_param sched_priority; char buf[4096]; int buf_data = 0; +int processing_register_output = 0; /* Boost Priority for this response processing thread to quickly digest @@ -2020,183 +2024,194 @@ while ((p->sock != INVALID_SOCKET) && s = buf; while ((eol = strchr (s, '\n'))) { /* Line to process */ - r = NULL; *eol++ = '\0'; while ((*s) && (s[strlen(s)-1] == '\r')) s[strlen(s)-1] = '\0'; - e = strchr (s, ':'); - if (e) { - size_t i; - char smp_dev[32], smp_reg[32], smp_ind[32]; - unsigned int bit; + if (processing_register_output) { + e = strchr (s, ':'); + if (e) { + size_t i; + char smp_dev[32], smp_reg[32], smp_ind[32]; + unsigned int bit; - *e++ = '\0'; - if (!strcmp("Time", s)) { - p->simulation_time = strtoull (e, NULL, 10); - s = eol; - while (isspace(0xFF & (*s))) - ++s; - continue; /* process next line */ - } - if ((*s == '}') && - (3 == sscanf (s, "}%s %s %s", smp_dev, smp_reg, smp_ind))) { /* Register bit Sample Data? */ - r = NULL; - for (i=0; ireg_count; i++) { - if (p->regs[i].bits == NULL) - continue; - if ((!strcmp (smp_reg, p->regs[i].name)) && - ((!p->device_name) || (!strcmp (smp_dev, p->device_name)))) { - r = &p->regs[i]; - break; - } - } - if (r) { - for (bit = 0; bit < r->bit_count; bit++) { - int val = (int)strtol (e, &e, 10); - r->bits[bit] = val; - if (*e == ',') - ++e; - else - break; - } + *e++ = '\0'; + if (!strcmp("Time", s)) { + p->simulation_time = strtoull (e, NULL, 10); s = eol; + while (isspace(0xFF & (*s))) + ++s; + continue; /* process next line */ } - while (isspace(0xFF & (*s))) - ++s; - r = NULL; - continue; /* process next line */ - } - if (!strncmp (s + strlen (sim_prompt), register_ind_echo, strlen (register_ind_echo) - 1)) { - e = s + strlen (sim_prompt) + strlen (register_ind_echo); - r = NULL; - for (i=0; ireg_count; i++) { - if (p->regs[i].indirect && (!strcmp(p->regs[i].name, e))) { - r = &p->regs[i]; - break; + if ((*s == '}') && + (3 == sscanf (s, "}%s %s %s", smp_dev, smp_reg, smp_ind))) { /* Register bit Sample Data? */ + r = NULL; + for (i=0; ireg_count; i++) { + if (p->regs[i].bits == NULL) + continue; + if ((!strcmp (smp_reg, p->regs[i].name)) && + ((!p->device_name) || (!strcmp (smp_dev, p->device_name)))) { + r = &p->regs[i]; + break; + } } + if (r) { + for (bit = 0; bit < r->bit_count; bit++) { + int val = (int)strtol (e, &e, 10); + r->bits[bit] = val; + if (*e == ',') + ++e; + else + break; + } + s = eol; + } + while (isspace(0xFF & (*s))) + ++s; + r = NULL; + continue; /* process next line */ } - s = eol; - while (isspace(0xFF & (*s))) - ++s; - if (r) - continue; /* process next line */ - } - if (!p->io_waiting) { - if (r) { - if (strcmp (s, r->name)) { - unsigned long long data; - - data = strtoull (e, NULL, 16); - if (little_endian) - memcpy (r->addr, &data, r->size); - else - memcpy (r->addr, ((char *)&data) + sizeof(data)-r->size, r->size); - r = NULL; + if (!strncmp (s + strlen (sim_prompt), register_ind_echo, strlen (register_ind_echo) - 1)) { + e = s + strlen (sim_prompt) + strlen (register_ind_echo); + r = NULL; + for (i=0; ireg_count; i++) { + if (p->regs[i].indirect && (!strcmp(p->regs[i].name, e))) { + r = &p->regs[i]; + break; + } } s = eol; while (isspace(0xFF & (*s))) ++s; - continue; /* process next line */ + if (r) + continue; /* process next line */ } - for (i=0; ireg_count; i++) { - if (p->regs[i].element_count == 0) { - if (!strcmp(p->regs[i].name, s)) { + if (!p->io_waiting) { + if (r) { + if (strcmp (s, r->name)) { unsigned long long data; data = strtoull (e, NULL, 16); if (little_endian) - memcpy (p->regs[i].addr, &data, p->regs[i].size); + memcpy (r->addr, &data, r->size); else - memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size); - break; + memcpy (r->addr, ((char *)&data) + sizeof(data)-r->size, r->size); + r = NULL; } + s = eol; + while (isspace(0xFF & (*s))) + ++s; + continue; /* process next line */ } - else { - size_t name_len = strlen (p->regs[i].name); + for (i=0; ireg_count; i++) { + if (p->regs[i].element_count == 0) { + if (!strcmp(p->regs[i].name, s)) { + unsigned long long data; - if ((0 == memcmp (p->regs[i].name, s, name_len)) && (s[name_len] == '[')) { - size_t array_index = (size_t)atoi (s + name_len + 1); - size_t end_index = array_index; - char *end = strchr (s + name_len + 1, '['); - - if (end) - end_index = (size_t)atoi (end + 1); - if (strcmp (e, " same as above")) - p->array_element_data = strtoull (e, NULL, 16); - while (array_index <= end_index) { + data = strtoull (e, NULL, 16); if (little_endian) - memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), &p->array_element_data, p->regs[i].size); + memcpy (p->regs[i].addr, &data, p->regs[i].size); else - memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), ((char *)&p->array_element_data) + sizeof(p->array_element_data)-p->regs[i].size, p->regs[i].size); - ++array_index; + memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size); + break; + } + } + else { + size_t name_len = strlen (p->regs[i].name); + + if ((0 == memcmp (p->regs[i].name, s, name_len)) && (s[name_len] == '[')) { + size_t array_index = (size_t)atoi (s + name_len + 1); + size_t end_index = array_index; + char *end = strchr (s + name_len + 1, '['); + + if (end) + end_index = (size_t)atoi (end + 1); + if (strcmp (e, " same as above")) + p->array_element_data = strtoull (e, NULL, 16); + while (array_index <= end_index) { + if (little_endian) + memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), &p->array_element_data, p->regs[i].size); + else + memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), ((char *)&p->array_element_data) + sizeof(p->array_element_data)-p->regs[i].size, p->regs[i].size); + ++array_index; + } + break; } - break; } } + if (i != p->reg_count) { + s = eol; + while (isspace(0xFF & (*s))) + ++s; + continue; + } } - if (i != p->reg_count) { - s = eol; - while (isspace(0xFF & (*s))) - ++s; - continue; - } + --e; + *e = ':'; + /* Unexpected Register Data Found (or other output containing a : character) */ } - --e; - *e = ':'; - /* Unexpected Register Data Found (or other output containing a : character) */ } - if (!strcmp (s + strlen (sim_prompt), register_repeat_echo)) { + if (!strcmp (s + strlen (sim_prompt), register_repeat_end)) { + _panel_debug (p, DBG_RCV, "*Repeat Block Complete", NULL, 0); if (p->callback) { pthread_mutex_unlock (&p->io_lock); p->callback (p, p->simulation_time_base + p->simulation_time, p->callback_context); pthread_mutex_lock (&p->io_lock); } + processing_register_output = 0; + goto Start_Next_Line; } - if (!strcmp (s + strlen (sim_prompt), register_get_echo)) { + if ((!strcmp (s + strlen (sim_prompt), register_repeat_start)) || + (!strcmp (s + strlen (sim_prompt), register_get_start))) { + _panel_debug (p, DBG_RCV, "*Repeat/Register Block Starting", NULL, 0); + processing_register_output = 1; + goto Start_Next_Line; + } + if (!strcmp (s + strlen (sim_prompt), register_get_end)) { + _panel_debug (p, DBG_RCV, "*Register Block Complete", NULL, 0); --p->io_reg_query_pending; p->io_waiting = 0; pthread_cond_signal (&p->io_done); + goto Start_Next_Line; } - else { - if (!strcmp (s + strlen (sim_prompt), command_done_echo)) { - _panel_debug (p, DBG_RCV, "Received Command Complete", NULL, 0); - p->io_waiting = 0; - pthread_cond_signal (&p->io_done); - } - else { - /* Non Register Data Found (echo of EXAMINE or other commands and/or command output) */ - if (p->io_waiting) { - char *t; + if (!strcmp (s + strlen (sim_prompt), command_done_echo)) { + _panel_debug (p, DBG_RCV, "*Received Command Complete", NULL, 0); + p->io_waiting = 0; + pthread_cond_signal (&p->io_done); + goto Start_Next_Line; + } + /* Non Register Data Found (echo of EXAMINE or other commands and/or command output) */ + if (p->io_waiting) { + char *t; - if (p->io_response_data + strlen (s) + 3 > p->io_response_size) { - t = (char *)_panel_malloc (p->io_response_data + strlen (s) + 3); - if (t == NULL) { - _panel_debug (p, DBG_RCV, "%s", NULL, 0, sim_panel_get_error()); - p->State = Error; - break; - } - memcpy (t, p->io_response, p->io_response_data); - free (p->io_response); - p->io_response = t; - p->io_response_size = p->io_response_data + strlen (s) + 3; - } - _panel_debug (p, DBG_RCV, "Receive Data Accumulated: '%s'", NULL, 0, s); - strcpy (p->io_response + p->io_response_data, s); - p->io_response_data += strlen(s); - strcpy (p->io_response + p->io_response_data, "\r\n"); - p->io_response_data += 2; + if (p->io_response_data + strlen (s) + 3 > p->io_response_size) { + t = (char *)_panel_malloc (p->io_response_data + strlen (s) + 3); + if (t == NULL) { + _panel_debug (p, DBG_RCV, "%s", NULL, 0, sim_panel_get_error()); + p->State = Error; + break; } - else - _panel_debug (p, DBG_RCV, "Receive Data Discarded: '%s'", NULL, 0, s); + memcpy (t, p->io_response, p->io_response_data); + free (p->io_response); + p->io_response = t; + p->io_response_size = p->io_response_data + strlen (s) + 3; } + _panel_debug (p, DBG_RCV, "Receive Data Accumulated: '%s'", NULL, 0, s); + strcpy (p->io_response + p->io_response_data, s); + p->io_response_data += strlen(s); + strcpy (p->io_response + p->io_response_data, "\r\n"); + p->io_response_data += 2; } + else + _panel_debug (p, DBG_RCV, "Receive Data Discarded: '%s'", NULL, 0, s); +Start_Next_Line: s = eol; while (isspace(0xFF & (*s))) ++s; } memmove (buf, s, strlen (s)+1); buf_data = strlen (buf); - _panel_debug (p, DBG_RSP, "Remnant Buffer Contents: '%s'", NULL, 0, buf); + if (buf_data) + _panel_debug (p, DBG_RSP, "Remnant Buffer Contents: '%s'", NULL, 0, buf); if (!memcmp ("Simulator Running...", buf, 20)) { _panel_debug (p, DBG_RSP, "State transitioning to Run", NULL, 0); p->State = Run; @@ -2280,22 +2295,25 @@ while ((p->sock != INVALID_SOCKET) && strlen (register_repeat_units) + /* units and spacing */ buf_data + /* command contents */ 1 + /* carriage return */ - strlen (register_repeat_echo) + /* auto repeat completion */ + strlen (register_repeat_start) + /* auto repeat begin */ + 1 + /* carriage return */ + strlen (register_repeat_end) + /* auto repeat completion */ 1 + /* carriage return */ 1; /* NUL */ char *repeat = (char *)malloc (repeat_data); char *c; - sprintf (repeat, "%s%d%s%*.*s", register_repeat_prefix, + sprintf (repeat, "%s%d%s%s%*.*s", register_repeat_prefix, p->usecs_between_callbacks, register_repeat_units, + register_repeat_start, (int)buf_data, (int)buf_data, buf); pthread_mutex_unlock (&p->io_lock); for (c = strchr (repeat, '\r'); c != NULL; c = strchr (c, '\r')) *c = ';'; /* replace carriage returns with semicolons */ - c = strstr (repeat, register_get_echo); /* remove register_done_echo string and */ + c = strstr (repeat, register_get_end); /* remove register_done_echo string and */ if (c) /* always true */ - strcpy (c, register_repeat_echo); /* replace it with the register_repeat_echo string */ + strcpy (c, register_repeat_end); /* replace it with the register_repeat_end string */ if (_panel_sendf (p, &cmd_stat, NULL, "%s", repeat)) { pthread_mutex_lock (&p->io_lock); free (repeat); @@ -2450,32 +2468,36 @@ ret = ((len + status_echo_len) == (sent_len = _panel_send (p, buf, len + status_ if (completion_status) { if (!ret) { /* Sent OK? */ + char *tresponse = NULL; + p->io_waiting = 1; while (p->io_waiting) pthread_cond_wait (&p->io_done, &p->io_lock); /* Wait for completion */ - if (response) { - *response = (char *)_panel_malloc (p->io_response_data + 1); - if (0 == memcmp (buf, p->io_response + strlen (sim_prompt), len)) { - char *eol, *status; - memcpy (*response, p->io_response + strlen (sim_prompt) + len + 1, p->io_response_data + 1 - (strlen (sim_prompt) + len + 1)); - *completion_status = -1; - status = strstr (*response, command_status); - if (status) { - *(status - strlen (sim_prompt)) = '\0'; - status += strlen (command_status) + 2; - eol = strchr (status, '\r'); - if (eol) - *eol = '\0'; - sscanf (status, "Status:%08X-", completion_status); - } + tresponse = (char *)_panel_malloc (p->io_response_data + 1); + if (0 == memcmp (buf, p->io_response + strlen (sim_prompt), len)) { + char *eol, *status; + memcpy (tresponse, p->io_response + strlen (sim_prompt) + len + 1, p->io_response_data + 1 - (strlen (sim_prompt) + len + 1)); + *completion_status = -1; + status = strstr (tresponse, command_status); + if (status) { + *(status - strlen (sim_prompt)) = '\0'; + status += strlen (command_status) + 2; + eol = strchr (status, '\r'); + if (eol) + *eol = '\0'; + sscanf (status, "Status:%08X-", completion_status); } - else - memcpy (*response, p->io_response, p->io_response_data + 1); + } + else + memcpy (tresponse, p->io_response, p->io_response_data + 1); + if (response) { + *response = tresponse; _panel_debug (p, DBG_RSP, "Command %d Response(Status=%d): '%s'", NULL, 0, p->command_count, *completion_status, *response); } else { + free (tresponse); if (p->io_response_data) - _panel_debug (p, DBG_RSP, "Discarded Unwanted Command %d Response Data:", p->io_response, p->io_response_data, p->command_count); + _panel_debug (p, DBG_RSP, "Discarded Unwanted Command %d Response Data(Status=%d):", p->io_response, p->io_response_data, p->command_count, *completion_status); } } p->io_response_data = 0; diff --git a/sim_frontpanel.h b/sim_frontpanel.h index ea862450..dca0a51a 100644 --- a/sim_frontpanel.h +++ b/sim_frontpanel.h @@ -56,7 +56,7 @@ extern "C" { #if !defined(__VAX) /* Unsupported platform */ -#define SIM_FRONTPANEL_VERSION 6 +#define SIM_FRONTPANEL_VERSION 7 /**