Merge pull request #935 from riscv/from_upstream
Merge down up to 0384fe5
from upstream.
This commit is contained in:
commit
3b0561d081
|
@ -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 }}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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",
|
||||||
},
|
},
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 = "",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 = ""
|
||||||
|
|
|
@ -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;
|
||||||
|
|
131
src/svf/svf.c
131
src/svf/svf.c
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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",
|
||||||
},
|
},
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
},
|
},
|
||||||
|
|
|
@ -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",
|
||||||
},
|
},
|
||||||
|
|
|
@ -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",
|
||||||
},
|
},
|
||||||
|
|
|
@ -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",
|
||||||
},
|
},
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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']",
|
||||||
},
|
},
|
||||||
|
|
|
@ -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]",
|
||||||
|
|
|
@ -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]
|
|
@ -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]
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue