diff --git a/urjtag/ChangeLog b/urjtag/ChangeLog index a1490566..9d597ebd 100644 --- a/urjtag/ChangeLog +++ b/urjtag/ChangeLog @@ -10,6 +10,15 @@ * configure.ac: Enable quiet automake rules when available. + * include/urjtag/jtag.h (urj_big_endian, urj_endian_t, urj_get_file_endian, + urj_set_file_endian, urj_endian_to_string, urj_endian_from_string): Replace + exposed endian storage with dedicated functions for parsing endians. + * src/global/log-error.c (urj_big_endian): Drop local storage. + * src/cmd/cmd_endian.c: Centralize all endian functions here. + * src/bus/readmem.c (urj_bus_readmem): Switch to new endian file functions. + * src/bus/writemem.c (urj_bus_writemem): Likewise. + * src/flash/flash.c (urj_flashmem): Likewise. + 2010-02-04 Jie Zhang * src/tap/cable/ft2232.c (ft2232_gnice_init_common): Replace diff --git a/urjtag/include/urjtag/jtag.h b/urjtag/include/urjtag/jtag.h index 889bb822..998c9445 100644 --- a/urjtag/include/urjtag/jtag.h +++ b/urjtag/include/urjtag/jtag.h @@ -27,7 +27,31 @@ #include "types.h" -extern int urj_big_endian; +typedef enum URJ_ENDIAN { + URJ_ENDIAN_LITTLE, + URJ_ENDIAN_BIG, + URJ_ENDIAN_UNKNOWN, +} urj_endian_t; + +/** + * Get the endian used in external files. See cmd_endian.c. + */ +urj_endian_t urj_get_file_endian (void); + +/** + * Set the endian used in external files. See cmd_endian.c. + */ +void urj_set_file_endian (urj_endian_t); + +/** + * Return the string representation of an endian type. + */ +const char *urj_endian_to_string (urj_endian_t); + +/** + * Convert an endian string representation into the normal type. + */ +urj_endian_t urj_endian_from_string (const char *); /** * Register the application name with global/data_dir. diff --git a/urjtag/src/bus/readmem.c b/urjtag/src/bus/readmem.c index 6c761361..86e07f20 100644 --- a/urjtag/src/bus/readmem.c +++ b/urjtag/src/bus/readmem.c @@ -107,7 +107,7 @@ urj_bus_readmem (urj_bus_t *bus, FILE *f, uint32_t addr, uint32_t len) data = URJ_BUS_READ_END (bus); for (j = step; j > 0; j--) - if (urj_big_endian) + if (urj_get_file_endian () == URJ_ENDIAN_BIG) b[bc++] = (data >> ((j - 1) * 8)) & 0xFF; else { diff --git a/urjtag/src/bus/writemem.c b/urjtag/src/bus/writemem.c index 9d51d032..4775d3d8 100644 --- a/urjtag/src/bus/writemem.c +++ b/urjtag/src/bus/writemem.c @@ -128,7 +128,7 @@ urj_bus_writemem (urj_bus_t *bus, FILE *f, uint32_t addr, uint32_t len) data = 0; for (j = step; j > 0 && bc > 0; j--) { - if (urj_big_endian) + if (urj_get_file_endian () == URJ_ENDIAN_BIG) { data <<= 8; /* first shift doesn't matter: data = 0 */ data |= b[bidx++]; diff --git a/urjtag/src/cmd/cmd_endian.c b/urjtag/src/cmd/cmd_endian.c index 44dd1817..c51a8044 100644 --- a/urjtag/src/cmd/cmd_endian.c +++ b/urjtag/src/cmd/cmd_endian.c @@ -34,9 +34,56 @@ #include "cmd.h" +static urj_endian_t current_file_endian = URJ_ENDIAN_LITTLE; + +urj_endian_t urj_get_file_endian (void) +{ + return current_file_endian; +} + +void urj_set_file_endian (urj_endian_t new_file_endian) +{ + current_file_endian = new_file_endian; +} + +static const struct { + const urj_endian_t endian; + const char *name; +} endians[] = { + { URJ_ENDIAN_LITTLE, "little", }, + { URJ_ENDIAN_BIG, "big", }, + { URJ_ENDIAN_UNKNOWN, "unknown" }, +}; + +const char *urj_endian_to_string (urj_endian_t endian) +{ + size_t idx; + + for (idx = 0; idx < ARRAY_SIZE(endians); ++idx) + if (endian == endians[idx].endian) + return endians[idx].name; + + /* last one is the "unknown" one */ + return endians[idx - 1].name; +} + +urj_endian_t urj_endian_from_string (const char *strendian) +{ + size_t idx; + + for (idx = 0; idx < ARRAY_SIZE(endians); ++idx) + if (!strcasecmp (endians[idx].name, strendian)) + return endians[idx].endian; + + /* last one is the "unknown" one */ + return endians[idx - 1].endian; +} + static int cmd_endian_run (urj_chain_t *chain, char *params[]) { + urj_endian_t new_endian; + if (urj_cmd_params (params) > 2) { urj_error_set (URJ_ERROR_SYNTAX, @@ -47,28 +94,21 @@ cmd_endian_run (urj_chain_t *chain, char *params[]) if (!params[1]) { - if (urj_big_endian) - urj_log (URJ_LOG_LEVEL_NORMAL, - _("Endianess for external files: big\n")); - else - urj_log (URJ_LOG_LEVEL_NORMAL, - _("Endianess for external files: little\n")); + urj_log (URJ_LOG_LEVEL_NORMAL, _("Endianess for external files: %s\n"), + urj_endian_to_string (urj_get_file_endian ())); return URJ_STATUS_OK; } - if (strcasecmp (params[1], "little") == 0) - { - urj_big_endian = 0; - return URJ_STATUS_OK; - } - if (strcasecmp (params[1], "big") == 0) + new_endian = urj_endian_from_string (params[1]); + if (new_endian != URJ_ENDIAN_UNKNOWN) { - urj_big_endian = 1; + urj_set_file_endian (new_endian); return URJ_STATUS_OK; } urj_error_set (URJ_ERROR_SYNTAX, - "endianness must be 'little' or 'big', not '%s'", params[1]); + _("endianness must be 'little' or 'big', not '%s'"), + params[1]); return URJ_STATUS_FAIL; } diff --git a/urjtag/src/flash/flash.c b/urjtag/src/flash/flash.c index 3cbb372b..93a22647 100644 --- a/urjtag/src/flash/flash.c +++ b/urjtag/src/flash/flash.c @@ -380,7 +380,7 @@ urj_flashmem (urj_bus_t *bus, FILE *f, uint32_t addr, int noverify) data = 0; for (j = 0; j < flash_driver->bus_width; j++) - if (urj_big_endian) + if (urj_get_file_endian () == URJ_ENDIAN_BIG) data = (data << 8) | b[bc + j]; else data |= b[bc + j] << (j * 8); @@ -442,7 +442,7 @@ urj_flashmem (urj_bus_t *bus, FILE *f, uint32_t addr, int noverify) data = 0; for (j = 0; j < flash_driver->bus_width; j++) - if (urj_big_endian) + if (urj_get_file_endian () == URJ_ENDIAN_BIG) data = (data << 8) | b[bc + j]; else data |= b[bc + j] << (j * 8); diff --git a/urjtag/src/global/log-error.c b/urjtag/src/global/log-error.c index 7c3ab7f5..458a4868 100644 --- a/urjtag/src/global/log-error.c +++ b/urjtag/src/global/log-error.c @@ -32,7 +32,6 @@ #include urj_error_state_t urj_error_state; -int urj_big_endian = 0; static int stderr_vprintf (const char *fmt, va_list ap); static int stdout_vprintf (const char *fmt, va_list ap);