Merge pull request #935 from riscv/from_upstream

Merge down up to 0384fe5 from upstream.
This commit is contained in:
Tim Newsome 2023-10-23 08:38:48 -07:00 committed by GitHub
commit 3b0561d081
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 863 additions and 1072 deletions

View File

@ -2,7 +2,7 @@
# Copyright (C) 2020 by Tarek BOUCHKATI <tarek.bouchkati@gmail.com> # Copyright (C) 2020 by Tarek BOUCHKATI <tarek.bouchkati@gmail.com>
on: pull_request on: push
name: OpenOCD Snapshot name: OpenOCD Snapshot
@ -30,7 +30,7 @@ jobs:
echo "LIBUSB1_SRC=$PWD/libusb-${LIBUSB1_VER}" >> $GITHUB_ENV echo "LIBUSB1_SRC=$PWD/libusb-${LIBUSB1_VER}" >> $GITHUB_ENV
- name: Prepare hidapi - name: Prepare hidapi
env: env:
HIDAPI_VER: 0.11.2 HIDAPI_VER: 0.13.1
run: | run: |
mkdir -p $DL_DIR && cd $DL_DIR mkdir -p $DL_DIR && cd $DL_DIR
wget "https://github.com/libusb/hidapi/archive/hidapi-${HIDAPI_VER}.tar.gz" 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" wget "https://github.com/aquynh/capstone/archive/${CAPSTONE_VER}.tar.gz"
tar -xzf ${CAPSTONE_VER}.tar.gz tar -xzf ${CAPSTONE_VER}.tar.gz
echo "CAPSTONE_SRC=$PWD/capstone-${CAPSTONE_VER}" >> $GITHUB_ENV 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 - name: Package OpenOCD for windows
env: env:
MAKE_JOBS: 2 MAKE_JOBS: 2
@ -64,7 +74,7 @@ jobs:
HIDAPI_CONFIG: --enable-shared --disable-static --disable-testgui HIDAPI_CONFIG: --enable-shared --disable-static --disable-testgui
LIBFTDI_CONFIG: -DSTATICLIBS=OFF -DEXAMPLES=OFF -DFTDI_EEPROM=OFF LIBFTDI_CONFIG: -DSTATICLIBS=OFF -DEXAMPLES=OFF -DFTDI_EEPROM=OFF
CAPSTONE_CONFIG: "CAPSTONE_BUILD_CORE_ONLY=yes CAPSTONE_STATIC=yes CAPSTONE_SHARED=no" 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: | run: |
# check if there is tag pointing at HEAD, otherwise take the HEAD SHA-1 as OPENOCD_TAG # check if there is tag pointing at HEAD, otherwise take the HEAD SHA-1 as OPENOCD_TAG
OPENOCD_TAG="`git tag --points-at HEAD`" OPENOCD_TAG="`git tag --points-at HEAD`"
@ -83,6 +93,7 @@ jobs:
# add missing dlls # add missing dlls
cd $HOST-root/usr cd $HOST-root/usr
cp `$HOST-gcc --print-file-name=libwinpthread-1.dll` ./bin/ 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/ cp `$HOST-gcc --print-file-name=libgcc_s_sjlj-1.dll` ./bin/
# prepare the artifact # prepare the artifact
ARTIFACT="openocd-${OPENOCD_TAG}-${HOST}.tar.gz" ARTIFACT="openocd-${OPENOCD_TAG}-${HOST}.tar.gz"
@ -90,9 +101,23 @@ jobs:
echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV
echo "IS_PRE_RELEASE=$IS_PRE_RELEASE" >> $GITHUB_ENV echo "IS_PRE_RELEASE=$IS_PRE_RELEASE" >> $GITHUB_ENV
echo "ARTIFACT_PATH=$PWD/$ARTIFACT" >> $GITHUB_ENV echo "ARTIFACT_PATH=$PWD/$ARTIFACT" >> $GITHUB_ENV
echo "ARTIFACT_NAME=openocd-windows-${OPENOCD_TAG}" >> $GITHUB_ENV
- name: Publish OpenOCD packaged for windows - name: Publish OpenOCD packaged for windows
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.ARTIFACT_PATH }} 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 }}

View File

@ -41,12 +41,14 @@ WORK_DIR=$PWD
: ${HIDAPI_SRC:=/path/to/hidapi} : ${HIDAPI_SRC:=/path/to/hidapi}
: ${LIBFTDI_SRC:=/path/to/libftdi} : ${LIBFTDI_SRC:=/path/to/libftdi}
: ${CAPSTONE_SRC:=/path/to/capstone} : ${CAPSTONE_SRC:=/path/to/capstone}
: ${LIBJAYLINK_SRC:=/path/to/libjaylink}
OPENOCD_SRC=`readlink -m $OPENOCD_SRC` OPENOCD_SRC=`readlink -m $OPENOCD_SRC`
LIBUSB1_SRC=`readlink -m $LIBUSB1_SRC` LIBUSB1_SRC=`readlink -m $LIBUSB1_SRC`
HIDAPI_SRC=`readlink -m $HIDAPI_SRC` HIDAPI_SRC=`readlink -m $HIDAPI_SRC`
LIBFTDI_SRC=`readlink -m $LIBFTDI_SRC` LIBFTDI_SRC=`readlink -m $LIBFTDI_SRC`
CAPSTONE_SRC=`readlink -m $CAPSTONE_SRC` CAPSTONE_SRC=`readlink -m $CAPSTONE_SRC`
LIBJAYLINK_SRC=`readlink -m $LIBJAYLINK_SRC`
HOST_TRIPLET=$1 HOST_TRIPLET=$1
BUILD_DIR=$WORK_DIR/$HOST_TRIPLET-build BUILD_DIR=$WORK_DIR/$HOST_TRIPLET-build
@ -54,6 +56,7 @@ LIBUSB1_BUILD_DIR=$BUILD_DIR/libusb1
HIDAPI_BUILD_DIR=$BUILD_DIR/hidapi HIDAPI_BUILD_DIR=$BUILD_DIR/hidapi
LIBFTDI_BUILD_DIR=$BUILD_DIR/libftdi LIBFTDI_BUILD_DIR=$BUILD_DIR/libftdi
CAPSTONE_BUILD_DIR=$BUILD_DIR/capstone CAPSTONE_BUILD_DIR=$BUILD_DIR/capstone
LIBJAYLINK_BUILD_DIR=$BUILD_DIR/libjaylink
OPENOCD_BUILD_DIR=$BUILD_DIR/openocd OPENOCD_BUILD_DIR=$BUILD_DIR/openocd
## Root of host file tree ## Root of host file tree
@ -158,6 +161,16 @@ libdir=${exec_prefix}/lib \
includedir=${prefix}/include/capstone\n\n;' $CAPSTONE_PC_FILE includedir=${prefix}/include/capstone\n\n;' $CAPSTONE_PC_FILE
fi 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 # OpenOCD build & install into sysroot
mkdir -p $OPENOCD_BUILD_DIR mkdir -p $OPENOCD_BUILD_DIR

View File

@ -8811,7 +8811,6 @@ power consumption (because the CPU is needlessly clocked).
@deffn {Command} {resume} [address] @deffn {Command} {resume} [address]
Resume the target at its current code position, Resume the target at its current code position,
or the optional @var{address} if it is provided. or the optional @var{address} if it is provided.
OpenOCD will wait 5 seconds for the target to resume.
@end deffn @end deffn
@deffn {Command} {step} [address] @deffn {Command} {step} [address]
@ -9132,8 +9131,10 @@ format. Optional @option{start} and @option{end} parameters allow to
limit the address range. limit the address range.
@end deffn @end deffn
@deffn {Command} {version} @deffn {Command} {version} [git]
Displays a string identifying the version of this OpenOCD server. 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 @end deffn
@deffn {Command} {virt2phys} virtual_address @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, In a debug session using JTAG for its transport protocol,
OpenOCD supports running such test files. OpenOCD supports running such test files.
@deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{[-]quiet}] @ @deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{-quiet}] @
[@option{[-]nil}] [@option{[-]progress}] [@option{[-]ignore_error}] @ [@option{-nil}] [@option{-progress}] [@option{-ignore_error}] @
[@option{-noreset}] [@option{-addcycles @var{cyclecount}}] [@option{-noreset}] [@option{-addcycles @var{cyclecount}}]
This issues a JTAG reset (Test-Logic-Reset) and then This issues a JTAG reset (Test-Logic-Reset) and then
runs the SVF script from @file{filename}. 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; specified by the SVF file with HIR, TIR, HDR and TDR commands;
instead, calculate them automatically according to the current JTAG instead, calculate them automatically according to the current JTAG
chain configuration, targeting @var{tapname}; chain configuration, targeting @var{tapname};
@item @option{[-]quiet} do not log every command before execution; @item @option{-quiet} do not log every command before execution;
@item @option{[-]nil} ``dry run'', i.e., do not perform any operations @item @option{-nil} ``dry run'', i.e., do not perform any operations
on the real interface; on the real interface;
@item @option{[-]progress} enable progress indication; @item @option{-progress} enable progress indication;
@item @option{[-]ignore_error} continue execution despite TDO check @item @option{-ignore_error} continue execution despite TDO check
errors. errors.
@item @option{-noreset} omit JTAG reset (Test-Logic-Reset) before executing @item @option{-noreset} omit JTAG reset (Test-Logic-Reset) before executing
content of the SVF file; content of the SVF file;

View File

