diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 6cbce86491..f5cf56459c 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -2,7 +2,7 @@ # Copyright (C) 2020 by Tarek BOUCHKATI -on: pull_request +on: push name: OpenOCD Snapshot @@ -30,7 +30,7 @@ jobs: echo "LIBUSB1_SRC=$PWD/libusb-${LIBUSB1_VER}" >> $GITHUB_ENV - name: Prepare hidapi env: - HIDAPI_VER: 0.11.2 + HIDAPI_VER: 0.13.1 run: | mkdir -p $DL_DIR && cd $DL_DIR wget "https://github.com/libusb/hidapi/archive/hidapi-${HIDAPI_VER}.tar.gz" @@ -56,6 +56,16 @@ jobs: wget "https://github.com/aquynh/capstone/archive/${CAPSTONE_VER}.tar.gz" tar -xzf ${CAPSTONE_VER}.tar.gz echo "CAPSTONE_SRC=$PWD/capstone-${CAPSTONE_VER}" >> $GITHUB_ENV + - name: Prepare libjaylink + env: + LIBJAYLINK_VER: 0.3.1 + run: | + mkdir -p $DL_DIR && cd $DL_DIR + wget https://gitlab.zapb.de/libjaylink/libjaylink/-/archive/${LIBJAYLINK_VER}/libjaylink-${LIBJAYLINK_VER}.tar.gz + tar -xzf libjaylink-${LIBJAYLINK_VER}.tar.gz + cd libjaylink-${LIBJAYLINK_VER} + ./autogen.sh + echo "LIBJAYLINK_SRC=$PWD" >> $GITHUB_ENV - name: Package OpenOCD for windows env: MAKE_JOBS: 2 @@ -64,7 +74,7 @@ jobs: HIDAPI_CONFIG: --enable-shared --disable-static --disable-testgui LIBFTDI_CONFIG: -DSTATICLIBS=OFF -DEXAMPLES=OFF -DFTDI_EEPROM=OFF CAPSTONE_CONFIG: "CAPSTONE_BUILD_CORE_ONLY=yes CAPSTONE_STATIC=yes CAPSTONE_SHARED=no" - CAPSTONE_CFLAGS: -I$(CAPSTONE_SRC)/include/capstone + LIBJAYLINK_CONFIG: --enable-shared --disable-static run: | # check if there is tag pointing at HEAD, otherwise take the HEAD SHA-1 as OPENOCD_TAG OPENOCD_TAG="`git tag --points-at HEAD`" @@ -83,6 +93,7 @@ jobs: # add missing dlls cd $HOST-root/usr cp `$HOST-gcc --print-file-name=libwinpthread-1.dll` ./bin/ + # required by libftdi1.dll. For the gcc-mingw-10.3.x or later "libgcc_s_dw2-1.dll" will need to be copied. cp `$HOST-gcc --print-file-name=libgcc_s_sjlj-1.dll` ./bin/ # prepare the artifact ARTIFACT="openocd-${OPENOCD_TAG}-${HOST}.tar.gz" @@ -90,9 +101,23 @@ jobs: echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV echo "IS_PRE_RELEASE=$IS_PRE_RELEASE" >> $GITHUB_ENV echo "ARTIFACT_PATH=$PWD/$ARTIFACT" >> $GITHUB_ENV - echo "ARTIFACT_NAME=openocd-windows-${OPENOCD_TAG}" >> $GITHUB_ENV - name: Publish OpenOCD packaged for windows - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: - name: ${{ env.ARTIFACT_NAME }} path: ${{ env.ARTIFACT_PATH }} + - name: Delete 'latest' Release + uses: dev-drprasad/delete-tag-and-release@v0.2.1 + with: + delete_release: true + tag_name: ${{ env.RELEASE_NAME }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Create Release + uses: ncipollo/release-action@v1 + with: + tag: ${{ env.RELEASE_NAME }} + commit: ${{ github.sha }} + draft: false + artifacts: ${{ env.ARTIFACT_PATH }} + prerelease: ${{ env.IS_PRE_RELEASE }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/contrib/cross-build.sh b/contrib/cross-build.sh index ded1691920..f1bd04df3e 100755 --- a/contrib/cross-build.sh +++ b/contrib/cross-build.sh @@ -41,12 +41,14 @@ WORK_DIR=$PWD : ${HIDAPI_SRC:=/path/to/hidapi} : ${LIBFTDI_SRC:=/path/to/libftdi} : ${CAPSTONE_SRC:=/path/to/capstone} +: ${LIBJAYLINK_SRC:=/path/to/libjaylink} OPENOCD_SRC=`readlink -m $OPENOCD_SRC` LIBUSB1_SRC=`readlink -m $LIBUSB1_SRC` HIDAPI_SRC=`readlink -m $HIDAPI_SRC` LIBFTDI_SRC=`readlink -m $LIBFTDI_SRC` CAPSTONE_SRC=`readlink -m $CAPSTONE_SRC` +LIBJAYLINK_SRC=`readlink -m $LIBJAYLINK_SRC` HOST_TRIPLET=$1 BUILD_DIR=$WORK_DIR/$HOST_TRIPLET-build @@ -54,6 +56,7 @@ LIBUSB1_BUILD_DIR=$BUILD_DIR/libusb1 HIDAPI_BUILD_DIR=$BUILD_DIR/hidapi LIBFTDI_BUILD_DIR=$BUILD_DIR/libftdi CAPSTONE_BUILD_DIR=$BUILD_DIR/capstone +LIBJAYLINK_BUILD_DIR=$BUILD_DIR/libjaylink OPENOCD_BUILD_DIR=$BUILD_DIR/openocd ## Root of host file tree @@ -158,6 +161,16 @@ libdir=${exec_prefix}/lib \ includedir=${prefix}/include/capstone\n\n;' $CAPSTONE_PC_FILE fi +# libjaylink build & install into sysroot +if [ -d $LIBJAYLINK_SRC ] ; then + mkdir -p $LIBJAYLINK_BUILD_DIR + cd $LIBJAYLINK_BUILD_DIR + $LIBJAYLINK_SRC/configure --build=`$LIBJAYLINK_SRC/config.guess` --host=$HOST_TRIPLET \ + --with-sysroot=$SYSROOT --prefix=$PREFIX \ + $LIBJAYLINK_CONFIG + make -j $MAKE_JOBS + make install DESTDIR=$SYSROOT +fi # OpenOCD build & install into sysroot mkdir -p $OPENOCD_BUILD_DIR diff --git a/doc/openocd.texi b/doc/openocd.texi index 4883e66da2..eb9f92f352 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -8811,7 +8811,6 @@ power consumption (because the CPU is needlessly clocked). @deffn {Command} {resume} [address] Resume the target at its current code position, or the optional @var{address} if it is provided. -OpenOCD will wait 5 seconds for the target to resume. @end deffn @deffn {Command} {step} [address] @@ -9132,8 +9131,10 @@ format. Optional @option{start} and @option{end} parameters allow to limit the address range. @end deffn -@deffn {Command} {version} -Displays a string identifying the version of this OpenOCD server. +@deffn {Command} {version} [git] +Returns a string identifying the version of this OpenOCD server. +With option @option{git}, it returns the git version obtained at compile time +through ``git describe''. @end deffn @deffn {Command} {virt2phys} virtual_address @@ -11665,8 +11666,8 @@ way to represent JTAG test patterns in text files. In a debug session using JTAG for its transport protocol, OpenOCD supports running such test files. -@deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{[-]quiet}] @ - [@option{[-]nil}] [@option{[-]progress}] [@option{[-]ignore_error}] @ +@deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{-quiet}] @ + [@option{-nil}] [@option{-progress}] [@option{-ignore_error}] @ [@option{-noreset}] [@option{-addcycles @var{cyclecount}}] This issues a JTAG reset (Test-Logic-Reset) and then runs the SVF script from @file{filename}. @@ -11680,11 +11681,11 @@ Command options: specified by the SVF file with HIR, TIR, HDR and TDR commands; instead, calculate them automatically according to the current JTAG chain configuration, targeting @var{tapname}; -@item @option{[-]quiet} do not log every command before execution; -@item @option{[-]nil} ``dry run'', i.e., do not perform any operations +@item @option{-quiet} do not log every command before execution; +@item @option{-nil} ``dry run'', i.e., do not perform any operations on the real interface; -@item @option{[-]progress} enable progress indication; -@item @option{[-]ignore_error} continue execution despite TDO check +@item @option{-progress} enable progress indication; +@item @option{-ignore_error} continue execution despite TDO check errors. @item @option{-noreset} omit JTAG reset (Test-Logic-Reset) before executing content of the SVF file; diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 0562906b92..7723a1755e 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -815,6 +815,7 @@ COMMAND_HANDLER(handle_flash_write_bank_command) if (buf_cnt != length) { LOG_ERROR("Short read"); free(buffer); + fileio_close(fileio); return ERROR_FAIL; } @@ -1325,40 +1326,27 @@ COMMAND_HANDLER(handle_flash_banks_command) return ERROR_OK; } -static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_flash_list) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, - "no arguments to 'flash list' command"); - return JIM_ERR; - } - - Jim_Obj *list = Jim_NewListObj(interp, NULL, 0); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; for (struct flash_bank *p = flash_bank_list(); p; p = p->next) { - Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0); - - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->name, -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "driver", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "target", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, target_name(p->target), -1)); - - Jim_ListAppendElement(interp, list, elem); + command_print(CMD, + "{\n" + " name %s\n" + " driver %s\n" + " base " TARGET_ADDR_FMT "\n" + " size 0x%" PRIx32 "\n" + " bus_width %u\n" + " chip_width %u\n" + " target %s\n" + "}", + p->name, p->driver->name, p->base, p->size, p->bus_width, p->chip_width, + target_name(p->target)); } - Jim_SetResult(interp, list); - - return JIM_OK; + return ERROR_OK; } COMMAND_HANDLER(handle_flash_init_command) @@ -1405,8 +1393,9 @@ static const struct command_registration flash_config_command_handlers[] = { { .name = "list", .mode = COMMAND_ANY, - .jim_handler = jim_flash_list, + .handler = handle_flash_list, .help = "Returns a list of details about the flash banks.", + .usage = "", }, COMMAND_REGISTRATION_DONE }; diff --git a/src/helper/command.c b/src/helper/command.c index b358e18aa4..235bec8580 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -662,19 +662,19 @@ void command_done(struct command_context *cmd_ctx) } /* find full path to file */ -static int jim_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_find) { - if (argc != 2) - return JIM_ERR; - const char *file = Jim_GetString(argv[1], NULL); - char *full_path = find_file(file); + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + char *full_path = find_file(CMD_ARGV[0]); if (!full_path) - return JIM_ERR; - Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path)); + return ERROR_COMMAND_ARGUMENT_INVALID; + + command_print(CMD, "%s", full_path); free(full_path); - Jim_SetResult(interp, result); - return JIM_OK; + return ERROR_OK; } COMMAND_HANDLER(handle_echo) @@ -1165,7 +1165,7 @@ static const struct command_registration command_builtin_handlers[] = { { .name = "ocd_find", .mode = COMMAND_ANY, - .jim_handler = jim_find, + .handler = handle_find, .help = "find full path to file", .usage = "file", }, diff --git a/src/helper/compiler.h b/src/helper/compiler.h index 33a075d64f..312d261fc3 100644 --- a/src/helper/compiler.h +++ b/src/helper/compiler.h @@ -36,9 +36,11 @@ * clang for Apple defines * #define __nonnull _Nonnull * that is a per argument attribute, incompatible with the gcc per function attribute __nonnull__. - * Undefine it to keep compatibility among compilers. + * gcc for Apple includes sys/cdefs.h from MacOSX.sdk that defines + * #define __nonnull + * In both cases, undefine __nonnull to keep compatibility among compilers and platforms. */ -#if defined(__clang__) && defined(__APPLE__) +#if defined(__APPLE__) # undef __nonnull #endif #ifndef __nonnull diff --git a/src/helper/list.h b/src/helper/list.h index 552a3202a5..c9de0569bc 100644 --- a/src/helper/list.h +++ b/src/helper/list.h @@ -27,13 +27,6 @@ struct list_head { struct list_head *next, *prev; }; -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; /* end local changes */ /* @@ -272,8 +265,7 @@ static inline void list_bulk_move_tail(struct list_head *head, * @param list the entry to test * @param head the head of the list */ -static inline int list_is_first(const struct list_head *list, - const struct list_head *head) +static inline int list_is_first(const struct list_head *list, const struct list_head *head) { return list->prev == head; } @@ -283,12 +275,21 @@ static inline int list_is_first(const struct list_head *list, * @param list the entry to test * @param head the head of the list */ -static inline int list_is_last(const struct list_head *list, - const struct list_head *head) +static inline int list_is_last(const struct list_head *list, const struct list_head *head) { return list->next == head; } +/** + * list_is_head - tests whether @a list is the list @a head + * @param list the entry to test + * @param head the head of the list + */ +static inline int list_is_head(const struct list_head *list, const struct list_head *head) +{ + return list == head; +} + /** * list_empty - tests whether a list is empty * @param head the list to test. @@ -407,10 +408,9 @@ static inline void list_cut_position(struct list_head *list, { if (list_empty(head)) return; - if (list_is_singular(head) && - (head->next != entry && head != entry)) + if (list_is_singular(head) && !list_is_head(entry, head) && (entry != head->next)) return; - if (entry == head) + if (list_is_head(entry, head)) INIT_LIST_HEAD(list); else __list_cut_position(list, head, entry); @@ -570,6 +570,19 @@ static inline void list_splice_tail_init(struct list_head *list, #define list_next_entry(pos, member) \ list_entry((pos)->member.next, typeof(*(pos)), member) +/** + * list_next_entry_circular - get the next element in list + * @param pos the type * to cursor. + * @param head the list head to take the element from. + * @param member the name of the list_head within the struct. + * + * Wraparound if pos is the last element (return the first element). + * Note, that list is expected to be not empty. + */ +#define list_next_entry_circular(pos, head, member) \ + (list_is_last(&(pos)->member, head) ? \ + list_first_entry(head, typeof(*(pos)), member) : list_next_entry(pos, member)) + /** * list_prev_entry - get the prev element in list * @param pos the type * to cursor @@ -578,13 +591,28 @@ static inline void list_splice_tail_init(struct list_head *list, #define list_prev_entry(pos, member) \ list_entry((pos)->member.prev, typeof(*(pos)), member) +/** + * list_prev_entry_circular - get the prev element in list + * @param pos the type * to cursor. + * @param head the list head to take the element from. + * @param member the name of the list_head within the struct. + * + * Wraparound if pos is the first element (return the last element). + * Note, that list is expected to be not empty. + */ +#define list_prev_entry_circular(pos, head, member) \ + (list_is_first(&(pos)->member, head) ? \ + list_last_entry(head, typeof(*(pos)), member) : list_prev_entry(pos, member)) + /** * list_for_each - iterate over a list * @param pos the &struct list_head to use as a loop cursor. * @param head the head for your list. */ #define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) + for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) + +/* Ignore kernel list_for_each_rcu() */ /** * list_for_each_continue - continue iteration over a list @@ -625,6 +653,21 @@ static inline void list_splice_tail_init(struct list_head *list, pos != (head); \ pos = n, n = pos->prev) +/** + * list_count_nodes - count nodes in the list + * @param head the head for your list. + */ +static inline size_t list_count_nodes(struct list_head *head) +{ + struct list_head *pos; + size_t count = 0; + + list_for_each(pos, head) + count++; + + return count; +} + /** * list_entry_is_head - test if the entry points to the head of the list * @param pos the type * to cursor @@ -811,237 +854,7 @@ static inline void list_splice_tail_init(struct list_head *list, /* * Double linked lists with a single pointer list head. - * Mostly useful for hash tables where the two pointer list head is - * too wasteful. - * You lose the ability to access the tail in O(1). - */ - -#define HLIST_HEAD_INIT { .first = NULL } -#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } -#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) -static inline void INIT_HLIST_NODE(struct hlist_node *h) -{ - h->next = NULL; - h->pprev = NULL; -} - -/** - * hlist_unhashed - Has node been removed from list and reinitialized? - * @param h Node to be checked - * - * Not that not all removal functions will leave a node in unhashed - * state. For example, hlist_nulls_del_init_rcu() does leave the - * node in unhashed state, but hlist_nulls_del() does not. - */ -static inline int hlist_unhashed(const struct hlist_node *h) -{ - return !h->pprev; -} - -/* Ignore kernel hlist_unhashed_lockless() */ - -/** - * hlist_empty - Is the specified hlist_head structure an empty hlist? - * @param h Structure to check. - */ -static inline int hlist_empty(const struct hlist_head *h) -{ - return !h->first; -} - -static inline void __hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - - *pprev = next; - if (next) - next->pprev = pprev; -} - -/** - * hlist_del - Delete the specified hlist_node from its list - * @param n Node to delete. - * - * Note that this function leaves the node in hashed state. Use - * hlist_del_init() or similar instead to unhash @a n. - */ -static inline void hlist_del(struct hlist_node *n) -{ - __hlist_del(n); - n->next = LIST_POISON1; - n->pprev = LIST_POISON2; -} - -/** - * hlist_del_init - Delete the specified hlist_node from its list and initialize - * @param n Node to delete. - * - * Note that this function leaves the node in unhashed state. - */ -static inline void hlist_del_init(struct hlist_node *n) -{ - if (!hlist_unhashed(n)) { - __hlist_del(n); - INIT_HLIST_NODE(n); - } -} - -/** - * hlist_add_head - add a new entry at the beginning of the hlist - * @param n new entry to be added - * @param h hlist head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - struct hlist_node *first = h->first; - n->next = first; - if (first) - first->pprev = &n->next; - h->first = n; - n->pprev = &h->first; -} - -/** - * hlist_add_before - add a new entry before the one specified - * @param n new entry to be added - * @param next hlist node to add it before, which must be non-NULL - */ -static inline void hlist_add_before(struct hlist_node *n, - struct hlist_node *next) -{ - n->pprev = next->pprev; - n->next = next; - next->pprev = &n->next; - *(n->pprev) = n; -} - -/** - * hlist_add_behind - add a new entry after the one specified - * @param n new entry to be added - * @param prev hlist node to add it after, which must be non-NULL - */ -static inline void hlist_add_behind(struct hlist_node *n, - struct hlist_node *prev) -{ - n->next = prev->next; - prev->next = n; - n->pprev = &prev->next; - - if (n->next) - n->next->pprev = &n->next; -} - -/** - * hlist_add_fake - create a fake hlist consisting of a single headless node - * @param n Node to make a fake list out of - * - * This makes @a n appear to be its own predecessor on a headless hlist. - * The point of this is to allow things like hlist_del() to work correctly - * in cases where there is no list. - */ -static inline void hlist_add_fake(struct hlist_node *n) -{ - n->pprev = &n->next; -} - -/** - * hlist_fake: Is this node a fake hlist? - * @param h Node to check for being a self-referential fake hlist. - */ -static inline bool hlist_fake(struct hlist_node *h) -{ - return h->pprev == &h->next; -} - -/** - * hlist_is_singular_node - is node the only element of the specified hlist? - * @param n Node to check for singularity. - * @param h Header for potentially singular list. - * - * Check whether the node is the only node of the head without - * accessing head, thus avoiding unnecessary cache misses. - */ -static inline bool -hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) -{ - return !n->next && n->pprev == &h->first; -} - -/** - * hlist_move_list - Move an hlist - * @param old hlist_head for old list. - * @param new hlist_head for new list. - * - * Move a list from one list head to another. Fixup the pprev - * reference of the first entry if it exists. - */ -static inline void hlist_move_list(struct hlist_head *old, - struct hlist_head *new) -{ - new->first = old->first; - if (new->first) - new->first->pprev = &new->first; - old->first = NULL; -} - -#define hlist_entry(ptr, type, member) container_of(ptr, type, member) - -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos ; pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ - pos = n) - -#define hlist_entry_safe(ptr, type, member) \ - ({ typeof(ptr) ____ptr = (ptr); \ - ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ - }) - -/** - * hlist_for_each_entry - iterate over list of given type - * @param pos the type * to use as a loop cursor. - * @param head the head for your list. - * @param member the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry(pos, head, member) \ - for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ - pos; \ - pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) - -/** - * hlist_for_each_entry_continue - iterate over a hlist continuing after current point - * @param pos the type * to use as a loop cursor. - * @param member the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_continue(pos, member) \ - for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ - pos; \ - pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) - -/** - * hlist_for_each_entry_from - iterate over a hlist continuing from current point - * @param pos the type * to use as a loop cursor. - * @param member the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_from(pos, member) \ - for (; pos; \ - pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) - -/** - * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @param pos the type * to use as a loop cursor. - * @param n a &struct hlist_node to use as temporary storage - * @param head the head for your list. - * @param member the name of the hlist_node within the struct. + * IGNORED */ -#define hlist_for_each_entry_safe(pos, n, head, member) \ - for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ - pos && ({ n = pos->member.next; 1; }); \ - pos = hlist_entry_safe(n, typeof(*pos), member)) #endif /* OPENOCD_HELPER_LIST_H */ diff --git a/src/helper/util.c b/src/helper/util.c index bf18f8e603..5e12021ff5 100644 --- a/src/helper/util.c +++ b/src/helper/util.c @@ -13,28 +13,21 @@ #include "log.h" #include "time_support.h" -static int jim_util_ms(Jim_Interp *interp, - int argc, - Jim_Obj * const *argv) +COMMAND_HANDLER(handler_util_ms) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?"); - return JIM_ERR; - } + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - /* Cast from 64 to 32 bit int works for 2's-compliment - * when calculating differences*/ - Jim_SetResult(interp, Jim_NewIntObj(interp, (int)timeval_ms())); + command_print(CMD, "%" PRId64, timeval_ms()); - return JIM_OK; + return ERROR_OK; } static const struct command_registration util_command_handlers[] = { - /* jim handlers */ { .name = "ms", .mode = COMMAND_ANY, - .jim_handler = jim_util_ms, + .handler = handler_util_ms, .help = "Returns ever increasing milliseconds. Used to calculate differences in time.", .usage = "", diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 430af6c3c8..e70f4a1e80 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -374,21 +374,18 @@ bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path return equal; } -static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_adapter_name) { - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - /* return the name of the interface */ /* TCL code might need to know the exact type... */ /* FUTURE: we allow this as a means to "set" the interface. */ - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); - return JIM_ERR; - } - const char *name = adapter_driver ? adapter_driver->name : NULL; - Jim_SetResultString(goi.interp, name ? name : "undefined", -1); - return JIM_OK; + + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + command_print(CMD, "%s", adapter_driver ? adapter_driver->name : "undefined"); + + return ERROR_OK; } COMMAND_HANDLER(adapter_transports_command) @@ -1123,9 +1120,10 @@ static const struct command_registration adapter_command_handlers[] = { { .name = "name", .mode = COMMAND_ANY, - .jim_handler = jim_adapter_name, + .handler = handle_adapter_name, .help = "Returns the name of the currently " "selected adapter (driver)", + .usage = "", }, { .name = "srst", diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index fc0d562e23..b3cbc48b49 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -249,12 +249,15 @@ static int jim_command_pathmove(Jim_Interp *interp, int argc, Jim_Obj * const *a return JIM_OK; } - -static int jim_command_flush_count(Jim_Interp *interp, int argc, Jim_Obj * const *args) +COMMAND_HANDLER(handle_jtag_flush_count) { - Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count())); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - return JIM_OK; + int count = jtag_get_flush_queue_count(); + command_print_sameline(CMD, "%d", count); + + return ERROR_OK; } /* REVISIT Just what about these should "move" ... ? @@ -279,9 +282,10 @@ static const struct command_registration jtag_command_handlers_to_move[] = { { .name = "flush_count", .mode = COMMAND_EXEC, - .jim_handler = jim_command_flush_count, + .handler = handle_jtag_flush_count, .help = "Returns the number of times the JTAG queue " "has been flushed.", + .usage = "", }, { .name = "pathmove", @@ -664,45 +668,26 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e) } } -static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_jtag_arp_init) { - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); - return JIM_ERR; - } - struct command_context *context = current_command_context(interp); - int e = jtag_init_inner(context); - if (e != ERROR_OK) { - Jim_Obj *obj = Jim_NewIntObj(goi.interp, e); - Jim_SetResultFormatted(goi.interp, "error: %#s", obj); - return JIM_ERR; - } - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + return jtag_init_inner(CMD_CTX); } -static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_jtag_arp_init_reset) { - int e = ERROR_OK; - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); - return JIM_ERR; - } - struct command_context *context = current_command_context(interp); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + if (transport_is_jtag()) - e = jtag_init_reset(context); - else if (transport_is_swd()) - e = swd_init_reset(context); + return jtag_init_reset(CMD_CTX); - if (e != ERROR_OK) { - Jim_Obj *obj = Jim_NewIntObj(goi.interp, e); - Jim_SetResultFormatted(goi.interp, "error: %#s", obj); - return JIM_ERR; - } - return JIM_OK; + if (transport_is_swd()) + return swd_init_reset(CMD_CTX); + + return ERROR_OK; } int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -805,24 +790,15 @@ int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return jtag_tap_configure_cmd(&goi, t); } -static int jim_jtag_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_jtag_names) { - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0)); - struct jtag_tap *tap; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - for (tap = jtag_all_taps(); tap; tap = tap->next_tap) { - Jim_ListAppendElement(goi.interp, - Jim_GetResult(goi.interp), - Jim_NewStringObj(goi.interp, - tap->dotted_name, -1)); - } - return JIM_OK; + for (struct jtag_tap *tap = jtag_all_taps(); tap; tap = tap->next_tap) + command_print(CMD, "%s", tap->dotted_name); + + return ERROR_OK; } COMMAND_HANDLER(handle_jtag_init_command) @@ -852,17 +828,19 @@ static const struct command_registration jtag_subcommand_handlers[] = { { .name = "arp_init", .mode = COMMAND_ANY, - .jim_handler = jim_jtag_arp_init, + .handler = handle_jtag_arp_init, .help = "Validates JTAG scan chain against the list of " "declared TAPs using just the four standard JTAG " "signals.", + .usage = "", }, { .name = "arp_init-reset", .mode = COMMAND_ANY, - .jim_handler = jim_jtag_arp_init_reset, + .handler = handle_jtag_arp_init_reset, .help = "Uses TRST and SRST to try resetting everything on " - "the JTAG scan chain, then performs 'jtag arp_init'." + "the JTAG scan chain, then performs 'jtag arp_init'.", + .usage = "", }, { .name = "newtap", @@ -921,8 +899,9 @@ static const struct command_registration jtag_subcommand_handlers[] = { { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_jtag_names, + .handler = handle_jtag_names, .help = "Returns list of all JTAG tap names.", + .usage = "", }, { .chain = jtag_command_handlers_to_move, diff --git a/src/openocd.c b/src/openocd.c index 875da5a62c..54c5eb34f7 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -51,24 +51,23 @@ static const char openocd_startup_tcl[] = { }; /* Give scripts and TELNET a way to find out what version this is */ -static int jim_version_command(Jim_Interp *interp, int argc, - Jim_Obj * const *argv) +COMMAND_HANDLER(handler_version_command) { - if (argc > 2) - return JIM_ERR; - const char *str = ""; - char *version_str; - version_str = OPENOCD_VERSION; + char *version_str = OPENOCD_VERSION; - if (argc == 2) - str = Jim_GetString(argv[1], NULL); + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (CMD_ARGC == 1) { + if (strcmp("git", CMD_ARGV[0])) + return ERROR_COMMAND_ARGUMENT_INVALID; - if (strcmp("git", str) == 0) version_str = GITVERSION; + } - Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1)); + command_print(CMD, "%s", version_str); - return JIM_OK; + return ERROR_OK; } static int log_target_callback_event_handler(struct target *target, @@ -194,9 +193,10 @@ COMMAND_HANDLER(handle_add_script_search_dir_command) static const struct command_registration openocd_command_handlers[] = { { .name = "version", - .jim_handler = jim_version_command, + .handler = handler_version_command, .mode = COMMAND_ANY, .help = "show program version", + .usage = "[git]", }, { .name = "noinit", diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c index bf2896cf72..ea37f7fe7d 100644 --- a/src/rtos/FreeRTOS.c +++ b/src/rtos/FreeRTOS.c @@ -729,6 +729,7 @@ static int freertos_update_threads(struct rtos *rtos) tasks_found++; list_thread_count--; + rtos->thread_count = tasks_found; prev_list_elem_ptr = list_elem_ptr; list_elem_ptr = 0; @@ -750,7 +751,6 @@ static int freertos_update_threads(struct rtos *rtos) } free(list_of_lists); - rtos->thread_count = tasks_found; return 0; } diff --git a/src/rtt/tcl.c b/src/rtt/tcl.c index 7cbdccf567..f949aa1c94 100644 --- a/src/rtt/tcl.c +++ b/src/rtt/tcl.c @@ -150,17 +150,17 @@ COMMAND_HANDLER(handle_rtt_channels_command) return ERROR_OK; } -static int jim_channel_list(Jim_Interp *interp, int argc, - Jim_Obj * const *argv) +COMMAND_HANDLER(handle_channel_list) { - Jim_Obj *list; - Jim_Obj *channel_list; char channel_name[CHANNEL_NAME_SIZE]; const struct rtt_control *ctrl; struct rtt_channel_info info; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + if (!rtt_found_cb()) { - Jim_SetResultFormatted(interp, "rtt: Control block not available"); + command_print(CMD, "rtt: Control block not available"); return ERROR_FAIL; } @@ -169,81 +169,47 @@ static int jim_channel_list(Jim_Interp *interp, int argc, info.name = channel_name; info.name_length = sizeof(channel_name); - list = Jim_NewListObj(interp, NULL, 0); - channel_list = Jim_NewListObj(interp, NULL, 0); + command_print(CMD, "{"); for (unsigned int i = 0; i < ctrl->num_up_channels; i++) { - int ret; - Jim_Obj *tmp; - - ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info); - + int ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info); if (ret != ERROR_OK) return ret; if (!info.size) continue; - tmp = Jim_NewListObj(interp, NULL, 0); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "name", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - info.name, -1)); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "size", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, - info.size)); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "flags", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, - info.flags)); - - Jim_ListAppendElement(interp, channel_list, tmp); + command_print(CMD, + " {\n" + " name %s\n" + " size 0x%" PRIx32 "\n" + " flags 0x%" PRIx32 "\n" + " }", + info.name, info.size, info.flags); } - Jim_ListAppendElement(interp, list, channel_list); - - channel_list = Jim_NewListObj(interp, NULL, 0); + command_print(CMD, "}\n{"); for (unsigned int i = 0; i < ctrl->num_down_channels; i++) { - int ret; - Jim_Obj *tmp; - - ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info); - + int ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info); if (ret != ERROR_OK) return ret; if (!info.size) continue; - tmp = Jim_NewListObj(interp, NULL, 0); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "name", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - info.name, -1)); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "size", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, - info.size)); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "flags", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, - info.flags)); - - Jim_ListAppendElement(interp, channel_list, tmp); + command_print(CMD, + " {\n" + " name %s\n" + " size 0x%" PRIx32 "\n" + " flags 0x%" PRIx32 "\n" + " }", + info.name, info.size, info.flags); } - Jim_ListAppendElement(interp, list, channel_list); - Jim_SetResult(interp, list); + command_print(CMD, "}"); - return JIM_OK; + return ERROR_OK; } static const struct command_registration rtt_subcommand_handlers[] = { @@ -284,7 +250,7 @@ static const struct command_registration rtt_subcommand_handlers[] = { }, { .name = "channellist", - .jim_handler = jim_channel_list, + .handler = handle_channel_list, .mode = COMMAND_EXEC, .help = "list available channels", .usage = "" diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c index f4a6f6cdcc..755d0510ed 100644 --- a/src/server/ipdbg.c +++ b/src/server/ipdbg.c @@ -90,7 +90,7 @@ static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo) return; size_t ri = fifo->rd_idx; - for (size_t idx = 0 ; idx < fifo->count ; ++idx) + for (size_t idx = 0; idx < fifo->count; ++idx) fifo->buffer[idx] = fifo->buffer[ri++]; fifo->rd_idx = 0; } @@ -149,7 +149,7 @@ static int ipdbg_max_tools_from_data_register_length(uint8_t data_register_lengt static struct ipdbg_service *ipdbg_find_service(struct ipdbg_hub *hub, uint8_t tool) { struct ipdbg_service *service; - for (service = ipdbg_first_service ; service ; service = service->next) { + for (service = ipdbg_first_service; service; service = service->next) { if (service->hub == hub && service->tool == tool) break; } @@ -160,7 +160,7 @@ static void ipdbg_add_service(struct ipdbg_service *service) { struct ipdbg_service *iservice; if (ipdbg_first_service) { - for (iservice = ipdbg_first_service ; iservice->next; iservice = iservice->next) + for (iservice = ipdbg_first_service; iservice->next; iservice = iservice->next) ; iservice->next = service; } else @@ -192,7 +192,7 @@ static int ipdbg_remove_service(struct ipdbg_service *service) return ERROR_OK; } - for (struct ipdbg_service *iservice = ipdbg_first_service ; iservice->next ; iservice = iservice->next) { + for (struct ipdbg_service *iservice = ipdbg_first_service; iservice->next; iservice = iservice->next) { if (service == iservice->next) { iservice->next = service->next; return ERROR_OK; @@ -205,7 +205,7 @@ static struct ipdbg_hub *ipdbg_find_hub(struct jtag_tap *tap, uint32_t user_instruction, struct ipdbg_virtual_ir_info *virtual_ir) { struct ipdbg_hub *hub = NULL; - for (hub = ipdbg_first_hub ; hub ; hub = hub->next) { + for (hub = ipdbg_first_hub; hub; hub = hub->next) { if (hub->tap == tap && hub->user_instruction == user_instruction) { if ((!virtual_ir && !hub->virtual_ir) || (virtual_ir && hub->virtual_ir && @@ -223,7 +223,7 @@ static void ipdbg_add_hub(struct ipdbg_hub *hub) { struct ipdbg_hub *ihub; if (ipdbg_first_hub) { - for (ihub = ipdbg_first_hub ; ihub->next; ihub = ihub->next) + for (ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next) ; ihub->next = hub; } else @@ -281,7 +281,7 @@ static int ipdbg_remove_hub(struct ipdbg_hub *hub) return ERROR_OK; } - for (struct ipdbg_hub *ihub = ipdbg_first_hub ; ihub->next ; ihub = ihub->next) { + for (struct ipdbg_hub *ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next) { if (hub == ihub->next) { ihub->next = hub->next; return ERROR_OK; @@ -447,7 +447,7 @@ static int ipdbg_polling_callback(void *priv) /* transfer dn buffers to jtag-hub */ unsigned int num_transfers = 0; - for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) { + for (size_t tool = 0; tool < hub->max_tools; ++tool) { struct connection *conn = hub->connections[tool]; if (conn && conn->priv) { struct ipdbg_connection *connection = conn->priv; @@ -475,7 +475,7 @@ static int ipdbg_polling_callback(void *priv) } /* write from up fifos to sockets */ - for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) { + for (size_t tool = 0; tool < hub->max_tools; ++tool) { struct connection *conn = hub->connections[tool]; if (conn && conn->priv) { struct ipdbg_connection *connection = conn->priv; diff --git a/src/svf/svf.c b/src/svf/svf.c index 7195880670..dd3d5175c3 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -22,6 +22,7 @@ #include "svf.h" #include "helper/system.h" #include +#include #include /* SVF command */ @@ -346,6 +347,37 @@ int svf_add_statemove(tap_state_t state_to) return ERROR_FAIL; } +enum svf_cmd_param { + OPT_ADDCYCLES, + OPT_IGNORE_ERROR, + OPT_NIL, + OPT_NORESET, + OPT_PROGRESS, + OPT_QUIET, + OPT_TAP, + /* DEPRECATED */ + DEPRECATED_OPT_IGNORE_ERROR, + DEPRECATED_OPT_NIL, + DEPRECATED_OPT_PROGRESS, + DEPRECATED_OPT_QUIET, +}; + +static const struct nvp svf_cmd_opts[] = { + { .name = "-addcycles", .value = OPT_ADDCYCLES }, + { .name = "-ignore_error", .value = OPT_IGNORE_ERROR }, + { .name = "-nil", .value = OPT_NIL }, + { .name = "-noreset", .value = OPT_NORESET }, + { .name = "-progress", .value = OPT_PROGRESS }, + { .name = "-quiet", .value = OPT_QUIET }, + { .name = "-tap", .value = OPT_TAP }, + /* DEPRECATED */ + { .name = "ignore_error", .value = DEPRECATED_OPT_IGNORE_ERROR }, + { .name = "nil", .value = DEPRECATED_OPT_NIL }, + { .name = "progress", .value = DEPRECATED_OPT_PROGRESS }, + { .name = "quiet", .value = DEPRECATED_OPT_QUIET }, + { .name = NULL, .value = -1 } +}; + COMMAND_HANDLER(handle_svf_command) { #define SVF_MIN_NUM_OF_OPTIONS 1 @@ -355,10 +387,11 @@ COMMAND_HANDLER(handle_svf_command) int64_t time_measure_ms; int time_measure_s, time_measure_m; - /* use NULL to indicate a "plain" svf file which accounts for + /* + * use NULL to indicate a "plain" svf file which accounts for * any additional devices in the scan chain, otherwise the device * that should be affected - */ + */ struct jtag_tap *tap = NULL; if ((CMD_ARGC < SVF_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > SVF_MAX_NUM_OF_OPTIONS)) @@ -373,42 +406,74 @@ COMMAND_HANDLER(handle_svf_command) svf_addcycles = 0; for (unsigned int i = 0; i < CMD_ARGC; i++) { - if (strcmp(CMD_ARGV[i], "-addcycles") == 0) { + const struct nvp *n = nvp_name2value(svf_cmd_opts, CMD_ARGV[i]); + switch (n->value) { + case OPT_ADDCYCLES: svf_addcycles = atoi(CMD_ARGV[i + 1]); if (svf_addcycles > SVF_MAX_ADDCYCLES) { command_print(CMD, "addcycles: %s out of range", CMD_ARGV[i + 1]); - return ERROR_FAIL; + if (svf_fd) + fclose(svf_fd); + svf_fd = NULL; + return ERROR_COMMAND_ARGUMENT_INVALID; } i++; - } else if (strcmp(CMD_ARGV[i], "-tap") == 0) { + break; + + case OPT_TAP: tap = jtag_tap_by_string(CMD_ARGV[i+1]); if (!tap) { command_print(CMD, "Tap: %s unknown", CMD_ARGV[i+1]); - return ERROR_FAIL; + if (svf_fd) + fclose(svf_fd); + svf_fd = NULL; + return ERROR_COMMAND_ARGUMENT_INVALID; } i++; - } else if ((strcmp(CMD_ARGV[i], - "quiet") == 0) || (strcmp(CMD_ARGV[i], "-quiet") == 0)) + break; + + case DEPRECATED_OPT_QUIET: + LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); + /* fallthrough */ + case OPT_QUIET: svf_quiet = 1; - else if ((strcmp(CMD_ARGV[i], "nil") == 0) || (strcmp(CMD_ARGV[i], "-nil") == 0)) + break; + + case DEPRECATED_OPT_NIL: + LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); + /* fallthrough */ + case OPT_NIL: svf_nil = 1; - else if ((strcmp(CMD_ARGV[i], - "progress") == 0) || (strcmp(CMD_ARGV[i], "-progress") == 0)) + break; + + case DEPRECATED_OPT_PROGRESS: + LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); + /* fallthrough */ + case OPT_PROGRESS: svf_progress_enabled = 1; - else if ((strcmp(CMD_ARGV[i], - "ignore_error") == 0) || (strcmp(CMD_ARGV[i], "-ignore_error") == 0)) + break; + + case DEPRECATED_OPT_IGNORE_ERROR: + LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); + /* fallthrough */ + case OPT_IGNORE_ERROR: svf_ignore_error = 1; - else if (strcmp(CMD_ARGV[i], "-noreset") == 0) + break; + + case OPT_NORESET: svf_noreset = true; - else { + break; + + default: svf_fd = fopen(CMD_ARGV[i], "r"); if (!svf_fd) { int err = errno; command_print(CMD, "open(\"%s\"): %s", CMD_ARGV[i], strerror(err)); /* no need to free anything now */ return ERROR_COMMAND_SYNTAX_ERROR; - } else - LOG_USER("svf processing file: \"%s\"", CMD_ARGV[i]); + } + LOG_USER("svf processing file: \"%s\"", CMD_ARGV[i]); + break; } } @@ -467,27 +532,31 @@ COMMAND_HANDLER(handle_svf_command) } /* HDR %d TDI (0) */ - if (svf_set_padding(&svf_para.hdr_para, header_dr_len, 0) != ERROR_OK) { - LOG_ERROR("failed to set data header"); - return ERROR_FAIL; + ret = svf_set_padding(&svf_para.hdr_para, header_dr_len, 0); + if (ret != ERROR_OK) { + command_print(CMD, "failed to set data header"); + goto free_all; } /* HIR %d TDI (0xFF) */ - if (svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF) != ERROR_OK) { - LOG_ERROR("failed to set instruction header"); - return ERROR_FAIL; + ret = svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF); + if (ret != ERROR_OK) { + command_print(CMD, "failed to set instruction header"); + goto free_all; } /* TDR %d TDI (0) */ - if (svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0) != ERROR_OK) { - LOG_ERROR("failed to set data trailer"); - return ERROR_FAIL; + ret = svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0); + if (ret != ERROR_OK) { + command_print(CMD, "failed to set data trailer"); + goto free_all; } /* TIR %d TDI (0xFF) */ - if (svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF) != ERROR_OK) { - LOG_ERROR("failed to set instruction trailer"); - return ERROR_FAIL; + ret = svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF); + if (ret != ERROR_OK) { + command_print(CMD, "failed to set instruction trailer"); + goto free_all; } } @@ -546,7 +615,7 @@ COMMAND_HANDLER(handle_svf_command) free_all: fclose(svf_fd); - svf_fd = 0; + svf_fd = NULL; /* free buffers */ free(svf_command_buffer); @@ -1566,7 +1635,7 @@ static const struct command_registration svf_command_handlers[] = { .handler = handle_svf_command, .mode = COMMAND_EXEC, .help = "Runs a SVF file.", - .usage = "[-tap device.tap] [quiet] [nil] [progress] [ignore_error] [-noreset] [-addcycles numcycles]", + .usage = "[-tap device.tap] [-quiet] [-nil] [-progress] [-ignore_error] [-noreset] [-addcycles numcycles] file", }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 8e90e64007..3c33032e97 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2952,53 +2952,41 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command) return ERROR_OK; } -static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(aarch64_mcrmrc_command) { - struct command *c = jim_to_command(interp); - struct command_context *context; - struct target *target; - struct arm *arm; - int retval; bool is_mcr = false; - int arg_cnt = 0; + unsigned int arg_cnt = 5; - if (!strcmp(c->name, "mcr")) { + if (!strcmp(CMD_NAME, "mcr")) { is_mcr = true; - arg_cnt = 7; - } else { arg_cnt = 6; } - context = current_command_context(interp); - assert(context); + if (arg_cnt != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; - target = get_current_target(context); + struct target *target = get_current_target(CMD_CTX); if (!target) { - LOG_ERROR("%s: no current target", __func__); - return JIM_ERR; + command_print(CMD, "no current target"); + return ERROR_FAIL; } if (!target_was_examined(target)) { - LOG_ERROR("%s: not yet examined", target_name(target)); - return JIM_ERR; + command_print(CMD, "%s: not yet examined", target_name(target)); + return ERROR_TARGET_NOT_EXAMINED; } - arm = target_to_arm(target); + struct arm *arm = target_to_arm(target); if (!is_arm(arm)) { - LOG_ERROR("%s: not an ARM", target_name(target)); - return JIM_ERR; + command_print(CMD, "%s: not an ARM", target_name(target)); + return ERROR_FAIL; } if (target->state != TARGET_HALTED) return ERROR_TARGET_NOT_HALTED; if (arm->core_state == ARM_STATE_AARCH64) { - LOG_ERROR("%s: not 32-bit arm target", target_name(target)); - return JIM_ERR; - } - - if (argc != arg_cnt) { - LOG_ERROR("%s: wrong number of arguments", __func__); - return JIM_ERR; + command_print(CMD, "%s: not 32-bit arm target", target_name(target)); + return ERROR_FAIL; } int cpnum; @@ -3007,87 +2995,62 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) uint32_t crn; uint32_t crm; uint32_t value; - long l; /* NOTE: parameter sequence matches ARM instruction set usage: * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX * The "rX" is necessarily omitted; it uses Tcl mechanisms. */ - retval = Jim_GetLong(interp, argv[1], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "coprocessor", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum); + if (cpnum & ~0xf) { + command_print(CMD, "coprocessor %d out of range", cpnum); + return ERROR_COMMAND_ARGUMENT_INVALID; } - cpnum = l; - retval = Jim_GetLong(interp, argv[2], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op1", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1); + if (op1 & ~0x7) { + command_print(CMD, "op1 %d out of range", op1); + return ERROR_COMMAND_ARGUMENT_INVALID; } - op1 = l; - retval = Jim_GetLong(interp, argv[3], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRn", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn); + if (crn & ~0xf) { + command_print(CMD, "CRn %d out of range", crn); + return ERROR_COMMAND_ARGUMENT_INVALID; } - crn = l; - retval = Jim_GetLong(interp, argv[4], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRm", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm); + if (crm & ~0xf) { + command_print(CMD, "CRm %d out of range", crm); + return ERROR_COMMAND_ARGUMENT_INVALID; } - crm = l; - retval = Jim_GetLong(interp, argv[5], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op2", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2); + if (op2 & ~0x7) { + command_print(CMD, "op2 %d out of range", op2); + return ERROR_COMMAND_ARGUMENT_INVALID; } - op2 = l; - value = 0; - - if (is_mcr == true) { - retval = Jim_GetLong(interp, argv[6], &l); - if (retval != JIM_OK) - return retval; - value = l; + if (is_mcr) { + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value); /* NOTE: parameters reordered! */ /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); + int retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); if (retval != ERROR_OK) - return JIM_ERR; + return retval; } else { + value = 0; /* NOTE: parameters reordered! */ /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); + int retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); if (retval != ERROR_OK) - return JIM_ERR; + return retval; - Jim_SetResult(interp, Jim_NewIntObj(interp, value)); + command_print(CMD, "0x%" PRIx32, value); } - return JIM_OK; + return ERROR_OK; } static const struct command_registration aarch64_exec_command_handlers[] = { @@ -3122,14 +3085,14 @@ static const struct command_registration aarch64_exec_command_handlers[] = { { .name = "mcr", .mode = COMMAND_EXEC, - .jim_handler = jim_mcrmrc, + .handler = aarch64_mcrmrc_command, .help = "write coprocessor register", .usage = "cpnum op1 CRn CRm op2 value", }, { .name = "mrc", .mode = COMMAND_EXEC, - .jim_handler = jim_mcrmrc, + .handler = aarch64_mcrmrc_command, .help = "read coprocessor register", .usage = "cpnum op1 CRn CRm op2", }, diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c index eeb796be45..9f66adc688 100644 --- a/src/target/adi_v5_jtag.c +++ b/src/target/adi_v5_jtag.c @@ -566,14 +566,20 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) /* restore SELECT register first */ if (!list_empty(&replay_list)) { el = list_first_entry(&replay_list, struct dap_cmd, lh); + + uint8_t out_value_buf[4]; + buf_set_u32(out_value_buf, 0, 32, (uint32_t)(el->dp_select)); + tmp = dap_cmd_new(dap, JTAG_DP_DPACC, - DP_SELECT, DPAP_WRITE, (uint8_t *)&el->dp_select, NULL, 0); + DP_SELECT, DPAP_WRITE, out_value_buf, NULL, 0); if (!tmp) { retval = ERROR_JTAG_DEVICE_ERROR; goto done; } list_add(&tmp->lh, &replay_list); + /* TODO: ADIv6 DP SELECT1 handling */ + dap->select = DP_SELECT_INVALID; } diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index aea730d4d1..653f91f130 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -13,7 +13,7 @@ * is a transport level interface, with "target/arm_adi_v5.[hc]" code * understanding operation semantics, shared with the JTAG transport. * - * Single-DAP support only. + * Single DAP and multidrop-SWD support. * * for details, see "ARM IHI 0031A" * ARM Debug Interface v5 Architecture Specification diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c index 3612874e2a..7637ad0158 100644 --- a/src/target/arm_cti.c +++ b/src/target/arm_cti.c @@ -525,20 +525,17 @@ static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return cti_create(&goi); } -static int jim_cti_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(cti_handle_names) { struct arm_cti *obj; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - list_for_each_entry(obj, &all_cti, lh) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, obj->name, -1)); - } - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + list_for_each_entry(obj, &all_cti, lh) + command_print(CMD, "%s", obj->name); + + return ERROR_OK; } @@ -553,7 +550,7 @@ static const struct command_registration cti_subcommand_handlers[] = { { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_cti_names, + .handler = cti_handle_names, .usage = "", .help = "Lists all registered CTI objects by name", }, diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index e21136dd69..bc9d962363 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -421,20 +421,16 @@ static int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return dap_create(&goi); } -static int jim_dap_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_dap_names) { + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + struct arm_dap_object *obj; + list_for_each_entry(obj, &all_dap, lh) + command_print(CMD, "%s", obj->name); - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - list_for_each_entry(obj, &all_dap, lh) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, obj->name, -1)); - } - return JIM_OK; + return ERROR_OK; } COMMAND_HANDLER(handle_dap_init) @@ -500,7 +496,7 @@ static const struct command_registration dap_subcommand_handlers[] = { { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_dap_names, + .handler = handle_dap_names, .usage = "", .help = "Lists all registered DAP instances by name", }, diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index 7096db3055..5cea682ec4 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -595,54 +595,52 @@ static const struct service_driver arm_tpiu_swo_service_driver = { .keep_client_alive_handler = NULL, }; -static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_arm_tpiu_swo_enable) { - struct command *c = jim_to_command(interp); - struct arm_tpiu_swo_object *obj = c->jim_handler_data; - struct command_context *cmd_ctx = current_command_context(interp); + struct arm_tpiu_swo_object *obj = CMD_DATA; uint32_t value; int retval; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - if (cmd_ctx->mode == COMMAND_CONFIG) { + if (CMD_CTX->mode == COMMAND_CONFIG) { LOG_DEBUG("%s: enable deferred", obj->name); obj->deferred_enable = true; - return JIM_OK; + return ERROR_OK; } if (obj->enabled) - return JIM_OK; + return ERROR_OK; if (transport_is_hla() && obj->spot.ap_num != 0) { - LOG_ERROR("Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", obj->spot.ap_num); - return JIM_ERR; + command_print(CMD, + "Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", + obj->spot.ap_num); + return ERROR_FAIL; } if (!obj->traceclkin_freq) { - LOG_ERROR("Trace clock-in frequency not set"); - return JIM_ERR; + command_print(CMD, "Trace clock-in frequency not set"); + return ERROR_FAIL; } if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) if (!obj->swo_pin_freq) LOG_DEBUG("SWO pin frequency not set, will be autodetected by the adapter"); - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(CMD_CTX); /* START_DEPRECATED_TPIU */ if (obj->recheck_ap_cur_target) { if (strcmp(target->type->name, "cortex_m") && strcmp(target->type->name, "hla_target")) { LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA"); - return JIM_ERR; + return ERROR_FAIL; } if (!target_was_examined(target)) { LOG_ERROR(MSG "Current target not examined yet"); - return JIM_ERR; + return ERROR_FAIL; } struct cortex_m_common *cm = target_to_cm(target); obj->recheck_ap_cur_target = false; @@ -660,8 +658,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const if (!obj->ap) { obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num); if (!obj->ap) { - LOG_ERROR("Cannot get AP"); - return JIM_ERR; + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; } } @@ -670,8 +668,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value); if (retval != ERROR_OK) { - LOG_ERROR("Unable to read %s", obj->name); - return JIM_ERR; + command_print(CMD, "Unable to read %s", obj->name); + return retval; } switch (obj->pin_protocol) { case TPIU_SPPR_PROTOCOL_SYNC: @@ -687,21 +685,20 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const value = 0; } if (!value) { - struct jim_nvp *p; - jim_nvp_value2name(interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p); - LOG_ERROR("%s does not support protocol %s", obj->name, p->name); - return JIM_ERR; + struct jim_nvp *p = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol); + command_print(CMD, "%s does not support protocol %s", obj->name, p->name); + return ERROR_FAIL; } if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) { retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value); if (retval != ERROR_OK) { - LOG_ERROR("Cannot read TPIU register SSPSR"); - return JIM_ERR; + command_print(CMD, "Cannot read TPIU register SSPSR"); + return retval; } if (!(value & BIT(obj->port_width - 1))) { - LOG_ERROR("TPIU does not support port-width of %d bits", obj->port_width); - return JIM_ERR; + command_print(CMD, "TPIU does not support port-width of %d bits", obj->port_width); + return ERROR_FAIL; } } @@ -713,41 +710,42 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const struct arm_tpiu_swo_priv_connection *priv = malloc(sizeof(*priv)); if (!priv) { LOG_ERROR("Out of memory"); - return JIM_ERR; + return ERROR_FAIL; } priv->obj = obj; LOG_INFO("starting trace server for %s on %s", obj->name, &obj->out_filename[1]); retval = add_service(&arm_tpiu_swo_service_driver, &obj->out_filename[1], CONNECTION_LIMIT_UNLIMITED, priv); if (retval != ERROR_OK) { - LOG_ERROR("Can't configure trace TCP port %s", &obj->out_filename[1]); - return JIM_ERR; + command_print(CMD, "Can't configure trace TCP port %s", &obj->out_filename[1]); + return retval; } } else if (strcmp(obj->out_filename, "-")) { obj->file = fopen(obj->out_filename, "ab"); if (!obj->file) { - LOG_ERROR("Can't open trace destination file \"%s\"", obj->out_filename); - return JIM_ERR; + command_print(CMD, "Can't open trace destination file \"%s\"", obj->out_filename); + return ERROR_FAIL; } } retval = adapter_config_trace(true, obj->pin_protocol, obj->port_width, &swo_pin_freq, obj->traceclkin_freq, &prescaler); if (retval != ERROR_OK) { - LOG_ERROR("Failed to start adapter's trace"); + command_print(CMD, "Failed to start adapter's trace"); arm_tpiu_swo_close_output(obj); - return JIM_ERR; + return retval; } if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) if (!swo_pin_freq) { if (obj->swo_pin_freq) - LOG_ERROR("Adapter rejected SWO pin frequency %d Hz", obj->swo_pin_freq); + command_print(CMD, "Adapter rejected SWO pin frequency %d Hz", obj->swo_pin_freq); else - LOG_ERROR("Adapter does not support auto-detection of SWO pin frequency nor a default value"); + command_print(CMD, + "Adapter does not support auto-detection of SWO pin frequency nor a default value"); arm_tpiu_swo_close_output(obj); - return JIM_ERR; + return ERROR_FAIL; } if (obj->swo_pin_freq != swo_pin_freq) @@ -799,10 +797,10 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const /* END_DEPRECATED_TPIU */ obj->enabled = true; - return JIM_OK; + return ERROR_OK; error_exit: - LOG_ERROR("Error!"); + command_print(CMD, "Error!"); if (obj->en_capture) { obj->en_capture = false; @@ -811,27 +809,22 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const target_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj); - retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL); - if (retval != ERROR_OK) { - LOG_ERROR("Failed to stop adapter's trace"); - return JIM_ERR; - } + int retval1 = adapter_config_trace(false, 0, 0, NULL, 0, NULL); + if (retval1 != ERROR_OK) + command_print(CMD, "Failed to stop adapter's trace"); } - return JIM_ERR; + return retval; } -static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_arm_tpiu_swo_disable) { - struct command *c = jim_to_command(interp); - struct arm_tpiu_swo_object *obj = c->jim_handler_data; + struct arm_tpiu_swo_object *obj = CMD_DATA; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; if (!obj->enabled) - return JIM_OK; + return ERROR_OK; obj->enabled = false; arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_DISABLE); @@ -845,20 +838,19 @@ static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const int retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL); if (retval != ERROR_OK) { - LOG_ERROR("Failed to stop adapter's trace"); - return JIM_ERR; + command_print(CMD, "Failed to stop adapter's trace"); + return retval; } } arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE); /* START_DEPRECATED_TPIU */ - struct command_context *cmd_ctx = current_command_context(interp); - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(CMD_CTX); target_handle_event(target, TARGET_EVENT_TRACE_CONFIG); /* END_DEPRECATED_TPIU */ - return JIM_OK; + return ERROR_OK; } static const struct command_registration arm_tpiu_swo_instance_command_handlers[] = { @@ -886,14 +878,14 @@ static const struct command_registration arm_tpiu_swo_instance_command_handlers[ { .name = "enable", .mode = COMMAND_ANY, - .jim_handler = jim_arm_tpiu_swo_enable, + .handler = handle_arm_tpiu_swo_enable, .usage = "", .help = "Enables the TPIU/SWO output", }, { .name = "disable", .mode = COMMAND_EXEC, - .jim_handler = jim_arm_tpiu_swo_disable, + .handler = handle_arm_tpiu_swo_disable, .usage = "", .help = "Disables the TPIU/SWO output", }, @@ -989,39 +981,34 @@ static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const return JIM_ERR; } -static int jim_arm_tpiu_swo_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_arm_tpiu_swo_names) { struct arm_tpiu_swo_object *obj; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - list_for_each_entry(obj, &all_tpiu_swo, lh) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, obj->name, -1)); - } - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + list_for_each_entry(obj, &all_tpiu_swo, lh) + command_print(CMD, "%s", obj->name); + + return ERROR_OK; } -static int jim_arm_tpiu_swo_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_arm_tpiu_swo_init) { - struct command_context *cmd_ctx = current_command_context(interp); struct arm_tpiu_swo_object *obj; - int retval = JIM_OK; + int retval = ERROR_OK; + + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } list_for_each_entry(obj, &all_tpiu_swo, lh) { if (!obj->deferred_enable) continue; LOG_DEBUG("%s: running enable during init", obj->name); - int retval2 = command_run_linef(cmd_ctx, "%s enable", obj->name); + int retval2 = command_run_linef(CMD_CTX, "%s enable", obj->name); if (retval2 != ERROR_OK) - retval = JIM_ERR; + retval = retval2; } return retval; } @@ -1193,14 +1180,14 @@ static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = { { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_arm_tpiu_swo_names, + .handler = handle_arm_tpiu_swo_names, .usage = "", .help = "Lists all registered TPIU and SWO objects by name", }, { .name = "init", .mode = COMMAND_EXEC, - .jim_handler = jim_arm_tpiu_swo_init, + .handler = handle_arm_tpiu_swo_init, .usage = "", .help = "Initialize TPIU and SWO", }, diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 48af5035a0..9586adc977 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -989,36 +989,37 @@ COMMAND_HANDLER(handle_arm_disassemble_command) #endif } -static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_armv4_5_mcrmrc) { - struct command_context *context; - struct target *target; - struct arm *arm; - int retval; + bool is_mcr = false; + unsigned int arg_cnt = 5; + + if (!strcmp(CMD_NAME, "mcr")) { + is_mcr = true; + arg_cnt = 6; + } - context = current_command_context(interp); - assert(context); + if (arg_cnt != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; - target = get_current_target(context); + struct target *target = get_current_target(CMD_CTX); if (!target) { - LOG_ERROR("%s: no current target", __func__); - return JIM_ERR; + command_print(CMD, "no current target"); + return ERROR_FAIL; } if (!target_was_examined(target)) { - LOG_ERROR("%s: not yet examined", target_name(target)); - return JIM_ERR; + command_print(CMD, "%s: not yet examined", target_name(target)); + return ERROR_TARGET_NOT_EXAMINED; } - arm = target_to_arm(target); + + struct arm *arm = target_to_arm(target); if (!is_arm(arm)) { - LOG_ERROR("%s: not an ARM", target_name(target)); - return JIM_ERR; + command_print(CMD, "%s: not an ARM", target_name(target)); + return ERROR_FAIL; } - if ((argc < 6) || (argc > 7)) { - /* FIXME use the command name to verify # params... */ - LOG_ERROR("%s: wrong number of arguments", __func__); - return JIM_ERR; - } + if (target->state != TARGET_HALTED) + return ERROR_TARGET_NOT_HALTED; int cpnum; uint32_t op1; @@ -1026,95 +1027,68 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) uint32_t crn; uint32_t crm; uint32_t value; - long l; /* NOTE: parameter sequence matches ARM instruction set usage: * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX * The "rX" is necessarily omitted; it uses Tcl mechanisms. */ - retval = Jim_GetLong(interp, argv[1], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "coprocessor", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum); + if (cpnum & ~0xf) { + command_print(CMD, "coprocessor %d out of range", cpnum); + return ERROR_COMMAND_ARGUMENT_INVALID; } - cpnum = l; - retval = Jim_GetLong(interp, argv[2], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op1", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1); + if (op1 & ~0x7) { + command_print(CMD, "op1 %d out of range", op1); + return ERROR_COMMAND_ARGUMENT_INVALID; } - op1 = l; - retval = Jim_GetLong(interp, argv[3], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRn", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn); + if (crn & ~0xf) { + command_print(CMD, "CRn %d out of range", crn); + return ERROR_COMMAND_ARGUMENT_INVALID; } - crn = l; - retval = Jim_GetLong(interp, argv[4], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRm", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm); + if (crm & ~0xf) { + command_print(CMD, "CRm %d out of range", crm); + return ERROR_COMMAND_ARGUMENT_INVALID; } - crm = l; - retval = Jim_GetLong(interp, argv[5], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op2", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2); + if (op2 & ~0x7) { + command_print(CMD, "op2 %d out of range", op2); + return ERROR_COMMAND_ARGUMENT_INVALID; } - op2 = l; - - value = 0; - /* FIXME don't assume "mrc" vs "mcr" from the number of params; - * that could easily be a typo! Check both... - * + /* * FIXME change the call syntax here ... simplest to just pass * the MRC() or MCR() instruction to be executed. That will also * let us support the "mrc2" and "mcr2" opcodes (toggling one bit) * if that's ever needed. */ - if (argc == 7) { - retval = Jim_GetLong(interp, argv[6], &l); - if (retval != JIM_OK) - return retval; - value = l; + if (is_mcr) { + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value); /* NOTE: parameters reordered! */ /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); + int retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); if (retval != ERROR_OK) - return JIM_ERR; + return retval; } else { + value = 0; /* NOTE: parameters reordered! */ /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); + int retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); if (retval != ERROR_OK) - return JIM_ERR; + return retval; - Jim_SetResult(interp, Jim_NewIntObj(interp, value)); + command_print(CMD, "0x%" PRIx32, value); } - return JIM_OK; + return ERROR_OK; } static const struct command_registration arm_exec_command_handlers[] = { @@ -1128,14 +1102,14 @@ static const struct command_registration arm_exec_command_handlers[] = { { .name = "mcr", .mode = COMMAND_EXEC, - .jim_handler = &jim_mcrmrc, + .handler = handle_armv4_5_mcrmrc, .help = "write coprocessor register", .usage = "cpnum op1 CRn CRm op2 value", }, { .name = "mrc", .mode = COMMAND_EXEC, - .jim_handler = &jim_mcrmrc, + .handler = handle_armv4_5_mcrmrc, .help = "read coprocessor register", .usage = "cpnum op1 CRn CRm op2", }, diff --git a/src/target/espressif/esp_semihosting.c b/src/target/espressif/esp_semihosting.c index 5e9cb94573..51d499866d 100644 --- a/src/target/espressif/esp_semihosting.c +++ b/src/target/espressif/esp_semihosting.c @@ -17,12 +17,10 @@ static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target) { - const char *arch = target_get_gdb_arch(target); - if (arch) { - if (strncmp(arch, "xtensa", 6) == 0) - return &target_to_esp_xtensa(target)->semihost; - /* TODO: add riscv */ - } + struct xtensa *xtensa = target->arch_info; + if (xtensa->common_magic == XTENSA_COMMON_MAGIC) + return &target_to_esp_xtensa(target)->semihost; + /* TODO: add riscv */ LOG_ERROR("Unknown target arch!"); return NULL; } diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 491b247b15..14e3f3b27a 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -36,6 +36,8 @@ static int mips_m4k_internal_restore(struct target *target, int current, static int mips_m4k_halt(struct target *target); static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer); +static int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address, + uint32_t count, uint8_t *buffer); static int mips_m4k_examine_debug_reason(struct target *target) { @@ -1021,6 +1023,12 @@ static int mips_m4k_read_memory(struct target *target, target_addr_t address, if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) return ERROR_TARGET_UNALIGNED_ACCESS; + if (size == 4 && count > 32) { + int retval = mips_m4k_bulk_read_memory(target, address, count, buffer); + if (retval == ERROR_OK) + return ERROR_OK; + LOG_WARNING("Falling back to non-bulk read"); + } /* since we don't know if buffer is aligned, we allocate new mem that is always aligned */ void *t = NULL; @@ -1218,8 +1226,8 @@ static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t addre fast_data_area = mips32->fast_data_area; - if (address <= fast_data_area->address + fast_data_area->size && - fast_data_area->address <= address + count) { + if (address < (fast_data_area->address + fast_data_area->size) && + fast_data_area->address < (address + count)) { LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area " "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").", fast_data_area->address, address, address + count); @@ -1249,6 +1257,71 @@ static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t addre return retval; } +static int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address, + uint32_t count, uint8_t *buffer) +{ + struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; + struct working_area *fast_data_area; + int retval; + int write_t = 0; + + LOG_DEBUG("address: " TARGET_ADDR_FMT ", count: 0x%8.8" PRIx32 "", + address, count); + + /* check alignment */ + if (address & 0x3u) + return ERROR_TARGET_UNALIGNED_ACCESS; + + if (!mips32->fast_data_area) { + /* Get memory for block read handler + * we preserve this area between calls and gain a speed increase + * of about 3kb/sec when reading flash + * this will be released/nulled by the system when the target is resumed or reset */ + retval = target_alloc_working_area(target, + MIPS32_FASTDATA_HANDLER_SIZE, + &mips32->fast_data_area); + if (retval != ERROR_OK) { + LOG_ERROR("No working area available"); + return retval; + } + + /* reset fastadata state so the algo get reloaded */ + ejtag_info->fast_access_save = -1; + } + + fast_data_area = mips32->fast_data_area; + + if (address < (fast_data_area->address + fast_data_area->size) && + fast_data_area->address < (address + count)) { + LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within read area " + "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").", + fast_data_area->address, address, address + count); + LOG_ERROR("Change work-area-phys or load_image address!"); + return ERROR_FAIL; + } + + /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */ + /* but byte array represents target endianness */ + uint32_t *t = malloc(count * sizeof(uint32_t)); + if (!t) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address, + count, t); + + target_buffer_set_u32_array(target, buffer, count, t); + + free(t); + + if (retval != ERROR_OK) + LOG_ERROR("Fastdata access Failed"); + + return retval; +} + static int mips_m4k_verify_pointer(struct command_invocation *cmd, struct mips_m4k_common *mips_m4k) { diff --git a/src/target/target.c b/src/target/target.c index e795f784dd..0ea8084734 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -4592,57 +4592,36 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, return e; } -static int target_jim_read_memory(Jim_Interp *interp, int argc, - Jim_Obj * const *argv) +COMMAND_HANDLER(handle_target_read_memory) { /* - * argv[1] = memory address - * argv[2] = desired element width in bits - * argv[3] = number of elements to read - * argv[4] = optional "phys" + * CMD_ARGV[0] = memory address + * CMD_ARGV[1] = desired element width in bits + * CMD_ARGV[2] = number of elements to read + * CMD_ARGV[3] = optional "phys" */ - if (argc < 4 || argc > 5) { - Jim_WrongNumArgs(interp, 1, argv, "address width count ['phys']"); - return JIM_ERR; - } + if (CMD_ARGC < 3 || CMD_ARGC > 4) + return ERROR_COMMAND_SYNTAX_ERROR; /* Arg 1: Memory address. */ - jim_wide wide_addr; - int e; - e = Jim_GetWide(interp, argv[1], &wide_addr); - - if (e != JIM_OK) - return e; - - target_addr_t addr = (target_addr_t)wide_addr; + target_addr_t addr; + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], addr); /* Arg 2: Bit width of one element. */ - long l; - e = Jim_GetLong(interp, argv[2], &l); - - if (e != JIM_OK) - return e; - - const unsigned int width_bits = l; + unsigned int width_bits; + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], width_bits); /* Arg 3: Number of elements to read. */ - e = Jim_GetLong(interp, argv[3], &l); - - if (e != JIM_OK) - return e; - - size_t count = l; + unsigned int count; + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], count); /* Arg 4: Optional 'phys'. */ bool is_phys = false; - - if (argc > 4) { - const char *phys = Jim_GetString(argv[4], NULL); - - if (strcmp(phys, "phys")) { - Jim_SetResultFormatted(interp, "invalid argument '%s', must be 'phys'", phys); - return JIM_ERR; + if (CMD_ARGC == 4) { + if (strcmp(CMD_ARGV[3], "phys")) { + command_print(CMD, "invalid argument '%s', must be 'phys'", CMD_ARGV[3]); + return ERROR_COMMAND_ARGUMENT_INVALID; } is_phys = true; @@ -4655,37 +4634,33 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, case 64: break; default: - Jim_SetResultString(interp, "invalid width, must be 8, 16, 32 or 64", -1); - return JIM_ERR; + command_print(CMD, "invalid width, must be 8, 16, 32 or 64"); + return ERROR_COMMAND_ARGUMENT_INVALID; } const unsigned int width = width_bits / 8; if ((addr + (count * width)) < addr) { - Jim_SetResultString(interp, "read_memory: addr + count wraps to zero", -1); - return JIM_ERR; + command_print(CMD, "read_memory: addr + count wraps to zero"); + return ERROR_COMMAND_ARGUMENT_INVALID; } if (count > 65536) { - Jim_SetResultString(interp, "read_memory: too large read request, exeeds 64K elements", -1); - return JIM_ERR; + command_print(CMD, "read_memory: too large read request, exceeds 64K elements"); + return ERROR_COMMAND_ARGUMENT_INVALID; } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx != NULL); - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(CMD_CTX); const size_t buffersize = 4096; uint8_t *buffer = malloc(buffersize); if (!buffer) { LOG_ERROR("Failed to allocate memory"); - return JIM_ERR; + return ERROR_FAIL; } - Jim_Obj *result_list = Jim_NewListObj(interp, NULL, 0); - Jim_IncrRefCount(result_list); - + char *separator = ""; while (count > 0) { const unsigned int max_chunk_len = buffersize / width; const size_t chunk_len = MIN(count, max_chunk_len); @@ -4698,11 +4673,15 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, retval = target_read_memory(target, addr, width, chunk_len, buffer); if (retval != ERROR_OK) { - LOG_ERROR("read_memory: read at " TARGET_ADDR_FMT " with width=%u and count=%zu failed", + LOG_DEBUG("read_memory: read at " TARGET_ADDR_FMT " with width=%u and count=%zu failed", addr, width_bits, chunk_len); - Jim_SetResultString(interp, "read_memory: failed to read memory", -1); - e = JIM_ERR; - break; + /* + * FIXME: we append the errmsg to the list of value already read. + * Add a way to flush and replace old output, but LOG_DEBUG() it + */ + command_print(CMD, "read_memory: failed to read memory"); + free(buffer); + return retval; } for (size_t i = 0; i < chunk_len ; i++) { @@ -4723,11 +4702,8 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, break; } - char value_buf[19]; - snprintf(value_buf, sizeof(value_buf), "0x%" PRIx64, v); - - Jim_ListAppendElement(interp, result_list, - Jim_NewStringObj(interp, value_buf, -1)); + command_print_sameline(CMD, "%s0x%" PRIx64, separator, v); + separator = " "; } count -= chunk_len; @@ -4736,15 +4712,7 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, free(buffer); - if (e != JIM_OK) { - Jim_DecrRefCount(interp, result_list); - return e; - } - - Jim_SetResult(interp, result_list); - Jim_DecrRefCount(interp, result_list); - - return JIM_OK; + return ERROR_OK; } static int get_u64_array_element(Jim_Interp *interp, const char *varname, size_t idx, uint64_t *val) @@ -5748,40 +5716,38 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv return JIM_OK; } -static int jim_target_was_examined(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_target_was_examined) { - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - Jim_SetResultBool(interp, target_was_examined(target)); - return JIM_OK; + struct target *target = get_current_target(CMD_CTX); + + command_print(CMD, "%d", target_was_examined(target) ? 1 : 0); + + return ERROR_OK; } -static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_target_examine_deferred) { - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - Jim_SetResultBool(interp, target->defer_examine); - return JIM_OK; + struct target *target = get_current_target(CMD_CTX); + + command_print(CMD, "%d", target->defer_examine ? 1 : 0); + + return ERROR_OK; } -static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_halt_gdb) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "[no parameters]"); - return JIM_ERR; - } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - if (target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT) != ERROR_OK) - return JIM_ERR; + struct target *target = get_current_target(CMD_CTX); - return JIM_OK; + return target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); } static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -5936,18 +5902,19 @@ COMMAND_HANDLER(handle_target_event_list) command_print(CMD, "***END***"); return ERROR_OK; } -static int jim_target_current_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv) + +COMMAND_HANDLER(handle_target_current_state) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "[no parameters]"); - return JIM_ERR; - } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - Jim_SetResultString(interp, target_state_name(target), -1); - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + struct target *target = get_current_target(CMD_CTX); + + command_print(CMD, "%s", target_state_name(target)); + + return ERROR_OK; } + static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { struct jim_getopt_info goi; @@ -6074,7 +6041,7 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "read_memory", .mode = COMMAND_EXEC, - .jim_handler = target_jim_read_memory, + .handler = handle_target_read_memory, .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory", .usage = "address width count ['phys']", }, @@ -6095,8 +6062,9 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "curstate", .mode = COMMAND_EXEC, - .jim_handler = jim_target_current_state, + .handler = handle_target_current_state, .help = "displays the current state of this target", + .usage = "", }, { .name = "arp_examine", @@ -6108,20 +6076,23 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "was_examined", .mode = COMMAND_EXEC, - .jim_handler = jim_target_was_examined, + .handler = handle_target_was_examined, .help = "used internally for reset processing", + .usage = "", }, { .name = "examine_deferred", .mode = COMMAND_EXEC, - .jim_handler = jim_target_examine_deferred, + .handler = handle_target_examine_deferred, .help = "used internally for reset processing", + .usage = "", }, { .name = "arp_halt_gdb", .mode = COMMAND_EXEC, - .jim_handler = jim_target_halt_gdb, + .handler = handle_target_halt_gdb, .help = "used internally for reset processing to halt GDB", + .usage = "", }, { .name = "arp_poll", @@ -6396,56 +6367,47 @@ static int target_create(struct jim_getopt_info *goi) return JIM_OK; } -static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_current) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - struct target *target = get_current_target_or_null(cmd_ctx); + struct target *target = get_current_target_or_null(CMD_CTX); if (target) - Jim_SetResultString(interp, target_name(target), -1); - return JIM_OK; + command_print(CMD, "%s", target_name(target)); + + return ERROR_OK; } -static int jim_target_types(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_types) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - for (unsigned x = 0; target_types[x]; x++) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, target_types[x]->name, -1)); - } - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + for (unsigned int x = 0; target_types[x]; x++) + command_print(CMD, "%s", target_types[x]->name); + + return ERROR_OK; } -static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_names) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + struct target *target = all_targets; while (target) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, target_name(target), -1)); + command_print(CMD, "%s", target_name(target)); target = target->next; } - return JIM_OK; + + return ERROR_OK; } static struct target_list * __attribute__((warn_unused_result)) -create_target_list_node(Jim_Obj *const name) { - int len; - const char *targetname = Jim_GetString(name, &len); +create_target_list_node(const char *targetname) +{ struct target *target = get_target(targetname); LOG_DEBUG("%s ", targetname); if (!target) @@ -6461,7 +6423,8 @@ create_target_list_node(Jim_Obj *const name) { return new; } -static int get_target_with_common_rtos_type(struct list_head *lh, struct target **result) +static int get_target_with_common_rtos_type(struct command_invocation *cmd, + struct list_head *lh, struct target **result) { struct target *target = NULL; struct target_list *curr; @@ -6469,39 +6432,39 @@ static int get_target_with_common_rtos_type(struct list_head *lh, struct target struct rtos *curr_rtos = curr->target->rtos; if (curr_rtos) { if (target && target->rtos && target->rtos->type != curr_rtos->type) { - LOG_ERROR("Different rtos types in members of one smp target!"); - return JIM_ERR; + command_print(cmd, "Different rtos types in members of one smp target!"); + return ERROR_FAIL; } target = curr->target; } } *result = target; - return JIM_OK; + return ERROR_OK; } -static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_smp) { static int smp_group = 1; - if (argc == 1) { + if (CMD_ARGC == 0) { LOG_DEBUG("Empty SMP target"); - return JIM_OK; + return ERROR_OK; } - LOG_DEBUG("%d", argc); - /* argv[1] = target to associate in smp - * argv[2] = target to associate in smp - * argv[3] ... + LOG_DEBUG("%d", CMD_ARGC); + /* CMD_ARGC[0] = target to associate in smp + * CMD_ARGC[1] = target to associate in smp + * CMD_ARGC[2] ... */ struct list_head *lh = malloc(sizeof(*lh)); if (!lh) { LOG_ERROR("Out of memory"); - return JIM_ERR; + return ERROR_FAIL; } INIT_LIST_HEAD(lh); - for (int i = 1; i < argc; i++) { - struct target_list *new = create_target_list_node(argv[i]); + for (unsigned int i = 0; i < CMD_ARGC; i++) { + struct target_list *new = create_target_list_node(CMD_ARGV[i]); if (new) list_add_tail(&new->lh, lh); } @@ -6515,14 +6478,13 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) smp_group++; struct target *rtos_target; - int retval = get_target_with_common_rtos_type(lh, &rtos_target); - if (retval == JIM_OK && rtos_target) + int retval = get_target_with_common_rtos_type(CMD, lh, &rtos_target); + if (retval == ERROR_OK && rtos_target) retval = rtos_smp_init(rtos_target); return retval; } - static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { struct jim_getopt_info goi; @@ -6553,26 +6515,29 @@ static const struct command_registration target_subcommand_handlers[] = { { .name = "current", .mode = COMMAND_ANY, - .jim_handler = jim_target_current, + .handler = handle_target_current, .help = "Returns the currently selected target", + .usage = "", }, { .name = "types", .mode = COMMAND_ANY, - .jim_handler = jim_target_types, + .handler = handle_target_types, .help = "Returns the available target types as " "a list of strings", + .usage = "", }, { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_target_names, + .handler = handle_target_names, .help = "Returns the names of all targets as a list of strings", + .usage = "", }, { .name = "smp", .mode = COMMAND_ANY, - .jim_handler = jim_target_smp, + .handler = handle_target_smp, .usage = "targetname1 targetname2 ...", .help = "gather several target in a smp list" }, @@ -7205,7 +7170,7 @@ static const struct command_registration target_exec_command_handlers[] = { { .name = "read_memory", .mode = COMMAND_EXEC, - .jim_handler = target_jim_read_memory, + .handler = handle_target_read_memory, .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory", .usage = "address width count ['phys']", }, diff --git a/src/transport/transport.c b/src/transport/transport.c index c05db3f005..81d3d583bc 100644 --- a/src/transport/transport.c +++ b/src/transport/transport.c @@ -252,64 +252,62 @@ COMMAND_HANDLER(handle_transport_list) * set supported by the debug adapter being used. Return value * is scriptable (allowing "if swd then..." etc). */ -static int jim_transport_select(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_transport_select) { - int res; - switch (argc) { - case 1: /* autoselect if necessary, then return/display current config */ - if (!session) { - if (!allowed_transports) { - LOG_ERROR("Debug adapter does not support any transports? Check config file order."); - return JIM_ERR; - } - LOG_INFO("auto-selecting first available session transport \"%s\". " - "To override use 'transport select '.", allowed_transports[0]); - res = transport_select(global_cmd_ctx, allowed_transports[0]); - if (res != JIM_OK) - return res; - } - Jim_SetResultString(interp, session->name, -1); - return JIM_OK; - case 2: /* assign */ - if (session) { - if (!strcmp(session->name, argv[1]->bytes)) { - LOG_WARNING("Transport \"%s\" was already selected", session->name); - Jim_SetResultString(interp, session->name, -1); - return JIM_OK; - } else { - LOG_ERROR("Can't change session's transport after the initial selection was made"); - return JIM_ERR; - } - } + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; - /* Is this transport supported by our debug adapter? - * Example, "JTAG-only" means SWD is not supported. - * - * NOTE: requires adapter to have been set up, with - * transports declared via C. - */ + if (CMD_ARGC == 0) { + /* autoselect if necessary, then return/display current config */ + if (!session) { if (!allowed_transports) { - LOG_ERROR("Debug adapter doesn't support any transports?"); - return JIM_ERR; + command_print(CMD, "Debug adapter does not support any transports? Check config file order."); + return ERROR_FAIL; } + LOG_INFO("auto-selecting first available session transport \"%s\". " + "To override use 'transport select '.", allowed_transports[0]); + int retval = transport_select(CMD_CTX, allowed_transports[0]); + if (retval != ERROR_OK) + return retval; + } + command_print(CMD, "%s", session->name); + return ERROR_OK; + } - for (unsigned i = 0; allowed_transports[i]; i++) { + /* assign transport */ + if (session) { + if (!strcmp(session->name, CMD_ARGV[0])) { + LOG_WARNING("Transport \"%s\" was already selected", session->name); + command_print(CMD, "%s", session->name); + return ERROR_OK; + } + command_print(CMD, "Can't change session's transport after the initial selection was made"); + return ERROR_FAIL; + } - if (strcmp(allowed_transports[i], argv[1]->bytes) == 0) { - if (transport_select(global_cmd_ctx, argv[1]->bytes) == ERROR_OK) { - Jim_SetResultString(interp, session->name, -1); - return JIM_OK; - } - return JIM_ERR; - } - } + /* Is this transport supported by our debug adapter? + * Example, "JTAG-only" means SWD is not supported. + * + * NOTE: requires adapter to have been set up, with + * transports declared via C. + */ + if (!allowed_transports) { + command_print(CMD, "Debug adapter doesn't support any transports?"); + return ERROR_FAIL; + } - LOG_ERROR("Debug adapter doesn't support '%s' transport", argv[1]->bytes); - return JIM_ERR; - default: - Jim_WrongNumArgs(interp, 1, argv, "[too many parameters]"); - return JIM_ERR; + for (unsigned int i = 0; allowed_transports[i]; i++) { + if (!strcmp(allowed_transports[i], CMD_ARGV[0])) { + int retval = transport_select(CMD_CTX, CMD_ARGV[0]); + if (retval != ERROR_OK) + return retval; + command_print(CMD, "%s", session->name); + return ERROR_OK; + } } + + command_print(CMD, "Debug adapter doesn't support '%s' transport", CMD_ARGV[0]); + return ERROR_FAIL; } static const struct command_registration transport_commands[] = { @@ -333,7 +331,7 @@ static const struct command_registration transport_commands[] = { }, { .name = "select", - .jim_handler = jim_transport_select, + .handler = handle_transport_select, .mode = COMMAND_ANY, .help = "Select this session's transport", .usage = "[transport_name]", diff --git a/tcl/board/calao-usb-a9260.cfg b/tcl/board/calao-usb-a9260.cfg new file mode 100644 index 0000000000..52fede0fa5 --- /dev/null +++ b/tcl/board/calao-usb-a9260.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# CALAO Systems USB-A9260 (C01 and C02) + +adapter driver ftdi +ftdi device_desc "USB-A9260" +ftdi vid_pid 0x0403 0x6001 0x0403 0x6010 +ftdi layout_init 0x0c08 0x0f1b +ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 +ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 + +transport select jtag + +source [find target/at91sam9260.cfg] diff --git a/tcl/board/calao-usb-a9g20-c01.cfg b/tcl/board/calao-usb-a9g20-c01.cfg new file mode 100644 index 0000000000..6c4bd40fe9 --- /dev/null +++ b/tcl/board/calao-usb-a9g20-c01.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# CALAO Systems USB-A9G20-C01 + +adapter driver ftdi +ftdi device_desc "USB-A9G20" +ftdi vid_pid 0x0403 0x6010 +ftdi layout_init 0x0c08 0x0f1b +ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 +ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 + +transport select jtag + +source [find target/at91sam9g20.cfg] diff --git a/tcl/cpld/xilinx-xc7.cfg b/tcl/cpld/xilinx-xc7.cfg index 22e0aea7f9..91a07f9eb4 100644 --- a/tcl/cpld/xilinx-xc7.cfg +++ b/tcl/cpld/xilinx-xc7.cfg @@ -33,19 +33,21 @@ jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \ -expected-id 0x03752093 \ -expected-id 0x03751093 \ -expected-id 0x03671093 \ - -expected-id 0x036B3093 \ - -expected-id 0x036B7093 \ - -expected-id 0x036BB093 \ - -expected-id 0x036BF093 \ -expected-id 0x03667093 \ -expected-id 0x03682093 \ -expected-id 0x03687093 \ -expected-id 0x03692093 \ -expected-id 0x03691093 \ - -expected-id 0x03696093 \ - -expected-id 0x036D5093 \ - -expected-id 0x036D9093 \ - -expected-id 0x036DB093 + -expected-id 0x03696093 + +#jtag newtap $_CHIPNAME tap -irlen 24 -ignore-version \ +# -expected-id 0x036B3093 -expected-id 0x036B7093 \ +# -expected-id 0x036BB093 -expected-id 0x036BF093 \ +# -expected-id 0x036D5093 + +#jtag newtap $_CHIPNAME tap -irlen 22 -ignore-version -expected-id 0x036D9093 + +#jtag newtap $_CHIPNAME tap -irlen 38 -ignore-version -expected-id 0x036DB093 pld device virtex2 $_CHIPNAME.tap 1 diff --git a/tcl/interface/calao-usb-a9260.cfg b/tcl/interface/calao-usb-a9260.cfg deleted file mode 100644 index ff652ef8fb..0000000000 --- a/tcl/interface/calao-usb-a9260.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -# -# CALAO Systems USB-A9260 common -C01 -C02 setup -# -# http://www.calao-systems.com/ -# -# See calao-usb-a9260-c01.cfg and calao-usb-a9260-c02.cfg. -# - -adapter srst delay 200 -jtag_ntrst_delay 200 diff --git a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg b/tcl/interface/ftdi/calao-usb-a9260-c01.cfg deleted file mode 100644 index c84e778746..0000000000 --- a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -# -# CALAO Systems USB-A9260-C01 -# -# http://www.calao-systems.com/ -# - -echo "WARNING!" -echo "This file was not tested with real interface, but is assumed to work as this" -echo "interface uses the same layout as configs that were verified. Please report your" -echo "experience with this file to openocd-devel mailing list, so it could be marked" -echo "as working or fixed." - -adapter driver ftdi -ftdi device_desc "USB-A9260" -ftdi vid_pid 0x0403 0x6010 - -ftdi layout_init 0x0c08 0x0f1b -ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 - -script interface/calao-usb-a9260.cfg -script target/at91sam9260minimal.cfg diff --git a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg b/tcl/interface/ftdi/calao-usb-a9260-c02.cfg deleted file mode 100644 index 9d79b26005..0000000000 --- a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -# -# CALAO Systems USB-A9260-C02 -# -# http://www.calao-systems.com/ -# - -echo "WARNING!" -echo "This file was not tested with real interface, but is assumed to work as this" -echo "interface uses the same layout as configs that were verified. Please report your" -echo "experience with this file to openocd-devel mailing list, so it could be marked" -echo "as working or fixed." - -adapter driver ftdi -ftdi device_desc "USB-A9260" -ftdi vid_pid 0x0403 0x6001 - -ftdi layout_init 0x0c08 0x0f1b -ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 - -script interface/calao-usb-a9260.cfg -script target/at91sam9260minimal.cfg diff --git a/tcl/target/zynq_7000.cfg b/tcl/target/zynq_7000.cfg index 0272587c1e..a6f8995417 100644 --- a/tcl/target/zynq_7000.cfg +++ b/tcl/target/zynq_7000.cfg @@ -1,18 +1,34 @@ # SPDX-License-Identifier: GPL-2.0-or-later -# # Xilinx Zynq-7000 All Programmable SoC # # http://www.xilinx.com/products/silicon-devices/soc/zynq-7000/index.htm +# https://www.xilinx.com/member/forms/download/sim-model-eval-license-xef.html?filename=bsdl_zynq_2.zip # +# 0x03736093 XQ7Z100 XC7Z100I XC7Z100 +# 0x03731093 XQ7Z045 XC7Z045I XC7Z045 +# 0x0372c093 XQ7Z030 XC7Z030I XC7Z030 XA7Z030 +# 0x03727093 XQ7Z020 XC7Z020I XC7Z020 XA7Z020 +# 0x03732093 XC7Z035I XC7Z035 +# 0x0373b093 XC7Z015I XC7Z015 +# 0x03728093 XC7Z014S +# 0x0373c093 XC7Z012S +# 0x03722093 XC7Z010I XC7Z010 XA7Z010 +# 0x03723093 XC7Z007S set _CHIPNAME zynq set _TARGETNAME $_CHIPNAME.cpu -jtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \ - -expected-id 0x23727093 \ - -expected-id 0x13722093 \ +jtag newtap zynq_pl bs -irlen 6 -ignore-version -ircapture 0x1 -irmask 0x03 \ + -expected-id 0x03723093 \ + -expected-id 0x03722093 \ + -expected-id 0x0373c093 \ + -expected-id 0x03728093 \ + -expected-id 0x0373B093 \ + -expected-id 0x03732093 \ -expected-id 0x03727093 \ + -expected-id 0x0372C093 \ + -expected-id 0x03731093 \ -expected-id 0x03736093 jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477