@ -815,6 +815,7 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
if (buf_cnt != length) { if (buf_cnt != length) {
LOG_ERROR("Short read"); LOG_ERROR("Short read");
free(buffer); free(buffer);
fileio_close(fileio);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -1325,40 +1326,27 @@ COMMAND_HANDLER(handle_flash_banks_command)
return ERROR_OK; 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) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, return ERROR_COMMAND_SYNTAX_ERROR;
"no arguments to 'flash list' command");
return JIM_ERR;
}
Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
for (struct flash_bank *p = flash_bank_list(); p; p = p->next) { for (struct flash_bank *p = flash_bank_list(); p; p = p->next) {
Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0); command_print(CMD,
"{\n"
Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1)); " name %s\n"
Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->name, -1)); " driver %s\n"
Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "driver", -1)); " base " TARGET_ADDR_FMT "\n"
Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1)); " size 0x%" PRIx32 "\n"
Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1)); " bus_width %u\n"
Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base)); " chip_width %u\n"
Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1)); " target %s\n"
Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size)); "}",
Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1)); p->name, p->driver->name, p->base, p->size, p->bus_width, p->chip_width,
Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width)); target_name(p->target));
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);
} }
Jim_SetResult(interp, list); return ERROR_OK;
return JIM_OK;
} }
COMMAND_HANDLER(handle_flash_init_command) COMMAND_HANDLER(handle_flash_init_command)
@ -1405,8 +1393,9 @@ static const struct command_registration flash_config_command_handlers[] = {
{ {
.name = "list", .name = "list",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_flash_list, .handler = handle_flash_list,
.help = "Returns a list of details about the flash banks.", .help = "Returns a list of details about the flash banks.",
.usage = "",
}, },
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };

View File

@ -662,19 +662,19 @@ void command_done(struct command_context *cmd_ctx)
} }
/* find full path to file */ /* 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) if (CMD_ARGC != 1)
return JIM_ERR; return ERROR_COMMAND_SYNTAX_ERROR;
const char *file = Jim_GetString(argv[1], NULL);
char *full_path = find_file(file); char *full_path = find_file(CMD_ARGV[0]);
if (!full_path) if (!full_path)
return JIM_ERR; return ERROR_COMMAND_ARGUMENT_INVALID;
Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path));
command_print(CMD, "%s", full_path);
free(full_path); free(full_path);
Jim_SetResult(interp, result); return ERROR_OK;
return JIM_OK;
} }
COMMAND_HANDLER(handle_echo) COMMAND_HANDLER(handle_echo)
@ -1165,7 +1165,7 @@ static const struct command_registration command_builtin_handlers[] = {
{ {
.name = "ocd_find", .name = "ocd_find",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_find, .handler = handle_find,
.help = "find full path to file", .help = "find full path to file",
.usage = "file", .usage = "file",
}, },

View File

@ -36,9 +36,11 @@
* clang for Apple defines * clang for Apple defines
* #define __nonnull _Nonnull * #define __nonnull _Nonnull
* that is a per argument attribute, incompatible with the gcc per function attribute __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 # undef __nonnull
#endif #endif
#ifndef __nonnull #ifndef __nonnull

View File

@ -27,13 +27,6 @@ struct list_head {
struct list_head *next, *prev; struct list_head *next, *prev;
}; };
struct hlist_head {
struct hlist_node *first;
};
struct hlist_node {
struct hlist_node *next, **pprev;
};
/* end local changes */ /* 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 list the entry to test
* @param head the head of the list * @param head the head of the list
*/ */
static inline int list_is_first(const struct list_head *list, static inline int list_is_first(const struct list_head *list, const struct list_head *head)
const struct list_head *head)
{ {
return list->prev == 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 list the entry to test
* @param head the head of the list * @param head the head of the list
*/ */
static inline int list_is_last(const struct list_head *list, static inline int list_is_last(const struct list_head *list, const struct list_head *head)
const struct list_head *head)
{ {
return list->next == 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 * list_empty - tests whether a list is empty
* @param head the list to test. * @param head the list to test.
@ -407,10 +408,9 @@ static inline void list_cut_position(struct list_head *list,
{ {
if (list_empty(head)) if (list_empty(head))
return; return;
if (list_is_singular(head) && if (list_is_singular(head) && !list_is_head(entry, head) && (entry != head->next))
(head->next != entry && head != entry))
return; return;
if (entry == head) if (list_is_head(entry, head))
INIT_LIST_HEAD(list); INIT_LIST_HEAD(list);
else else
__list_cut_position(list, head, entry); __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) \ #define list_next_entry(pos, member) \
list_entry((pos)->member.next, typeof(*(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 * list_prev_entry - get the prev element in list
* @param pos the type * to cursor * @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) \ #define list_prev_entry(pos, member) \
list_entry((pos)->member.prev, typeof(*(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 * list_for_each - iterate over a list
* @param pos the &struct list_head to use as a loop cursor. * @param pos the &struct list_head to use as a loop cursor.
* @param head the head for your list. * @param head the head for your list.
*/ */
#define list_for_each(pos, head) \ #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 * 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 != (head); \
pos = n, n = pos->prev) 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 * list_entry_is_head - test if the entry points to the head of the list
* @param pos the type * to cursor * @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. * Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is * IGNORED
* 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.
*/
#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 */ #endif /* OPENOCD_HELPER_LIST_H */

View File

@ -13,28 +13,21 @@
#include "log.h" #include "log.h"
#include "time_support.h" #include "time_support.h"
static int jim_util_ms(Jim_Interp *interp, COMMAND_HANDLER(handler_util_ms)
int argc,
Jim_Obj * const *argv)
{ {
if (argc != 1) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
}
/* Cast from 64 to 32 bit int works for 2's-compliment command_print(CMD, "%" PRId64, timeval_ms());
* when calculating differences*/
Jim_SetResult(interp, Jim_NewIntObj(interp, (int)timeval_ms()));
return JIM_OK; return ERROR_OK;
} }
static const struct command_registration util_command_handlers[] = { static const struct command_registration util_command_handlers[] = {
/* jim handlers */
{ {
.name = "ms", .name = "ms",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_util_ms, .handler = handler_util_ms,
.help = .help =
"Returns ever increasing milliseconds. Used to calculate differences in time.", "Returns ever increasing milliseconds. Used to calculate differences in time.",
.usage = "", .usage = "",

View File

@ -374,21 +374,18 @@ done:
return equal; 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 */ /* return the name of the interface */
/* TCL code might need to know the exact type... */ /* TCL code might need to know the exact type... */
/* FUTURE: we allow this as a means to "set" the interface. */ /* 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)"); if (CMD_ARGC != 0)
return JIM_ERR; return ERROR_COMMAND_SYNTAX_ERROR;
}
const char *name = adapter_driver ? adapter_driver->name : NULL; command_print(CMD, "%s", adapter_driver ? adapter_driver->name : "undefined");
Jim_SetResultString(goi.interp, name ? name : "undefined", -1);
return JIM_OK; return ERROR_OK;
} }
COMMAND_HANDLER(adapter_transports_command) COMMAND_HANDLER(adapter_transports_command)
@ -1123,9 +1120,10 @@ static const struct command_registration adapter_command_handlers[] = {
{ {
.name = "name", .name = "name",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_adapter_name, .handler = handle_adapter_name,
.help = "Returns the name of the currently " .help = "Returns the name of the currently "
"selected adapter (driver)", "selected adapter (driver)",
.usage = "",
}, },
{ {
.name = "srst", .name = "srst",

View File

@ -249,12 +249,15 @@ static int jim_command_pathmove(Jim_Interp *interp, int argc, Jim_Obj * const *a
return JIM_OK; return JIM_OK;
} }
COMMAND_HANDLER(handle_jtag_flush_count)
static int jim_command_flush_count(Jim_Interp *interp, int argc, Jim_Obj * const *args)
{ {
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" ... ? /* REVISIT Just what about these should "move" ... ?
@ -279,9 +282,10 @@ static const struct command_registration jtag_command_handlers_to_move[] = {
{ {
.name = "flush_count", .name = "flush_count",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_command_flush_count, .handler = handle_jtag_flush_count,
.help = "Returns the number of times the JTAG queue " .help = "Returns the number of times the JTAG queue "
"has been flushed.", "has been flushed.",
.usage = "",
}, },
{ {
.name = "pathmove", .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; if (CMD_ARGC != 0)
jim_getopt_setup(&goi, interp, argc-1, argv + 1); return ERROR_COMMAND_SYNTAX_ERROR;
if (goi.argc != 0) {
Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); return jtag_init_inner(CMD_CTX);
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;
} }
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; if (CMD_ARGC != 0)
struct jim_getopt_info goi; return ERROR_COMMAND_SYNTAX_ERROR;
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 (transport_is_jtag())
e = jtag_init_reset(context);
else if (transport_is_swd())
e = swd_init_reset(context);
if (e != ERROR_OK) { if (transport_is_jtag())
Jim_Obj *obj = Jim_NewIntObj(goi.interp, e); return jtag_init_reset(CMD_CTX);
Jim_SetResultFormatted(goi.interp, "error: %#s", obj);
return JIM_ERR; if (transport_is_swd())
} return swd_init_reset(CMD_CTX);
return JIM_OK;
return ERROR_OK;
} }
int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv) 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); 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; if (CMD_ARGC != 0)
jim_getopt_setup(&goi, interp, argc-1, argv + 1); return ERROR_COMMAND_SYNTAX_ERROR;
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;
for (tap = jtag_all_taps(); tap; tap = tap->next_tap) { for (struct jtag_tap *tap = jtag_all_taps(); tap; tap = tap->next_tap)
Jim_ListAppendElement(goi.interp, command_print(CMD, "%s", tap->dotted_name);
Jim_GetResult(goi.interp),
Jim_NewStringObj(goi.interp, return ERROR_OK;
tap->dotted_name, -1));
}
return JIM_OK;
} }
COMMAND_HANDLER(handle_jtag_init_command) COMMAND_HANDLER(handle_jtag_init_command)
@ -852,17 +828,19 @@ static const struct command_registration jtag_subcommand_handlers[] = {
{ {
.name = "arp_init", .name = "arp_init",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_jtag_arp_init, .handler = handle_jtag_arp_init,
.help = "Validates JTAG scan chain against the list of " .help = "Validates JTAG scan chain against the list of "
"declared TAPs using just the four standard JTAG " "declared TAPs using just the four standard JTAG "
"signals.", "signals.",
.usage = "",
}, },
{ {
.name = "arp_init-reset", .name = "arp_init-reset",
.mode = COMMAND_ANY, .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 " .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", .name = "newtap",
@ -921,8 +899,9 @@ static const struct command_registration jtag_subcommand_handlers[] = {
{ {
.name = "names", .name = "names",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_jtag_names, .handler = handle_jtag_names,
.help = "Returns list of all JTAG tap names.", .help = "Returns list of all JTAG tap names.",
.usage = "",
}, },
{ {
.chain = jtag_command_handlers_to_move, .chain = jtag_command_handlers_to_move,

View File

@ -51,24 +51,23 @@ static const char openocd_startup_tcl[] = {
}; };
/* Give scripts and TELNET a way to find out what version this is */ /* Give scripts and TELNET a way to find out what version this is */
static int jim_version_command(Jim_Interp *interp, int argc, COMMAND_HANDLER(handler_version_command)
Jim_Obj * const *argv)
{ {
if (argc > 2) char *version_str = OPENOCD_VERSION;
return JIM_ERR;
const char *str = "";
char *version_str;
version_str = OPENOCD_VERSION;
if (argc == 2) if (CMD_ARGC > 1)
str = Jim_GetString(argv[1], NULL); 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; 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, 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[] = { static const struct command_registration openocd_command_handlers[] = {
{ {
.name = "version", .name = "version",
.jim_handler = jim_version_command, .handler = handler_version_command,
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.help = "show program version", .help = "show program version",
.usage = "[git]",
}, },
{ {
.name = "noinit", .name = "noinit",

View File

@ -729,6 +729,7 @@ static int freertos_update_threads(struct rtos *rtos)
tasks_found++; tasks_found++;
list_thread_count--; list_thread_count--;
rtos->thread_count = tasks_found;
prev_list_elem_ptr = list_elem_ptr; prev_list_elem_ptr = list_elem_ptr;
list_elem_ptr = 0; list_elem_ptr = 0;
@ -750,7 +751,6 @@ static int freertos_update_threads(struct rtos *rtos)
} }
free(list_of_lists); free(list_of_lists);
rtos->thread_count = tasks_found;
return 0; return 0;
} }

View File

@ -150,17 +150,17 @@ COMMAND_HANDLER(handle_rtt_channels_command)
return ERROR_OK; return ERROR_OK;
} }
static int jim_channel_list(Jim_Interp *interp, int argc, COMMAND_HANDLER(handle_channel_list)
Jim_Obj * const *argv)
{ {
Jim_Obj *list;
Jim_Obj *channel_list;
char channel_name[CHANNEL_NAME_SIZE]; char channel_name[CHANNEL_NAME_SIZE];
const struct rtt_control *ctrl; const struct rtt_control *ctrl;
struct rtt_channel_info info; struct rtt_channel_info info;
if (CMD_ARGC != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
if (!rtt_found_cb()) { if (!rtt_found_cb()) {
Jim_SetResultFormatted(interp, "rtt: Control block not available"); command_print(CMD, "rtt: Control block not available");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -169,81 +169,47 @@ static int jim_channel_list(Jim_Interp *interp, int argc,
info.name = channel_name; info.name = channel_name;
info.name_length = sizeof(channel_name); info.name_length = sizeof(channel_name);
list = Jim_NewListObj(interp, NULL, 0); command_print(CMD, "{");
channel_list = Jim_NewListObj(interp, NULL, 0);
for (unsigned int i = 0; i < ctrl->num_up_channels; i++) { for (unsigned int i = 0; i < ctrl->num_up_channels; i++) {
int ret; int ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info);
Jim_Obj *tmp;
ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info);
if (ret != ERROR_OK) if (ret != ERROR_OK)
return ret; return ret;
if (!info.size) if (!info.size)
continue; continue;
tmp = Jim_NewListObj(interp, NULL, 0); command_print(CMD,
" {\n"
Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, " name %s\n"
"name", -1)); " size 0x%" PRIx32 "\n"
Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, " flags 0x%" PRIx32 "\n"
info.name, -1)); " }",
info.name, info.size, info.flags);
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);
} }
Jim_ListAppendElement(interp, list, channel_list); command_print(CMD, "}\n{");
channel_list = Jim_NewListObj(interp, NULL, 0);
for (unsigned int i = 0; i < ctrl->num_down_channels; i++) { for (unsigned int i = 0; i < ctrl->num_down_channels; i++) {
int ret; int ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info);
Jim_Obj *tmp;
ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info);
if (ret != ERROR_OK) if (ret != ERROR_OK)
return ret; return ret;
if (!info.size) if (!info.size)
continue; continue;
tmp = Jim_NewListObj(interp, NULL, 0); command_print(CMD,
" {\n"
Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, " name %s\n"
"name", -1)); " size 0x%" PRIx32 "\n"
Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, " flags 0x%" PRIx32 "\n"
info.name, -1)); " }",
info.name, info.size, info.flags);
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);
} }
Jim_ListAppendElement(interp, list, channel_list); command_print(CMD, "}");
Jim_SetResult(interp, list);
return JIM_OK; return ERROR_OK;
} }
static const struct command_registration rtt_subcommand_handlers[] = { static const struct command_registration rtt_subcommand_handlers[] = {
@ -284,7 +250,7 @@ static const struct command_registration rtt_subcommand_handlers[] = {
}, },
{ {
.name = "channellist", .name = "channellist",
.jim_handler = jim_channel_list, .handler = handle_channel_list,
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.help = "list available channels", .help = "list available channels",
.usage = "" .usage = ""

View File

@ -90,7 +90,7 @@ static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo)
return; return;
size_t ri = fifo->rd_idx; 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->buffer[idx] = fifo->buffer[ri++];
fifo->rd_idx = 0; 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) static struct ipdbg_service *ipdbg_find_service(struct ipdbg_hub *hub, uint8_t tool)
{ {
struct ipdbg_service *service; 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) if (service->hub == hub && service->tool == tool)
break; break;
} }
@ -160,7 +160,7 @@ static void ipdbg_add_service(struct ipdbg_service *service)
{ {
struct ipdbg_service *iservice; struct ipdbg_service *iservice;
if (ipdbg_first_service) { 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; iservice->next = service;
} else } else
@ -192,7 +192,7 @@ static int ipdbg_remove_service(struct ipdbg_service *service)
return ERROR_OK; 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) { if (service == iservice->next) {
iservice->next = service->next; iservice->next = service->next;
return ERROR_OK; 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) uint32_t user_instruction, struct ipdbg_virtual_ir_info *virtual_ir)
{ {
struct ipdbg_hub *hub = NULL; 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 (hub->tap == tap && hub->user_instruction == user_instruction) {
if ((!virtual_ir && !hub->virtual_ir) || if ((!virtual_ir && !hub->virtual_ir) ||
(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; struct ipdbg_hub *ihub;
if (ipdbg_first_hub) { 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; ihub->next = hub;
} else } else
@ -281,7 +281,7 @@ static int ipdbg_remove_hub(struct ipdbg_hub *hub)
return ERROR_OK; 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) { if (hub == ihub->next) {
ihub->next = hub->next; ihub->next = hub->next;
return ERROR_OK; return ERROR_OK;
@ -447,7 +447,7 @@ static int ipdbg_polling_callback(void *priv)
/* transfer dn buffers to jtag-hub */ /* transfer dn buffers to jtag-hub */
unsigned int num_transfers = 0; 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]; struct connection *conn = hub->connections[tool];
if (conn && conn->priv) { if (conn && conn->priv) {
struct ipdbg_connection *connection = 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 */ /* 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]; struct connection *conn = hub->connections[tool];
if (conn && conn->priv) { if (conn && conn->priv) {
struct ipdbg_connection *connection = conn->priv; struct ipdbg_connection *connection = conn->priv;

View File

@ -22,6 +22,7 @@
#include "svf.h" #include "svf.h"
#include "helper/system.h" #include "helper/system.h"
#include <helper/time_support.h> #include <helper/time_support.h>
#include <helper/nvp.h>
#include <stdbool.h> #include <stdbool.h>
/* SVF command */ /* SVF command */
@ -346,6 +347,37 @@ int svf_add_statemove(tap_state_t state_to)
return ERROR_FAIL; 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) COMMAND_HANDLER(handle_svf_command)
{ {
#define SVF_MIN_NUM_OF_OPTIONS 1 #define SVF_MIN_NUM_OF_OPTIONS 1
@ -355,10 +387,11 @@ COMMAND_HANDLER(handle_svf_command)
int64_t time_measure_ms; int64_t time_measure_ms;
int time_measure_s, time_measure_m; 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 * any additional devices in the scan chain, otherwise the device
* that should be affected * that should be affected
*/ */
struct jtag_tap *tap = NULL; struct jtag_tap *tap = NULL;
if ((CMD_ARGC < SVF_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > SVF_MAX_NUM_OF_OPTIONS)) 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; svf_addcycles = 0;
for (unsigned int i = 0; i < CMD_ARGC; i++) { 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]); svf_addcycles = atoi(CMD_ARGV[i + 1]);
if (svf_addcycles > SVF_MAX_ADDCYCLES) { if (svf_addcycles > SVF_MAX_ADDCYCLES) {
command_print(CMD, "addcycles: %s out of range", CMD_ARGV[i + 1]); 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++; i++;
} else if (strcmp(CMD_ARGV[i], "-tap") == 0) { break;
case OPT_TAP:
tap = jtag_tap_by_string(CMD_ARGV[i+1]); tap = jtag_tap_by_string(CMD_ARGV[i+1]);
if (!tap) { if (!tap) {
command_print(CMD, "Tap: %s unknown", CMD_ARGV[i+1]); 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++; i++;
} else if ((strcmp(CMD_ARGV[i], break;
"quiet") == 0) || (strcmp(CMD_ARGV[i], "-quiet") == 0))
case DEPRECATED_OPT_QUIET:
LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]);
/* fallthrough */
case OPT_QUIET:
svf_quiet = 1; 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; svf_nil = 1;
else if ((strcmp(CMD_ARGV[i], break;
"progress") == 0) || (strcmp(CMD_ARGV[i], "-progress") == 0))
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; svf_progress_enabled = 1;
else if ((strcmp(CMD_ARGV[i], break;
"ignore_error") == 0) || (strcmp(CMD_ARGV[i], "-ignore_error") == 0))
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; svf_ignore_error = 1;
else if (strcmp(CMD_ARGV[i], "-noreset") == 0) break;
case OPT_NORESET:
svf_noreset = true; svf_noreset = true;
else { break;
default:
svf_fd = fopen(CMD_ARGV[i], "r"); svf_fd = fopen(CMD_ARGV[i], "r");
if (!svf_fd) { if (!svf_fd) {
int err = errno; int err = errno;
command_print(CMD, "open(\"%s\"): %s", CMD_ARGV[i], strerror(err)); command_print(CMD, "open(\"%s\"): %s", CMD_ARGV[i], strerror(err));
/* no need to free anything now */ /* no need to free anything now */
return ERROR_COMMAND_SYNTAX_ERROR; 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) */ /* HDR %d TDI (0) */
if (svf_set_padding(&svf_para.hdr_para, header_dr_len, 0) != ERROR_OK) { ret = svf_set_padding(&svf_para.hdr_para, header_dr_len, 0);
LOG_ERROR("failed to set data header"); if (ret != ERROR_OK) {
return ERROR_FAIL; command_print(CMD, "failed to set data header");
goto free_all;
} }
/* HIR %d TDI (0xFF) */ /* HIR %d TDI (0xFF) */
if (svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF) != ERROR_OK) { ret = svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF);
LOG_ERROR("failed to set instruction header"); if (ret != ERROR_OK) {
return ERROR_FAIL; command_print(CMD, "failed to set instruction header");
goto free_all;
} }
/* TDR %d TDI (0) */ /* TDR %d TDI (0) */
if (svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0) != ERROR_OK) { ret = svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0);
LOG_ERROR("failed to set data trailer"); if (ret != ERROR_OK) {
return ERROR_FAIL; command_print(CMD, "failed to set data trailer");
goto free_all;
} }
/* TIR %d TDI (0xFF) */ /* TIR %d TDI (0xFF) */
if (svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF) != ERROR_OK) { ret = svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF);
LOG_ERROR("failed to set instruction trailer"); if (ret != ERROR_OK) {
return ERROR_FAIL; command_print(CMD, "failed to set instruction trailer");
goto free_all;
} }
} }
@ -546,7 +615,7 @@ COMMAND_HANDLER(handle_svf_command)
free_all: free_all:
fclose(svf_fd); fclose(svf_fd);
svf_fd = 0; svf_fd = NULL;
/* free buffers */ /* free buffers */
free(svf_command_buffer); free(svf_command_buffer);
@ -1566,7 +1635,7 @@ static const struct command_registration svf_command_handlers[] = {
.handler = handle_svf_command, .handler = handle_svf_command,
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.help = "Runs a SVF file.", .help = "Runs a SVF file.",
.usage = "[-tap device.tap] <file> [quiet] [nil] [progress] [ignore_error] [-noreset] [-addcycles numcycles]", .usage = "[-tap device.tap] [-quiet] [-nil] [-progress] [-ignore_error] [-noreset] [-addcycles numcycles] file",
}, },
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };

View File

@ -2952,53 +2952,41 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command)
return ERROR_OK; 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; 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; is_mcr = true;
arg_cnt = 7;
} else {
arg_cnt = 6; arg_cnt = 6;
} }
context = current_command_context(interp); if (arg_cnt != CMD_ARGC)
assert(context); return ERROR_COMMAND_SYNTAX_ERROR;
target = get_current_target(context); struct target *target = get_current_target(CMD_CTX);
if (!target) { if (!target) {
LOG_ERROR("%s: no current target", __func__); command_print(CMD, "no current target");
return JIM_ERR; return ERROR_FAIL;
} }
if (!target_was_examined(target)) { if (!target_was_examined(target)) {
LOG_ERROR("%s: not yet examined", target_name(target)); command_print(CMD, "%s: not yet examined", target_name(target));
return JIM_ERR; return ERROR_TARGET_NOT_EXAMINED;
} }
arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
if (!is_arm(arm)) { if (!is_arm(arm)) {
LOG_ERROR("%s: not an ARM", target_name(target)); command_print(CMD, "%s: not an ARM", target_name(target));
return JIM_ERR; return ERROR_FAIL;
} }
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED)
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
if (arm->core_state == ARM_STATE_AARCH64) { if (arm->core_state == ARM_STATE_AARCH64) {
LOG_ERROR("%s: not 32-bit arm target", target_name(target)); command_print(CMD, "%s: not 32-bit arm target", target_name(target));
return JIM_ERR; return ERROR_FAIL;
}
if (argc != arg_cnt) {
LOG_ERROR("%s: wrong number of arguments", __func__);
return JIM_ERR;
} }
int cpnum; int cpnum;
@ -3007,87 +2995,62 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
uint32_t crn; uint32_t crn;
uint32_t crm; uint32_t crm;
uint32_t value; uint32_t value;
long l;
/* NOTE: parameter sequence matches ARM instruction set usage: /* NOTE: parameter sequence matches ARM instruction set usage:
* MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX
* MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX
* The "rX" is necessarily omitted; it uses Tcl mechanisms. * The "rX" is necessarily omitted; it uses Tcl mechanisms.
*/ */
retval = Jim_GetLong(interp, argv[1], &l); COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum);
if (retval != JIM_OK) if (cpnum & ~0xf) {
return retval; command_print(CMD, "coprocessor %d out of range", cpnum);
if (l & ~0xf) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"coprocessor", (int) l);
return JIM_ERR;
} }
cpnum = l;
retval = Jim_GetLong(interp, argv[2], &l); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1);
if (retval != JIM_OK) if (op1 & ~0x7) {
return retval; command_print(CMD, "op1 %d out of range", op1);
if (l & ~0x7) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"op1", (int) l);
return JIM_ERR;
} }
op1 = l;
retval = Jim_GetLong(interp, argv[3], &l); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn);
if (retval != JIM_OK) if (crn & ~0xf) {
return retval; command_print(CMD, "CRn %d out of range", crn);
if (l & ~0xf) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"CRn", (int) l);
return JIM_ERR;
} }
crn = l;
retval = Jim_GetLong(interp, argv[4], &l); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm);
if (retval != JIM_OK) if (crm & ~0xf) {
return retval; command_print(CMD, "CRm %d out of range", crm);
if (l & ~0xf) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"CRm", (int) l);
return JIM_ERR;
} }
crm = l;
retval = Jim_GetLong(interp, argv[5], &l); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2);
if (retval != JIM_OK) if (op2 & ~0x7) {
return retval; command_print(CMD, "op2 %d out of range", op2);
if (l & ~0x7) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"op2", (int) l);
return JIM_ERR;
} }
op2 = l;
value = 0; if (is_mcr) {
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value);
if (is_mcr == true) {
retval = Jim_GetLong(interp, argv[6], &l);
if (retval != JIM_OK)
return retval;
value = l;
/* NOTE: parameters reordered! */ /* NOTE: parameters reordered! */
/* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ /* 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) if (retval != ERROR_OK)
return JIM_ERR; return retval;
} else { } else {
value = 0;
/* NOTE: parameters reordered! */ /* NOTE: parameters reordered! */
/* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ /* 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) 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[] = { static const struct command_registration aarch64_exec_command_handlers[] = {
@ -3122,14 +3085,14 @@ static const struct command_registration aarch64_exec_command_handlers[] = {
{ {
.name = "mcr", .name = "mcr",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_mcrmrc, .handler = aarch64_mcrmrc_command,
.help = "write coprocessor register", .help = "write coprocessor register",
.usage = "cpnum op1 CRn CRm op2 value", .usage = "cpnum op1 CRn CRm op2 value",
}, },
{ {
.name = "mrc", .name = "mrc",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_mcrmrc, .handler = aarch64_mcrmrc_command,
.help = "read coprocessor register", .help = "read coprocessor register",
.usage = "cpnum op1 CRn CRm op2", .usage = "cpnum op1 CRn CRm op2",
}, },

View File

@ -566,14 +566,20 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
/* restore SELECT register first */ /* restore SELECT register first */
if (!list_empty(&replay_list)) { if (!list_empty(&replay_list)) {
el = list_first_entry(&replay_list, struct dap_cmd, lh); 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, 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) { if (!tmp) {
retval = ERROR_JTAG_DEVICE_ERROR; retval = ERROR_JTAG_DEVICE_ERROR;
goto done; goto done;
} }
list_add(&tmp->lh, &replay_list); list_add(&tmp->lh, &replay_list);
/* TODO: ADIv6 DP SELECT1 handling */
dap->select = DP_SELECT_INVALID; dap->select = DP_SELECT_INVALID;
} }

View File

@ -13,7 +13,7 @@
* is a transport level interface, with "target/arm_adi_v5.[hc]" code * is a transport level interface, with "target/arm_adi_v5.[hc]" code
* understanding operation semantics, shared with the JTAG transport. * understanding operation semantics, shared with the JTAG transport.
* *
* Single-DAP support only. * Single DAP and multidrop-SWD support.
* *
* for details, see "ARM IHI 0031A" * for details, see "ARM IHI 0031A"
* ARM Debug Interface v5 Architecture Specification * ARM Debug Interface v5 Architecture Specification

View File

@ -525,20 +525,17 @@ static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return cti_create(&goi); 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; struct arm_cti *obj;
if (argc != 1) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
} list_for_each_entry(obj, &all_cti, lh)
Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); command_print(CMD, "%s", obj->name);
list_for_each_entry(obj, &all_cti, lh) {
Jim_ListAppendElement(interp, Jim_GetResult(interp), return ERROR_OK;
Jim_NewStringObj(interp, obj->name, -1));
}
return JIM_OK;
} }
@ -553,7 +550,7 @@ static const struct command_registration cti_subcommand_handlers[] = {
{ {
.name = "names", .name = "names",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_cti_names, .handler = cti_handle_names,
.usage = "", .usage = "",
.help = "Lists all registered CTI objects by name", .help = "Lists all registered CTI objects by name",
}, },

View File

@ -421,20 +421,16 @@ static int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return dap_create(&goi); return dap_create(&goi);
} }
static int jim_dap_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) COMMAND_HANDLER(handle_dap_names)
{ {
struct arm_dap_object *obj; if (CMD_ARGC != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
if (argc != 1) { struct arm_dap_object *obj;
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); list_for_each_entry(obj, &all_dap, lh)
return JIM_ERR; command_print(CMD, "%s", obj->name);
}
Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); return ERROR_OK;
list_for_each_entry(obj, &all_dap, lh) {
Jim_ListAppendElement(interp, Jim_GetResult(interp),
Jim_NewStringObj(interp, obj->name, -1));
}
return JIM_OK;
} }
COMMAND_HANDLER(handle_dap_init) COMMAND_HANDLER(handle_dap_init)
@ -500,7 +496,7 @@ static const struct command_registration dap_subcommand_handlers[] = {
{ {
.name = "names", .name = "names",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_dap_names, .handler = handle_dap_names,
.usage = "", .usage = "",
.help = "Lists all registered DAP instances by name", .help = "Lists all registered DAP instances by name",
}, },

View File

@ -595,54 +595,52 @@ static const struct service_driver arm_tpiu_swo_service_driver = {
.keep_client_alive_handler = NULL, .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 = CMD_DATA;
struct arm_tpiu_swo_object *obj = c->jim_handler_data;
struct command_context *cmd_ctx = current_command_context(interp);
uint32_t value; uint32_t value;
int retval; int retval;
if (argc != 1) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
}
if (cmd_ctx->mode == COMMAND_CONFIG) { if (CMD_CTX->mode == COMMAND_CONFIG) {
LOG_DEBUG("%s: enable deferred", obj->name); LOG_DEBUG("%s: enable deferred", obj->name);
obj->deferred_enable = true; obj->deferred_enable = true;
return JIM_OK; return ERROR_OK;
} }
if (obj->enabled) if (obj->enabled)
return JIM_OK; return ERROR_OK;
if (transport_is_hla() && obj->spot.ap_num != 0) { 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); command_print(CMD,
return JIM_ERR; "Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport",
obj->spot.ap_num);
return ERROR_FAIL;
} }
if (!obj->traceclkin_freq) { if (!obj->traceclkin_freq) {
LOG_ERROR("Trace clock-in frequency not set"); command_print(CMD, "Trace clock-in frequency not set");
return JIM_ERR; return ERROR_FAIL;
} }
if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)
if (!obj->swo_pin_freq) if (!obj->swo_pin_freq)
LOG_DEBUG("SWO pin frequency not set, will be autodetected by the adapter"); 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 */ /* START_DEPRECATED_TPIU */
if (obj->recheck_ap_cur_target) { if (obj->recheck_ap_cur_target) {
if (strcmp(target->type->name, "cortex_m") && if (strcmp(target->type->name, "cortex_m") &&
strcmp(target->type->name, "hla_target")) { strcmp(target->type->name, "hla_target")) {
LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA"); LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA");
return JIM_ERR; return ERROR_FAIL;
} }
if (!target_was_examined(target)) { if (!target_was_examined(target)) {
LOG_ERROR(MSG "Current target not examined yet"); LOG_ERROR(MSG "Current target not examined yet");
return JIM_ERR; return ERROR_FAIL;
} }
struct cortex_m_common *cm = target_to_cm(target); struct cortex_m_common *cm = target_to_cm(target);
obj->recheck_ap_cur_target = false; 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) { if (!obj->ap) {
obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num); obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num);
if (!obj->ap) { if (!obj->ap) {
LOG_ERROR("Cannot get AP"); command_print(CMD, "Cannot get AP");
return JIM_ERR; 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); retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
LOG_ERROR("Unable to read %s", obj->name); command_print(CMD, "Unable to read %s", obj->name);
return JIM_ERR; return retval;
} }
switch (obj->pin_protocol) { switch (obj->pin_protocol) {
case TPIU_SPPR_PROTOCOL_SYNC: 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; value = 0;
} }
if (!value) { if (!value) {
struct jim_nvp *p; struct jim_nvp *p = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol);
jim_nvp_value2name(interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p); command_print(CMD, "%s does not support protocol %s", obj->name, p->name);
LOG_ERROR("%s does not support protocol %s", obj->name, p->name); return ERROR_FAIL;
return JIM_ERR;
} }
if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) { if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) {
retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value); retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value);
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
LOG_ERROR("Cannot read TPIU register SSPSR"); command_print(CMD, "Cannot read TPIU register SSPSR");
return JIM_ERR; return retval;
} }
if (!(value & BIT(obj->port_width - 1))) { if (!(value & BIT(obj->port_width - 1))) {
LOG_ERROR("TPIU does not support port-width of %d bits", obj->port_width); command_print(CMD, "TPIU does not support port-width of %d bits", obj->port_width);
return JIM_ERR; 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)); struct arm_tpiu_swo_priv_connection *priv = malloc(sizeof(*priv));
if (!priv) { if (!priv) {
LOG_ERROR("Out of memory"); LOG_ERROR("Out of memory");
return JIM_ERR; return ERROR_FAIL;
} }
priv->obj = obj; priv->obj = obj;
LOG_INFO("starting trace server for %s on %s", obj->name, &obj->out_filename[1]); 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], retval = add_service(&arm_tpiu_swo_service_driver, &obj->out_filename[1],
CONNECTION_LIMIT_UNLIMITED, priv); CONNECTION_LIMIT_UNLIMITED, priv);
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
LOG_ERROR("Can't configure trace TCP port %s", &obj->out_filename[1]); command_print(CMD, "Can't configure trace TCP port %s", &obj->out_filename[1]);
return JIM_ERR; return retval;
} }
} else if (strcmp(obj->out_filename, "-")) { } else if (strcmp(obj->out_filename, "-")) {
obj->file = fopen(obj->out_filename, "ab"); obj->file = fopen(obj->out_filename, "ab");
if (!obj->file) { if (!obj->file) {
LOG_ERROR("Can't open trace destination file \"%s\"", obj->out_filename); command_print(CMD, "Can't open trace destination file \"%s\"", obj->out_filename);
return JIM_ERR; return ERROR_FAIL;
} }
} }
retval = adapter_config_trace(true, obj->pin_protocol, obj->port_width, retval = adapter_config_trace(true, obj->pin_protocol, obj->port_width,
&swo_pin_freq, obj->traceclkin_freq, &prescaler); &swo_pin_freq, obj->traceclkin_freq, &prescaler);
if (retval != ERROR_OK) { 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); 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 (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)
if (!swo_pin_freq) { if (!swo_pin_freq) {
if (obj->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 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); arm_tpiu_swo_close_output(obj);
return JIM_ERR; return ERROR_FAIL;
} }
if (obj->swo_pin_freq != swo_pin_freq) 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 */ /* END_DEPRECATED_TPIU */
obj->enabled = true; obj->enabled = true;
return JIM_OK; return ERROR_OK;
error_exit: error_exit:
LOG_ERROR("Error!"); command_print(CMD, "Error!");
if (obj->en_capture) { if (obj->en_capture) {
obj->en_capture = false; obj->en_capture = false;
@ -811,27 +809,22 @@ error_exit:
target_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj); target_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj);
retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL); int retval1 = adapter_config_trace(false, 0, 0, NULL, 0, NULL);
if (retval != ERROR_OK) { if (retval1 != ERROR_OK)
LOG_ERROR("Failed to stop adapter's trace"); command_print(CMD, "Failed to stop adapter's trace");
return JIM_ERR;
}
} }
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 = CMD_DATA;
struct arm_tpiu_swo_object *obj = c->jim_handler_data;
if (argc != 1) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
}
if (!obj->enabled) if (!obj->enabled)
return JIM_OK; return ERROR_OK;
obj->enabled = false; obj->enabled = false;
arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_DISABLE); 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); int retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL);
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
LOG_ERROR("Failed to stop adapter's trace"); command_print(CMD, "Failed to stop adapter's trace");
return JIM_ERR; return retval;
} }
} }
arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE); arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE);
/* START_DEPRECATED_TPIU */ /* 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); target_handle_event(target, TARGET_EVENT_TRACE_CONFIG);
/* END_DEPRECATED_TPIU */ /* END_DEPRECATED_TPIU */
return JIM_OK; return ERROR_OK;
} }
static const struct command_registration arm_tpiu_swo_instance_command_handlers[] = { 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", .name = "enable",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_arm_tpiu_swo_enable, .handler = handle_arm_tpiu_swo_enable,
.usage = "", .usage = "",
.help = "Enables the TPIU/SWO output", .help = "Enables the TPIU/SWO output",
}, },
{ {
.name = "disable", .name = "disable",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_arm_tpiu_swo_disable, .handler = handle_arm_tpiu_swo_disable,
.usage = "", .usage = "",
.help = "Disables the TPIU/SWO output", .help = "Disables the TPIU/SWO output",
}, },
@ -989,39 +981,34 @@ err_exit:
return JIM_ERR; 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; struct arm_tpiu_swo_object *obj;
if (argc != 1) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
} list_for_each_entry(obj, &all_tpiu_swo, lh)
Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); command_print(CMD, "%s", obj->name);
list_for_each_entry(obj, &all_tpiu_swo, lh) {
Jim_ListAppendElement(interp, Jim_GetResult(interp), return ERROR_OK;
Jim_NewStringObj(interp, obj->name, -1));
}
return JIM_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; 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) { list_for_each_entry(obj, &all_tpiu_swo, lh) {
if (!obj->deferred_enable) if (!obj->deferred_enable)
continue; continue;
LOG_DEBUG("%s: running enable during init", obj->name); 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) if (retval2 != ERROR_OK)
retval = JIM_ERR; retval = retval2;
} }
return retval; return retval;
} }
@ -1193,14 +1180,14 @@ static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = {
{ {
.name = "names", .name = "names",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_arm_tpiu_swo_names, .handler = handle_arm_tpiu_swo_names,
.usage = "", .usage = "",
.help = "Lists all registered TPIU and SWO objects by name", .help = "Lists all registered TPIU and SWO objects by name",
}, },
{ {
.name = "init", .name = "init",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_arm_tpiu_swo_init, .handler = handle_arm_tpiu_swo_init,
.usage = "", .usage = "",
.help = "Initialize TPIU and SWO", .help = "Initialize TPIU and SWO",
}, },

View File

@ -989,132 +989,106 @@ COMMAND_HANDLER(handle_arm_disassemble_command)
#endif #endif
} }
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) COMMAND_HANDLER(handle_armv4_5_mcrmrc)
{ {
struct command_context *context; bool is_mcr = false;
struct target *target; unsigned int arg_cnt = 5;
struct arm *arm;
int retval;
context = current_command_context(interp); if (!strcmp(CMD_NAME, "mcr")) {
assert(context); is_mcr = true;
arg_cnt = 6;
}
target = get_current_target(context); if (arg_cnt != CMD_ARGC)
return ERROR_COMMAND_SYNTAX_ERROR;
struct target *target = get_current_target(CMD_CTX);
if (!target) { if (!target) {
LOG_ERROR("%s: no current target", __func__); command_print(CMD, "no current target");
return JIM_ERR; return ERROR_FAIL;
} }
if (!target_was_examined(target)) { if (!target_was_examined(target)) {
LOG_ERROR("%s: not yet examined", target_name(target)); command_print(CMD, "%s: not yet examined", target_name(target));
return JIM_ERR; return ERROR_TARGET_NOT_EXAMINED;
}
arm = target_to_arm(target);
if (!is_arm(arm)) {
LOG_ERROR("%s: not an ARM", target_name(target));
return JIM_ERR;
} }
if ((argc < 6) || (argc > 7)) { struct arm *arm = target_to_arm(target);
/* FIXME use the command name to verify # params... */ if (!is_arm(arm)) {
LOG_ERROR("%s: wrong number of arguments", __func__); command_print(CMD, "%s: not an ARM", target_name(target));
return JIM_ERR; return ERROR_FAIL;
} }
if (target->state != TARGET_HALTED)
return ERROR_TARGET_NOT_HALTED;
int cpnum; int cpnum;
uint32_t op1; uint32_t op1;
uint32_t op2; uint32_t op2;
uint32_t crn; uint32_t crn;
uint32_t crm; uint32_t crm;
uint32_t value; uint32_t value;
long l;
/* NOTE: parameter sequence matches ARM instruction set usage: /* NOTE: parameter sequence matches ARM instruction set usage:
* MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX
* MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX
* The "rX" is necessarily omitted; it uses Tcl mechanisms. * The "rX" is necessarily omitted; it uses Tcl mechanisms.
*/ */
retval = Jim_GetLong(interp, argv[1], &l); COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum);
if (retval != JIM_OK) if (cpnum & ~0xf) {
return retval; command_print(CMD, "coprocessor %d out of range", cpnum);
if (l & ~0xf) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"coprocessor", (int) l);
return JIM_ERR;
} }
cpnum = l;
retval = Jim_GetLong(interp, argv[2], &l); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1);
if (retval != JIM_OK) if (op1 & ~0x7) {
return retval; command_print(CMD, "op1 %d out of range", op1);
if (l & ~0x7) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"op1", (int) l);
return JIM_ERR;
} }
op1 = l;
retval = Jim_GetLong(interp, argv[3], &l); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn);
if (retval != JIM_OK) if (crn & ~0xf) {
return retval; command_print(CMD, "CRn %d out of range", crn);
if (l & ~0xf) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"CRn", (int) l);
return JIM_ERR;
} }
crn = l;
retval = Jim_GetLong(interp, argv[4], &l); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm);
if (retval != JIM_OK) if (crm & ~0xf) {
return retval; command_print(CMD, "CRm %d out of range", crm);
if (l & ~0xf) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"CRm", (int) l);
return JIM_ERR;
} }
crm = l;
retval = Jim_GetLong(interp, argv[5], &l); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2);
if (retval != JIM_OK) if (op2 & ~0x7) {
return retval; command_print(CMD, "op2 %d out of range", op2);
if (l & ~0x7) { return ERROR_COMMAND_ARGUMENT_INVALID;
LOG_ERROR("%s: %s %d out of range", __func__,
"op2", (int) l);
return JIM_ERR;
} }
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 * FIXME change the call syntax here ... simplest to just pass
* the MRC() or MCR() instruction to be executed. That will also * the MRC() or MCR() instruction to be executed. That will also
* let us support the "mrc2" and "mcr2" opcodes (toggling one bit) * let us support the "mrc2" and "mcr2" opcodes (toggling one bit)
* if that's ever needed. * if that's ever needed.
*/ */
if (argc == 7) { if (is_mcr) {
retval = Jim_GetLong(interp, argv[6], &l); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value);
if (retval != JIM_OK)
return retval;
value = l;
/* NOTE: parameters reordered! */ /* NOTE: parameters reordered! */
/* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ /* 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) if (retval != ERROR_OK)
return JIM_ERR; return retval;
} else { } else {
value = 0;
/* NOTE: parameters reordered! */ /* NOTE: parameters reordered! */
/* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ /* 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) 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[] = { static const struct command_registration arm_exec_command_handlers[] = {
@ -1128,14 +1102,14 @@ static const struct command_registration arm_exec_command_handlers[] = {
{ {
.name = "mcr", .name = "mcr",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = &jim_mcrmrc, .handler = handle_armv4_5_mcrmrc,
.help = "write coprocessor register", .help = "write coprocessor register",
.usage = "cpnum op1 CRn CRm op2 value", .usage = "cpnum op1 CRn CRm op2 value",
}, },
{ {
.name = "mrc", .name = "mrc",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = &jim_mcrmrc, .handler = handle_armv4_5_mcrmrc,
.help = "read coprocessor register", .help = "read coprocessor register",
.usage = "cpnum op1 CRn CRm op2", .usage = "cpnum op1 CRn CRm op2",
}, },

View File

@ -17,12 +17,10 @@
static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target) static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target)
{ {
const char *arch = target_get_gdb_arch(target); struct xtensa *xtensa = target->arch_info;
if (arch) { if (xtensa->common_magic == XTENSA_COMMON_MAGIC)
if (strncmp(arch, "xtensa", 6) == 0) return &target_to_esp_xtensa(target)->semihost;
return &target_to_esp_xtensa(target)->semihost; /* TODO: add riscv */
/* TODO: add riscv */
}
LOG_ERROR("Unknown target arch!"); LOG_ERROR("Unknown target arch!");
return NULL; return NULL;
} }

View File

@ -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_halt(struct target *target);
static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address, static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address,
uint32_t count, const uint8_t *buffer); 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) 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))) if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
return ERROR_TARGET_UNALIGNED_ACCESS; 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 */ /* since we don't know if buffer is aligned, we allocate new mem that is always aligned */
void *t = NULL; 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; fast_data_area = mips32->fast_data_area;
if (address <= fast_data_area->address + fast_data_area->size && if (address < (fast_data_area->address + fast_data_area->size) &&
fast_data_area->address <= address + count) { fast_data_area->address < (address + count)) {
LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area " LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area "
"(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").", "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").",
fast_data_area->address, address, address + count); 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; 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, static int mips_m4k_verify_pointer(struct command_invocation *cmd,
struct mips_m4k_common *mips_m4k) struct mips_m4k_common *mips_m4k)
{ {

View File

@ -4594,57 +4594,36 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc,
return e; return e;
} }
static int target_jim_read_memory(Jim_Interp *interp, int argc, COMMAND_HANDLER(handle_target_read_memory)
Jim_Obj * const *argv)
{ {
/* /*
* argv[1] = memory address * CMD_ARGV[0] = memory address
* argv[2] = desired element width in bits * CMD_ARGV[1] = desired element width in bits
* argv[3] = number of elements to read * CMD_ARGV[2] = number of elements to read
* argv[4] = optional "phys" * CMD_ARGV[3] = optional "phys"
*/ */
if (argc < 4 || argc > 5) { if (CMD_ARGC < 3 || CMD_ARGC > 4)
Jim_WrongNumArgs(interp, 1, argv, "address width count ['phys']"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
}
/* Arg 1: Memory address. */ /* Arg 1: Memory address. */
jim_wide wide_addr; target_addr_t addr;
int e; COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], addr);
e = Jim_GetWide(interp, argv[1], &wide_addr);
if (e != JIM_OK)
return e;
target_addr_t addr = (target_addr_t)wide_addr;
/* Arg 2: Bit width of one element. */ /* Arg 2: Bit width of one element. */
long l; unsigned int width_bits;
e = Jim_GetLong(interp, argv[2], &l); COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], width_bits);
if (e != JIM_OK)
return e;
const unsigned int width_bits = l;
/* Arg 3: Number of elements to read. */ /* Arg 3: Number of elements to read. */
e = Jim_GetLong(interp, argv[3], &l); unsigned int count;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], count);
if (e != JIM_OK)
return e;
size_t count = l;
/* Arg 4: Optional 'phys'. */ /* Arg 4: Optional 'phys'. */
bool is_phys = false; bool is_phys = false;
if (CMD_ARGC == 4) {
if (argc > 4) { if (strcmp(CMD_ARGV[3], "phys")) {
const char *phys = Jim_GetString(argv[4], NULL); command_print(CMD, "invalid argument '%s', must be 'phys'", CMD_ARGV[3]);
return ERROR_COMMAND_ARGUMENT_INVALID;
if (strcmp(phys, "phys")) {
Jim_SetResultFormatted(interp, "invalid argument '%s', must be 'phys'", phys);
return JIM_ERR;
} }
is_phys = true; is_phys = true;
@ -4657,37 +4636,33 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc,
case 64: case 64:
break; break;
default: default:
Jim_SetResultString(interp, "invalid width, must be 8, 16, 32 or 64", -1); command_print(CMD, "invalid width, must be 8, 16, 32 or 64");
return JIM_ERR; return ERROR_COMMAND_ARGUMENT_INVALID;
} }
const unsigned int width = width_bits / 8; const unsigned int width = width_bits / 8;
if ((addr + (count * width)) < addr) { if ((addr + (count * width)) < addr) {
Jim_SetResultString(interp, "read_memory: addr + count wraps to zero", -1); command_print(CMD, "read_memory: addr + count wraps to zero");
return JIM_ERR; return ERROR_COMMAND_ARGUMENT_INVALID;
} }
if (count > 65536) { if (count > 65536) {
Jim_SetResultString(interp, "read_memory: too large read request, exeeds 64K elements", -1); command_print(CMD, "read_memory: too large read request, exceeds 64K elements");
return JIM_ERR; return ERROR_COMMAND_ARGUMENT_INVALID;
} }
struct command_context *cmd_ctx = current_command_context(interp); struct target *target = get_current_target(CMD_CTX);
assert(cmd_ctx != NULL);
struct target *target = get_current_target(cmd_ctx);
const size_t buffersize = 4096; const size_t buffersize = 4096;
uint8_t *buffer = malloc(buffersize); uint8_t *buffer = malloc(buffersize);
if (!buffer) { if (!buffer) {
LOG_ERROR("Failed to allocate memory"); LOG_ERROR("Failed to allocate memory");
return JIM_ERR; return ERROR_FAIL;
} }
Jim_Obj *result_list = Jim_NewListObj(interp, NULL, 0); char *separator = "";
Jim_IncrRefCount(result_list);
while (count > 0) { while (count > 0) {
const unsigned int max_chunk_len = buffersize / width; const unsigned int max_chunk_len = buffersize / width;
const size_t chunk_len = MIN(count, max_chunk_len); const size_t chunk_len = MIN(count, max_chunk_len);
@ -4700,11 +4675,15 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc,
retval = target_read_memory(target, addr, width, chunk_len, buffer); retval = target_read_memory(target, addr, width, chunk_len, buffer);
if (retval != ERROR_OK) { 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); addr, width_bits, chunk_len);
Jim_SetResultString(interp, "read_memory: failed to read memory", -1); /*
e = JIM_ERR; * FIXME: we append the errmsg to the list of value already read.
break; * 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++) { for (size_t i = 0; i < chunk_len ; i++) {
@ -4725,11 +4704,8 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc,
break; break;
} }
char value_buf[19]; command_print_sameline(CMD, "%s0x%" PRIx64, separator, v);
snprintf(value_buf, sizeof(value_buf), "0x%" PRIx64, v); separator = " ";
Jim_ListAppendElement(interp, result_list,
Jim_NewStringObj(interp, value_buf, -1));
} }
count -= chunk_len; count -= chunk_len;
@ -4738,15 +4714,7 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc,
free(buffer); free(buffer);
if (e != JIM_OK) { return ERROR_OK;
Jim_DecrRefCount(interp, result_list);
return e;
}
Jim_SetResult(interp, result_list);
Jim_DecrRefCount(interp, result_list);
return JIM_OK;
} }
static int get_u64_array_element(Jim_Interp *interp, const char *varname, size_t idx, uint64_t *val) static int get_u64_array_element(Jim_Interp *interp, const char *varname, size_t idx, uint64_t *val)
@ -5750,40 +5718,38 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv
return JIM_OK; 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); if (CMD_ARGC != 0)
assert(cmd_ctx); return ERROR_COMMAND_SYNTAX_ERROR;
struct target *target = get_current_target(cmd_ctx);
Jim_SetResultBool(interp, target_was_examined(target)); struct target *target = get_current_target(CMD_CTX);
return JIM_OK;
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); if (CMD_ARGC != 0)
assert(cmd_ctx); return ERROR_COMMAND_SYNTAX_ERROR;
struct target *target = get_current_target(cmd_ctx);
Jim_SetResultBool(interp, target->defer_examine); struct target *target = get_current_target(CMD_CTX);
return JIM_OK;
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) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
}
struct command_context *cmd_ctx = current_command_context(interp);
assert(cmd_ctx);
struct target *target = get_current_target(cmd_ctx);
if (target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT) != ERROR_OK) struct target *target = get_current_target(CMD_CTX);
return JIM_ERR;
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) static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@ -5938,18 +5904,19 @@ COMMAND_HANDLER(handle_target_event_list)
command_print(CMD, "***END***"); command_print(CMD, "***END***");
return ERROR_OK; 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) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
} struct target *target = get_current_target(CMD_CTX);
struct command_context *cmd_ctx = current_command_context(interp);
assert(cmd_ctx); command_print(CMD, "%s", target_state_name(target));
struct target *target = get_current_target(cmd_ctx);
Jim_SetResultString(interp, target_state_name(target), -1); return ERROR_OK;
return JIM_OK;
} }
static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{ {
struct jim_getopt_info goi; struct jim_getopt_info goi;
@ -6076,7 +6043,7 @@ static const struct command_registration target_instance_command_handlers[] = {
{ {
.name = "read_memory", .name = "read_memory",
.mode = COMMAND_EXEC, .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", .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory",
.usage = "address width count ['phys']", .usage = "address width count ['phys']",
}, },
@ -6097,8 +6064,9 @@ static const struct command_registration target_instance_command_handlers[] = {
{ {
.name = "curstate", .name = "curstate",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_target_current_state, .handler = handle_target_current_state,
.help = "displays the current state of this target", .help = "displays the current state of this target",
.usage = "",
}, },
{ {
.name = "arp_examine", .name = "arp_examine",
@ -6110,20 +6078,23 @@ static const struct command_registration target_instance_command_handlers[] = {
{ {
.name = "was_examined", .name = "was_examined",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_target_was_examined, .handler = handle_target_was_examined,
.help = "used internally for reset processing", .help = "used internally for reset processing",
.usage = "",
}, },
{ {
.name = "examine_deferred", .name = "examine_deferred",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_target_examine_deferred, .handler = handle_target_examine_deferred,
.help = "used internally for reset processing", .help = "used internally for reset processing",
.usage = "",
}, },
{ {
.name = "arp_halt_gdb", .name = "arp_halt_gdb",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_target_halt_gdb, .handler = handle_target_halt_gdb,
.help = "used internally for reset processing to halt GDB", .help = "used internally for reset processing to halt GDB",
.usage = "",
}, },
{ {
.name = "arp_poll", .name = "arp_poll",
@ -6396,56 +6367,47 @@ static int target_create(struct jim_getopt_info *goi)
return JIM_OK; 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) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
}
struct command_context *cmd_ctx = current_command_context(interp);
assert(cmd_ctx);
struct target *target = get_current_target_or_null(cmd_ctx); struct target *target = get_current_target_or_null(CMD_CTX);
if (target) if (target)
Jim_SetResultString(interp, target_name(target), -1); command_print(CMD, "%s", target_name(target));
return JIM_OK;
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) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
} for (unsigned int x = 0; target_types[x]; x++)
Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); command_print(CMD, "%s", target_types[x]->name);
for (unsigned x = 0; target_types[x]; x++) {
Jim_ListAppendElement(interp, Jim_GetResult(interp), return ERROR_OK;
Jim_NewStringObj(interp, target_types[x]->name, -1));
}
return JIM_OK;
} }
static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) COMMAND_HANDLER(handle_target_names)
{ {
if (argc != 1) { if (CMD_ARGC != 0)
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
}
Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
struct target *target = all_targets; struct target *target = all_targets;
while (target) { while (target) {
Jim_ListAppendElement(interp, Jim_GetResult(interp), command_print(CMD, "%s", target_name(target));
Jim_NewStringObj(interp, target_name(target), -1));
target = target->next; target = target->next;
} }
return JIM_OK;
return ERROR_OK;
} }
static struct target_list * static struct target_list *
__attribute__((warn_unused_result)) __attribute__((warn_unused_result))
create_target_list_node(Jim_Obj *const name) { create_target_list_node(const char *targetname)
int len; {
const char *targetname = Jim_GetString(name, &len);
struct target *target = get_target(targetname); struct target *target = get_target(targetname);
LOG_DEBUG("%s ", targetname); LOG_DEBUG("%s ", targetname);
if (!target) if (!target)
@ -6461,7 +6423,8 @@ create_target_list_node(Jim_Obj *const name) {
return new; 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 *target = NULL;
struct target_list *curr; 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; struct rtos *curr_rtos = curr->target->rtos;
if (curr_rtos) { if (curr_rtos) {
if (target && target->rtos && target->rtos->type != curr_rtos->type) { if (target && target->rtos && target->rtos->type != curr_rtos->type) {
LOG_ERROR("Different rtos types in members of one smp target!"); command_print(cmd, "Different rtos types in members of one smp target!");
return JIM_ERR; return ERROR_FAIL;
} }
target = curr->target; target = curr->target;
} }
} }
*result = 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; static int smp_group = 1;
if (argc == 1) { if (CMD_ARGC == 0) {
LOG_DEBUG("Empty SMP target"); LOG_DEBUG("Empty SMP target");
return JIM_OK; return ERROR_OK;
} }
LOG_DEBUG("%d", argc); LOG_DEBUG("%d", CMD_ARGC);
/* argv[1] = target to associate in smp /* CMD_ARGC[0] = target to associate in smp
* argv[2] = target to associate in smp * CMD_ARGC[1] = target to associate in smp
* argv[3] ... * CMD_ARGC[2] ...
*/ */
struct list_head *lh = malloc(sizeof(*lh)); struct list_head *lh = malloc(sizeof(*lh));
if (!lh) { if (!lh) {
LOG_ERROR("Out of memory"); LOG_ERROR("Out of memory");
return JIM_ERR; return ERROR_FAIL;
} }
INIT_LIST_HEAD(lh); INIT_LIST_HEAD(lh);
for (int i = 1; i < argc; i++) { for (unsigned int i = 0; i < CMD_ARGC; i++) {
struct target_list *new = create_target_list_node(argv[i]); struct target_list *new = create_target_list_node(CMD_ARGV[i]);
if (new) if (new)
list_add_tail(&new->lh, lh); 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++; smp_group++;
struct target *rtos_target; struct target *rtos_target;
int retval = get_target_with_common_rtos_type(lh, &rtos_target); int retval = get_target_with_common_rtos_type(CMD, lh, &rtos_target);
if (retval == JIM_OK && rtos_target) if (retval == ERROR_OK && rtos_target)
retval = rtos_smp_init(rtos_target); retval = rtos_smp_init(rtos_target);
return retval; return retval;
} }
static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{ {
struct jim_getopt_info goi; struct jim_getopt_info goi;
@ -6553,26 +6515,29 @@ static const struct command_registration target_subcommand_handlers[] = {
{ {
.name = "current", .name = "current",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_target_current, .handler = handle_target_current,
.help = "Returns the currently selected target", .help = "Returns the currently selected target",
.usage = "",
}, },
{ {
.name = "types", .name = "types",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_target_types, .handler = handle_target_types,
.help = "Returns the available target types as " .help = "Returns the available target types as "
"a list of strings", "a list of strings",
.usage = "",
}, },
{ {
.name = "names", .name = "names",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_target_names, .handler = handle_target_names,
.help = "Returns the names of all targets as a list of strings", .help = "Returns the names of all targets as a list of strings",
.usage = "",
}, },
{ {
.name = "smp", .name = "smp",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_target_smp, .handler = handle_target_smp,
.usage = "targetname1 targetname2 ...", .usage = "targetname1 targetname2 ...",
.help = "gather several target in a smp list" .help = "gather several target in a smp list"
}, },
@ -7205,7 +7170,7 @@ static const struct command_registration target_exec_command_handlers[] = {
{ {
.name = "read_memory", .name = "read_memory",
.mode = COMMAND_EXEC, .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", .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory",
.usage = "address width count ['phys']", .usage = "address width count ['phys']",
}, },

View File

@ -252,64 +252,62 @@ COMMAND_HANDLER(handle_transport_list)
* set supported by the debug adapter being used. Return value * set supported by the debug adapter being used. Return value
* is scriptable (allowing "if swd then..." etc). * 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; if (CMD_ARGC > 1)
switch (argc) { return ERROR_COMMAND_SYNTAX_ERROR;
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 <transport>'.", 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;
}
}
/* Is this transport supported by our debug adapter? if (CMD_ARGC == 0) {
* Example, "JTAG-only" means SWD is not supported. /* autoselect if necessary, then return/display current config */
* if (!session) {
* NOTE: requires adapter to have been set up, with
* transports declared via C.
*/
if (!allowed_transports) { if (!allowed_transports) {
LOG_ERROR("Debug adapter doesn't support any transports?"); command_print(CMD, "Debug adapter does not support any transports? Check config file order.");
return JIM_ERR; return ERROR_FAIL;
} }
LOG_INFO("auto-selecting first available session transport \"%s\". "
for (unsigned i = 0; allowed_transports[i]; i++) { "To override use 'transport select <transport>'.", allowed_transports[0]);
int retval = transport_select(CMD_CTX, allowed_transports[0]);
if (strcmp(allowed_transports[i], argv[1]->bytes) == 0) { if (retval != ERROR_OK)
if (transport_select(global_cmd_ctx, argv[1]->bytes) == ERROR_OK) { return retval;
Jim_SetResultString(interp, session->name, -1); }
return JIM_OK; command_print(CMD, "%s", session->name);
} return ERROR_OK;
return JIM_ERR;
}
}
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;
} }
/* 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;
}
/* 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;
}
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[] = { static const struct command_registration transport_commands[] = {
@ -333,7 +331,7 @@ static const struct command_registration transport_commands[] = {
}, },
{ {
.name = "select", .name = "select",
.jim_handler = jim_transport_select, .handler = handle_transport_select,
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.help = "Select this session's transport", .help = "Select this session's transport",
.usage = "[transport_name]", .usage = "[transport_name]",

View File

@ -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]

View File

@ -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]

View File

@ -33,19 +33,21 @@ jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \
-expected-id 0x03752093 \ -expected-id 0x03752093 \
-expected-id 0x03751093 \ -expected-id 0x03751093 \
-expected-id 0x03671093 \ -expected-id 0x03671093 \
-expected-id 0x036B3093 \
-expected-id 0x036B7093 \
-expected-id 0x036BB093 \
-expected-id 0x036BF093 \
-expected-id 0x03667093 \ -expected-id 0x03667093 \
-expected-id 0x03682093 \ -expected-id 0x03682093 \
-expected-id 0x03687093 \ -expected-id 0x03687093 \
-expected-id 0x03692093 \ -expected-id 0x03692093 \
-expected-id 0x03691093 \ -expected-id 0x03691093 \
-expected-id 0x03696093 \ -expected-id 0x03696093
-expected-id 0x036D5093 \
-expected-id 0x036D9093 \ #jtag newtap $_CHIPNAME tap -irlen 24 -ignore-version \
-expected-id 0x036DB093 # -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 pld device virtex2 $_CHIPNAME.tap 1

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,18 +1,34 @@
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
#
# Xilinx Zynq-7000 All Programmable SoC # Xilinx Zynq-7000 All Programmable SoC
# #
# http://www.xilinx.com/products/silicon-devices/soc/zynq-7000/index.htm # 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 _CHIPNAME zynq
set _TARGETNAME $_CHIPNAME.cpu set _TARGETNAME $_CHIPNAME.cpu
jtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \ jtag newtap zynq_pl bs -irlen 6 -ignore-version -ircapture 0x1 -irmask 0x03 \
-expected-id 0x23727093 \ -expected-id 0x03723093 \
-expected-id 0x13722093 \ -expected-id 0x03722093 \
-expected-id 0x0373c093 \
-expected-id 0x03728093 \
-expected-id 0x0373B093 \
-expected-id 0x03732093 \
-expected-id 0x03727093 \ -expected-id 0x03727093 \
-expected-id 0x0372C093 \
-expected-id 0x03731093 \
-expected-id 0x03736093 -expected-id 0x03736093
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477 jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477