Compare commits

...

12 Commits

Author SHA1 Message Date
Antonio Borneo
744955e5b4 LICENSES: add dual/CC-BY-4.0
The license CC-BY-4.0 is not compatible with GPLv2, but files can
be dual licensed with a GPLv2 compatible license 'OR' CC-BY-4.0.

This is the case for some file auto-generated by riscv project.

Change-Id: I4313d85a569a5e6423392129a730d1e22ef17c51
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8894
Reviewed-by: Bernhard Rosenkraenzer <bero@baylibre.com>
Tested-by: jenkins
2025-05-09 12:13:29 +00:00
Evgeniy Naydanov
1b2a2b8185 testing/tcl_commands: test target create, cget, configure
Introduce basic testing of error-handling in target configuration
related commands.

The tests can be run via `make check` when JTAG `dummy` adapter is
enabled.

Change-Id: Id0f382046dd70007d8e696d82d2396a7ccab7a33
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8644
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
2025-05-09 12:12:56 +00:00
Evgeniy Naydanov
f42540cc90 target: improve error reporting for -event option
`target create` calls can get quite long and an indication what is the
option that caused the error can be helpful.

Also, there can be multiple `-event` options for different events,
therefore indicating which one is it is also helpful.

Change-Id: I5ea61437ca9705e790ed8343183883a3fdfebc80
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8861
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Tested-by: jenkins
2025-05-09 12:12:32 +00:00
Evgeniy Naydanov
8c09cc2c17 target: improve error messaging in target create
There are a couple of issues with the usage string for `target create`,
namely:
* `-chain-position` is allowed to be not the first option.
* `-chain-position` should be ommited alltogether on ARM targets when
  DAP is specified.

Before the patch:
```
> openocd -c 'target create name testee'
...
  target create name type '-chain-position' name [options ...]
```

After the patch:
```
> openocd -c 'target create name testee'
...
-chain-position ?name? required when creating target
> openocd -c 'target create'
...
  target create name type [options ...]
```

Change-Id: Ia21a99ce6a4086e2e0676f5ef4685da3514a4f69
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8860
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Tested-by: jenkins
2025-05-09 12:12:04 +00:00
Daniel Goehring
d6c54b9494 target: cget command fix for result output
Function target_configure() when processing a "cget" command needs
to print the result to the console. Currently the result is only printed
when an error occurs. To fix this, move the command print statement from
the error handling section to the common code section.

The code was tested by executing a "$target_name cget -dap" command
and reviewing the result.

Change-Id: Iff1999de8c8e9a837055ba95714137aa03e68d4b
Signed-off-by: Daniel Goehring <dgoehrin@os.amperecomputing.com>
Fixes: 61890e3dc3 ("target: rewrite function target_configure() as COMMAND_HELPER")
Reviewed-on: https://review.openocd.org/c/openocd/+/8870
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
2025-05-09 12:10:49 +00:00
Antonio Borneo
618e447278 tcl: board: convert transport select dapdirect_swd to swd
Two new boards were added after the commit ad53fe659b ("tcl:
convert transport select to jtag and swd")

Align them too.

Change-Id: I53e36a3a1a7730822521f0239922682c7b2fcef6
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8869
Tested-by: jenkins
2025-05-09 12:10:27 +00:00
Antonio Borneo
00f5b7ece6 transport: fix incorrect statement
Commit 236208a5ff ("transport: use a bitmask for the transport")
has an incorrect C statement in place of a return.
The code is working thanks to the previous condition never true.

The issue has been detected by clang scan-build in OpenOCD ACI
since the missing return can make the following statement
dereferencing a NULL pointer.

Fix it!

Change-Id: I3bbe04d99ad9b1288f55ba3c45e2e487aef9ae40
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Fixes: 236208a5ff ("transport: use a bitmask for the transport")
Reviewed-on: https://review.openocd.org/c/openocd/+/8868
Tested-by: jenkins
2025-05-09 12:10:05 +00:00
Antonio Borneo
06c827757b target: armv7a: use proper type for struct armv7a_cache_common::outer_cache
The field 'outer_cache' is always initialized and used as a
pointer to 'struct armv7a_l2x_cache'.
There is no reason for using type 'void *' for it.

Change the type of 'outer_cache'.
Drop the useless cast while reading 'outer_cache'.

Change-Id: Iaea9d02e247da26e230f887c85fbf8e9d7be34d5
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8858
Tested-by: jenkins
2025-05-09 12:09:34 +00:00
Antonio Borneo
d71ed4f3bc target: armv7a: drop command 'cache_config l2x'
The command was already tagged as deprecated in 2015 with commit
0df5577282 ("armv7a: remove l1 flush all data handler") but has
never been removed.
An equivalent command 'cache l2x conf' was introduced at the same
time in commit cd440bd32a ("add armv7a_cache handlers").

Drop it and deprecate it.
Replace the old command in the Tcl script.

Change-Id: Ie24eccc99a78786903704d10ee1d9f6c924529b5
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8857
Tested-by: jenkins
2025-05-09 12:09:22 +00:00
Chien Wong
3954896d6e rtos/FreeRTOS: fix next pointer member offset in FreeRTOS lists
Currently, we are using offset of xListEnd.pxPrevious in List_t for
list_next_offset and offset of pxPrevious in ListItem_t for
list_elem_next_offset. This is confusing. Fix this.
As the related lists are doubly linked lists, only iteration order is
changed without breaking functionality.
Also document those offsets.

Change-Id: I8beacc235ee781ab4e3b415fccad7b72ec55b098
Signed-off-by: Chien Wong <m@xv97.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8833
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Tested-by: jenkins
2025-05-09 12:08:39 +00:00
Antonio Borneo
3a879c7dcb rtos: rework rtos_types[] and rtos_try_next()
Drop the NULL sentinel at the end of the array and use ARRAY_SIZE()
to bound the loops.
Adapt rtos_try_next() to use ARRAY_SIZE().

While there:
- change to bool the return type of rtos_try_next();
- move rtos_try_next() to avoid the forward declaration.

Change-Id: I1bee11db943b670789e62f1bebe2509bbef451a0
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8855
Tested-by: jenkins
2025-05-09 12:07:47 +00:00
Antonio Borneo
b3b790e4e0 rtos: rework rtos_create()
To simplify the caller of rtos_create(), convert the code from
jimtcl oriented to OpenOCD commands.

While there, fix inconsistencies in almost every rtos create()
method and reset rtos_auto_detect to better cooperate on run-time
rtos configuration.

Change-Id: I59c443aaed77a48174facdfc86db75d6b28c8480
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8830
Tested-by: jenkins
2025-05-09 12:06:54 +00:00
32 changed files with 743 additions and 208 deletions

409
LICENSES/dual/CC-BY-4.0 Normal file
View File

@@ -0,0 +1,409 @@
Valid-License-Identifier: CC-BY-4.0
SPDX-URL: https://spdx.org/licenses/CC-BY-4.0
Usage-Guide:
Do NOT use on OpenOCD code. This license is not GPL2 compatible. It may only
be used for dual-licensed files where the other license is GPL2 compatible.
If you end up using this it MUST be used together with a GPL2 compatible
license using "OR".
To use the Creative Commons Attribution 4.0 International license put
the following SPDX tag/value pair into a comment according to the
placement guidelines in the licensing rules documentation:
SPDX-License-Identifier: CC-BY-4.0
License-Text:
Creative Commons Attribution 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution 4.0 International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution 4.0 International Public License ("Public License"). To the
extent this Public License may be interpreted as a contract, You are
granted the Licensed Rights in consideration of Your acceptance of
these terms and conditions, and the Licensor grants You such rights in
consideration of benefits the Licensor receives from making the
Licensed Material available under these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
d. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
e. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
f. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
g. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
h. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
4. If You Share Adapted Material You produce, the Adapter's
License You apply must not prevent recipients of the Adapted
Material from complying with this Public License.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the "Licensor." The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.

View File

@@ -187,7 +187,21 @@ OpenOCD, can be broken down into:
License-Text: License-Text:
Full license text Full license text
2. Exceptions: 2. Dual Licensing Only:
These licenses should only be used to dual license code with another
license in addition to a preferred license. These licenses are available
from the directory::
LICENSES/dual/
in the OpenOCD source tree.
The files in this directory contain the full license text and
`Metatags`_. The file names are identical to the SPDX license
identifier which shall be used for the license in source files.
3. Exceptions:
Some licenses can be amended with exceptions which grant certain rights Some licenses can be amended with exceptions which grant certain rights
which the original license does not. These exceptions are available which the original license does not. These exceptions are available
@@ -244,7 +258,7 @@ OpenOCD, can be broken down into:
License-Text: License-Text:
Full license text Full license text
3. Stand-alone licenses: 4. Stand-alone licenses:
These licenses should only be used for stand-alone applications that are These licenses should only be used for stand-alone applications that are
distributed with OpenOCD but are not included in the OpenOCD binary. distributed with OpenOCD but are not included in the OpenOCD binary.

View File

@@ -10,7 +10,7 @@ AUTOMAKE_OPTIONS = gnu 1.6
AM_DISTCHECK_CONFIGURE_FLAGS = --disable-install-jim AM_DISTCHECK_CONFIGURE_FLAGS = --disable-install-jim
# do not run Jim Tcl tests (esp. during distcheck) # do not run Jim Tcl tests (esp. during distcheck)
check-recursive: SUBDIRS := check-recursive: SUBDIRS := $(SUBDIRS:jimtcl=)
nobase_dist_pkgdata_DATA = \ nobase_dist_pkgdata_DATA = \
contrib/libdcc/dcc_stdio.c \ contrib/libdcc/dcc_stdio.c \
@@ -36,6 +36,9 @@ EXTRA_DIST += jimtcl/configure.gnu
DISTCLEANFILES += jimtcl/jsmn/jsmn.o DISTCLEANFILES += jimtcl/jsmn/jsmn.o
endif endif
SUBDIRS += testing
DIST_SUBDIRS += testing
# common flags used in openocd build # common flags used in openocd build
AM_CFLAGS = $(GCC_WARNINGS) AM_CFLAGS = $(GCC_WARNINGS)
AM_LDFLAGS = AM_LDFLAGS =
@@ -67,6 +70,7 @@ EXTRA_DIST += \
$(EXTRA_DIST_NEWS) \ $(EXTRA_DIST_NEWS) \
Doxyfile.in \ Doxyfile.in \
LICENSES/license-rules.txt \ LICENSES/license-rules.txt \
LICENSES/dual/CC-BY-4.0 \
LICENSES/exceptions/eCos-exception-2.0 \ LICENSES/exceptions/eCos-exception-2.0 \
LICENSES/preferred/BSD-1-Clause \ LICENSES/preferred/BSD-1-Clause \
LICENSES/preferred/BSD-2-Clause \ LICENSES/preferred/BSD-2-Clause \

View File

@@ -835,7 +835,9 @@ AS_IF([test "x$gcc_warnings" = "xyes"], [
AC_SUBST(EXTRA_DIST_NEWS, ["$(echo $srcdir/NEWS-*)"]) AC_SUBST(EXTRA_DIST_NEWS, ["$(echo $srcdir/NEWS-*)"])
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile \
testing/Makefile \
testing/tcl_commands/Makefile
]) ])
AC_OUTPUT AC_OUTPUT

View File

@@ -10710,10 +10710,6 @@ Display/set the current core displayed in GDB
Selects whether interrupts will be processed when single stepping Selects whether interrupts will be processed when single stepping
@end deffn @end deffn
@deffn {Command} {cache_config l2x} [base way]
configure l2x cache
@end deffn
@deffn {Command} {cortex_a mmu dump} [@option{0}|@option{1}|@option{addr} address [@option{num_entries}]] @deffn {Command} {cortex_a mmu dump} [@option{0}|@option{1}|@option{addr} address [@option{num_entries}]]
Dump the MMU translation table from TTB0 or TTB1 register, or from physical Dump the MMU translation table from TTB0 or TTB1 register, or from physical
memory location @var{address}. When dumping the table from @var{address}, print at most memory location @var{address}. When dumping the table from @var{address}, print at most

View File

@@ -515,10 +515,10 @@ static int chibios_create(struct target *target)
for (unsigned int i = 0; i < ARRAY_SIZE(chibios_params_list); i++) for (unsigned int i = 0; i < ARRAY_SIZE(chibios_params_list); i++)
if (strcmp(chibios_params_list[i].target_name, target_type_name(target)) == 0) { if (strcmp(chibios_params_list[i].target_name, target_type_name(target)) == 0) {
target->rtos->rtos_specific_params = (void *)&chibios_params_list[i]; target->rtos->rtos_specific_params = (void *)&chibios_params_list[i];
return 0; return ERROR_OK;
} }
LOG_WARNING("Could not find target \"%s\" in ChibiOS compatibility " LOG_WARNING("Could not find target \"%s\" in ChibiOS compatibility "
"list", target_type_name(target)); "list", target_type_name(target));
return -1; return ERROR_FAIL;
} }

View File

@@ -1213,12 +1213,12 @@ static int ecos_create(struct target *target)
target->rtos->gdb_thread_packet = ecos_packet_hook; target->rtos->gdb_thread_packet = ecos_packet_hook;
/* We do not currently use the target->rtos->gdb_target_for_threadid /* We do not currently use the target->rtos->gdb_target_for_threadid
* hook. */ * hook. */
return 0; return ERROR_OK;
} }
tnames++; tnames++;
} }
} }
LOG_ERROR("Could not find target in eCos compatibility list"); LOG_ERROR("Could not find target in eCos compatibility list");
return -1; return ERROR_FAIL;
} }

View File

@@ -115,11 +115,11 @@ static int embkernel_create(struct target *target)
if (i >= ARRAY_SIZE(embkernel_params_list)) { if (i >= ARRAY_SIZE(embkernel_params_list)) {
LOG_WARNING("Could not find target \"%s\" in embKernel compatibility " LOG_WARNING("Could not find target \"%s\" in embKernel compatibility "
"list", target_type_name(target)); "list", target_type_name(target));
return -1; return ERROR_FAIL;
} }
target->rtos->rtos_specific_params = (void *) &embkernel_params_list[i]; target->rtos->rtos_specific_params = (void *) &embkernel_params_list[i];
return 0; return ERROR_OK;
} }
static int embkernel_get_tasks_details(struct rtos *rtos, int64_t iterable, const struct embkernel_params *param, static int embkernel_get_tasks_details(struct rtos *rtos, int64_t iterable, const struct embkernel_params *param,

View File

@@ -30,12 +30,12 @@ struct freertos_params {
const char *target_name; const char *target_name;
const unsigned char thread_count_width; const unsigned char thread_count_width;
const unsigned char pointer_width; const unsigned char pointer_width;
const unsigned char list_next_offset; const unsigned char list_next_offset; /* offsetof(List_t, xListEnd.pxNext) */
const unsigned char list_width; const unsigned char list_width; /* sizeof(List_t) */
const unsigned char list_elem_next_offset; const unsigned char list_elem_next_offset; /* offsetof(ListItem_t, pxNext) */
const unsigned char list_elem_content_offset; const unsigned char list_elem_content_offset; /* offsetof(ListItem_t, pvOwner) */
const unsigned char thread_stack_offset; const unsigned char thread_stack_offset; /* offsetof(TCB_t, pxTopOfStack) */
const unsigned char thread_name_offset; const unsigned char thread_name_offset; /* offsetof(TCB_t, pcTaskName) */
const struct rtos_register_stacking *stacking_info_cm3; const struct rtos_register_stacking *stacking_info_cm3;
const struct rtos_register_stacking *stacking_info_cm4f; const struct rtos_register_stacking *stacking_info_cm4f;
const struct rtos_register_stacking *stacking_info_cm4f_fpu; const struct rtos_register_stacking *stacking_info_cm4f_fpu;
@@ -46,9 +46,9 @@ static const struct freertos_params freertos_params_list[] = {
"cortex_m", /* target_name */ "cortex_m", /* target_name */
4, /* thread_count_width; */ 4, /* thread_count_width; */
4, /* pointer_width; */ 4, /* pointer_width; */
16, /* list_next_offset; */ 12, /* list_next_offset; */
20, /* list_width; */ 20, /* list_width; */
8, /* list_elem_next_offset; */ 4, /* list_elem_next_offset; */
12, /* list_elem_content_offset */ 12, /* list_elem_content_offset */
0, /* thread_stack_offset; */ 0, /* thread_stack_offset; */
52, /* thread_name_offset; */ 52, /* thread_name_offset; */
@@ -60,9 +60,9 @@ static const struct freertos_params freertos_params_list[] = {
"hla_target", /* target_name */ "hla_target", /* target_name */
4, /* thread_count_width; */ 4, /* thread_count_width; */
4, /* pointer_width; */ 4, /* pointer_width; */
16, /* list_next_offset; */ 12, /* list_next_offset; */
20, /* list_width; */ 20, /* list_width; */
8, /* list_elem_next_offset; */ 4, /* list_elem_next_offset; */
12, /* list_elem_content_offset */ 12, /* list_elem_content_offset */
0, /* thread_stack_offset; */ 0, /* thread_stack_offset; */
52, /* thread_name_offset; */ 52, /* thread_name_offset; */
@@ -534,9 +534,9 @@ static int freertos_create(struct target *target)
for (unsigned int i = 0; i < ARRAY_SIZE(freertos_params_list); i++) for (unsigned int i = 0; i < ARRAY_SIZE(freertos_params_list); i++)
if (strcmp(freertos_params_list[i].target_name, target_type_name(target)) == 0) { if (strcmp(freertos_params_list[i].target_name, target_type_name(target)) == 0) {
target->rtos->rtos_specific_params = (void *)&freertos_params_list[i]; target->rtos->rtos_specific_params = (void *)&freertos_params_list[i];
return 0; return ERROR_OK;
} }
LOG_ERROR("Could not find target in FreeRTOS compatibility list"); LOG_ERROR("Could not find target in FreeRTOS compatibility list");
return -1; return ERROR_FAIL;
} }

View File

@@ -412,7 +412,7 @@ static int hwthread_create(struct target *target)
target->rtos->thread_details = NULL; target->rtos->thread_details = NULL;
target->rtos->gdb_target_for_threadid = hwthread_target_for_threadid; target->rtos->gdb_target_for_threadid = hwthread_target_for_threadid;
target->rtos->gdb_thread_packet = hwthread_thread_packet; target->rtos->gdb_thread_packet = hwthread_thread_packet;
return 0; return ERROR_OK;
} }
static int hwthread_read_buffer(struct rtos *rtos, target_addr_t address, static int hwthread_read_buffer(struct rtos *rtos, target_addr_t address,

View File

@@ -1424,7 +1424,7 @@ static int linux_os_create(struct target *target)
/* initialize a default virt 2 phys translation */ /* initialize a default virt 2 phys translation */
os_linux->phys_mask = ~0xc0000000; os_linux->phys_mask = ~0xc0000000;
os_linux->phys_base = 0x0; os_linux->phys_base = 0x0;
return JIM_OK; return ERROR_OK;
} }
static char *linux_ps_command(struct target *target) static char *linux_ps_command(struct target *target)

View File

@@ -251,11 +251,11 @@ static int mqx_create(
if (strcmp(mqx_params_list[i].target_name, target_type_name(target)) == 0) { if (strcmp(mqx_params_list[i].target_name, target_type_name(target)) == 0) {
target->rtos->rtos_specific_params = (void *)&mqx_params_list[i]; target->rtos->rtos_specific_params = (void *)&mqx_params_list[i];
/* LOG_DEBUG("MQX RTOS - valid architecture: %s", target_type_name(target)); */ /* LOG_DEBUG("MQX RTOS - valid architecture: %s", target_type_name(target)); */
return 0; return ERROR_OK;
} }
} }
LOG_ERROR("MQX RTOS - could not find target \"%s\" in MQX compatibility list", target_type_name(target)); LOG_ERROR("MQX RTOS - could not find target \"%s\" in MQX compatibility list", target_type_name(target));
return -1; return ERROR_FAIL;
} }
/* /*

View File

@@ -129,13 +129,13 @@ static int nuttx_create(struct target *target)
if (i >= ARRAY_SIZE(nuttx_params_list)) { if (i >= ARRAY_SIZE(nuttx_params_list)) {
LOG_ERROR("Could not find \"%s\" target in NuttX compatibility list", target_type_name(target)); LOG_ERROR("Could not find \"%s\" target in NuttX compatibility list", target_type_name(target));
return JIM_ERR; return ERROR_FAIL;
} }
/* We found a target in our list, copy its reference. */ /* We found a target in our list, copy its reference. */
target->rtos->rtos_specific_params = (void *)param; target->rtos->rtos_specific_params = (void *)param;
return JIM_OK; return ERROR_OK;
} }
static int nuttx_smp_init(struct target *target) static int nuttx_smp_init(struct target *target)

View File

@@ -364,12 +364,12 @@ static int rtkernel_create(struct target *target)
for (size_t i = 0; i < ARRAY_SIZE(rtkernel_params_list); i++) { for (size_t i = 0; i < ARRAY_SIZE(rtkernel_params_list); i++) {
if (strcmp(rtkernel_params_list[i].target_name, target_type_name(target)) == 0) { if (strcmp(rtkernel_params_list[i].target_name, target_type_name(target)) == 0) {
target->rtos->rtos_specific_params = (void *)&rtkernel_params_list[i]; target->rtos->rtos_specific_params = (void *)&rtkernel_params_list[i];
return 0; return ERROR_OK;
} }
} }
LOG_ERROR("Could not find target in rt-kernel compatibility list"); LOG_ERROR("Could not find target in rt-kernel compatibility list");
return -1; return ERROR_FAIL;
} }
const struct rtos_type rtkernel_rtos = { const struct rtos_type rtkernel_rtos = {

View File

@@ -13,6 +13,7 @@
#include "target/target.h" #include "target/target.h"
#include "helper/log.h" #include "helper/log.h"
#include "helper/binarybuffer.h" #include "helper/binarybuffer.h"
#include "helper/types.h"
#include "server/gdb_server.h" #include "server/gdb_server.h"
static const struct rtos_type *rtos_types[] = { static const struct rtos_type *rtos_types[] = {
@@ -31,11 +32,8 @@ static const struct rtos_type *rtos_types[] = {
&rtkernel_rtos, &rtkernel_rtos,
/* keep this as last, as it always matches with rtos auto */ /* keep this as last, as it always matches with rtos auto */
&hwthread_rtos, &hwthread_rtos,
NULL
}; };
static int rtos_try_next(struct target *target);
int rtos_smp_init(struct target *target) int rtos_smp_init(struct target *target)
{ {
if (target->rtos->type->smp_init) if (target->rtos->type->smp_init)
@@ -57,7 +55,7 @@ static int os_alloc(struct target *target, const struct rtos_type *ostype)
struct rtos *os = target->rtos = calloc(1, sizeof(struct rtos)); struct rtos *os = target->rtos = calloc(1, sizeof(struct rtos));
if (!os) if (!os)
return JIM_ERR; return ERROR_FAIL;
os->type = ostype; os->type = ostype;
os->current_threadid = -1; os->current_threadid = -1;
@@ -69,7 +67,7 @@ static int os_alloc(struct target *target, const struct rtos_type *ostype)
os->gdb_thread_packet = rtos_thread_packet; os->gdb_thread_packet = rtos_thread_packet;
os->gdb_target_for_threadid = rtos_target_for_threadid; os->gdb_target_for_threadid = rtos_target_for_threadid;
return JIM_OK; return ERROR_OK;
} }
static void os_free(struct target *target) static void os_free(struct target *target)
@@ -86,38 +84,26 @@ static void os_free(struct target *target)
static int os_alloc_create(struct target *target, const struct rtos_type *ostype) static int os_alloc_create(struct target *target, const struct rtos_type *ostype)
{ {
int ret = os_alloc(target, ostype); int ret = os_alloc(target, ostype);
if (ret != ERROR_OK)
return ret;
if (ret == JIM_OK) { ret = target->rtos->type->create(target);
ret = target->rtos->type->create(target); if (ret != ERROR_OK)
if (ret != JIM_OK) os_free(target);
os_free(target);
}
return ret; return ret;
} }
int rtos_create(struct jim_getopt_info *goi, struct target *target) int rtos_create(struct command_invocation *cmd, struct target *target,
const char *rtos_name)
{ {
int x;
const char *cp;
Jim_Obj *res;
int e;
if (!goi->is_configure && goi->argc != 0) {
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS");
return JIM_ERR;
}
os_free(target); os_free(target);
target->rtos_auto_detect = false;
e = jim_getopt_string(goi, &cp, NULL); if (strcmp(rtos_name, "none") == 0)
if (e != JIM_OK) return ERROR_OK;
return e;
if (strcmp(cp, "none") == 0) if (strcmp(rtos_name, "auto") == 0) {
return JIM_OK;
if (strcmp(cp, "auto") == 0) {
/* Auto detect tries to look up all symbols for each RTOS, /* Auto detect tries to look up all symbols for each RTOS,
* and runs the RTOS driver's _detect() function when GDB * and runs the RTOS driver's _detect() function when GDB
* finds all symbols for any RTOS. See rtos_qsymbol(). */ * finds all symbols for any RTOS. See rtos_qsymbol(). */
@@ -128,17 +114,29 @@ int rtos_create(struct jim_getopt_info *goi, struct target *target)
return os_alloc(target, rtos_types[0]); return os_alloc(target, rtos_types[0]);
} }
for (x = 0; rtos_types[x]; x++) for (size_t x = 0; x < ARRAY_SIZE(rtos_types); x++)
if (strcmp(cp, rtos_types[x]->name) == 0) if (strcmp(rtos_name, rtos_types[x]->name) == 0)
return os_alloc_create(target, rtos_types[x]); return os_alloc_create(target, rtos_types[x]);
Jim_SetResultFormatted(goi->interp, "Unknown RTOS type %s, try one of: ", cp); char *all = NULL;
res = Jim_GetResult(goi->interp); for (size_t x = 0; x < ARRAY_SIZE(rtos_types); x++) {
for (x = 0; rtos_types[x]; x++) char *prev = all;
Jim_AppendStrings(goi->interp, res, rtos_types[x]->name, ", ", NULL); if (all)
Jim_AppendStrings(goi->interp, res, ", auto or none", NULL); all = alloc_printf("%s, %s", all, rtos_types[x]->name);
else
all = alloc_printf("%s", rtos_types[x]->name);
free(prev);
if (!all) {
LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
}
return JIM_ERR; command_print(cmd, "Unknown RTOS type %s, try one of: %s, auto or none",
rtos_name, all);
free(all);
return ERROR_COMMAND_ARGUMENT_INVALID;
} }
void rtos_destroy(struct target *target) void rtos_destroy(struct target *target)
@@ -155,6 +153,29 @@ int gdb_thread_packet(struct connection *connection, char const *packet, int pac
return target->rtos->gdb_thread_packet(connection, packet, packet_size); return target->rtos->gdb_thread_packet(connection, packet, packet_size);
} }
static bool rtos_try_next(struct target *target)
{
struct rtos *os = target->rtos;
if (!os)
return false;
for (size_t x = 0; x < ARRAY_SIZE(rtos_types) - 1; x++) {
if (os->type == rtos_types[x]) {
// Use next RTOS in the list
os->type = rtos_types[x + 1];
free(os->symbols);
os->symbols = NULL;
return true;
}
}
// No next RTOS to try
return false;
}
static struct symbol_table_elem *find_symbol(const struct rtos *os, const char *symbol) static struct symbol_table_elem *find_symbol(const struct rtos *os, const char *symbol)
{ {
struct symbol_table_elem *s; struct symbol_table_elem *s;
@@ -667,28 +688,6 @@ int rtos_generic_stack_read(struct target *target,
return ERROR_OK; return ERROR_OK;
} }
static int rtos_try_next(struct target *target)
{
struct rtos *os = target->rtos;
const struct rtos_type **type = rtos_types;
if (!os)
return 0;
while (*type && os->type != *type)
type++;
if (!*type || !*(++type))
return 0;
os->type = *type;
free(os->symbols);
os->symbols = NULL;
return 1;
}
int rtos_update_threads(struct target *target) int rtos_update_threads(struct target *target)
{ {
if ((target->rtos) && (target->rtos->type)) if ((target->rtos) && (target->rtos->type))

View File

@@ -10,7 +10,6 @@
#include "server/server.h" #include "server/server.h"
#include "target/target.h" #include "target/target.h"
#include <helper/jim-nvp.h>
typedef int64_t threadid_t; typedef int64_t threadid_t;
typedef int64_t symbol_address_t; typedef int64_t symbol_address_t;
@@ -113,7 +112,8 @@ struct rtos_register_stacking {
#define GDB_THREAD_PACKET_NOT_CONSUMED (-40) #define GDB_THREAD_PACKET_NOT_CONSUMED (-40)
int rtos_create(struct jim_getopt_info *goi, struct target *target); int rtos_create(struct command_invocation *cmd, struct target *target,
const char *rtos_name);
void rtos_destroy(struct target *target); void rtos_destroy(struct target *target);
int rtos_set_reg(struct connection *connection, int reg_num, int rtos_set_reg(struct connection *connection, int reg_num,
uint8_t *reg_value); uint8_t *reg_value);

View File

@@ -611,9 +611,9 @@ static int threadx_create(struct target *target)
target->rtos->rtos_specific_params = (void *)&threadx_params_list[i]; target->rtos->rtos_specific_params = (void *)&threadx_params_list[i];
target->rtos->current_thread = 0; target->rtos->current_thread = 0;
target->rtos->thread_details = NULL; target->rtos->thread_details = NULL;
return 0; return ERROR_OK;
} }
LOG_ERROR("Could not find target in ThreadX compatibility list"); LOG_ERROR("Could not find target in ThreadX compatibility list");
return -1; return ERROR_FAIL;
} }

View File

@@ -179,59 +179,10 @@ done:
return retval; return retval;
} }
/* FIXME: remove it */
static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t way)
{
struct armv7a_l2x_cache *l2x_cache;
struct target_list *head;
struct armv7a_common *armv7a = target_to_armv7a(target);
l2x_cache = calloc(1, sizeof(struct armv7a_l2x_cache));
l2x_cache->base = base;
l2x_cache->way = way;
/*LOG_INFO("cache l2 initialized base %x way %d",
l2x_cache->base,l2x_cache->way);*/
if (armv7a->armv7a_mmu.armv7a_cache.outer_cache)
LOG_INFO("outer cache already initialized\n");
armv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache;
/* initialize all target in this cluster (smp target)
* l2 cache must be configured after smp declaration */
foreach_smp_target(head, target->smp_targets) {
struct target *curr = head->target;
if (curr != target) {
armv7a = target_to_armv7a(curr);
if (armv7a->armv7a_mmu.armv7a_cache.outer_cache)
LOG_ERROR("smp target : outer cache already initialized\n");
armv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache;
}
}
return JIM_OK;
}
/* FIXME: remove it */
COMMAND_HANDLER(handle_cache_l2x)
{
struct target *target = get_current_target(CMD_CTX);
uint32_t base, way;
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
/* command_print(CMD, "%s %s", CMD_ARGV[0], CMD_ARGV[1]); */
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], base);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], way);
/* AP address is in bits 31:24 of DP_SELECT */
armv7a_l2x_cache_init(target, base, way);
return ERROR_OK;
}
int armv7a_handle_cache_info_command(struct command_invocation *cmd, int armv7a_handle_cache_info_command(struct command_invocation *cmd,
struct armv7a_cache_common *armv7a_cache) struct armv7a_cache_common *armv7a_cache)
{ {
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) struct armv7a_l2x_cache *l2x_cache = armv7a_cache->outer_cache;
(armv7a_cache->outer_cache);
int cl; int cl;
@@ -561,33 +512,7 @@ int armv7a_arch_state(struct target *target)
return ERROR_OK; return ERROR_OK;
} }
static const struct command_registration l2_cache_commands[] = {
{
.name = "l2x",
.handler = handle_cache_l2x,
.mode = COMMAND_EXEC,
.help = "configure l2x cache",
.usage = "[base_addr] [number_of_way]",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration l2x_cache_command_handlers[] = {
{
.name = "cache_config",
.mode = COMMAND_EXEC,
.help = "cache configuration for a target",
.usage = "",
.chain = l2_cache_commands,
},
COMMAND_REGISTRATION_DONE
};
const struct command_registration armv7a_command_handlers[] = { const struct command_registration armv7a_command_handlers[] = {
{
.chain = l2x_cache_command_handlers,
},
{ {
.chain = arm7a_cache_command_handlers, .chain = arm7a_cache_command_handlers,
}, },

View File

@@ -66,7 +66,7 @@ struct armv7a_cache_common {
int i_cache_enabled; int i_cache_enabled;
int d_u_cache_enabled; int d_u_cache_enabled;
/* outer unified cache if some */ /* outer unified cache if some */
void *outer_cache; struct armv7a_l2x_cache *outer_cache;
int (*flush_all_data_cache)(struct target *target); int (*flush_all_data_cache)(struct target *target);
}; };

View File

@@ -21,8 +21,8 @@
static int arm7a_l2x_sanity_check(struct target *target) static int arm7a_l2x_sanity_check(struct target *target)
{ {
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) struct armv7a_l2x_cache *l2x_cache =
(armv7a->armv7a_mmu.armv7a_cache.outer_cache); armv7a->armv7a_mmu.armv7a_cache.outer_cache;
if (target->state != TARGET_HALTED) { if (target->state != TARGET_HALTED) {
LOG_ERROR("%s: target not halted", __func__); LOG_ERROR("%s: target not halted", __func__);
@@ -42,8 +42,8 @@ static int arm7a_l2x_sanity_check(struct target *target)
int arm7a_l2x_flush_all_data(struct target *target) int arm7a_l2x_flush_all_data(struct target *target)
{ {
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) struct armv7a_l2x_cache *l2x_cache =
(armv7a->armv7a_mmu.armv7a_cache.outer_cache); armv7a->armv7a_mmu.armv7a_cache.outer_cache;
uint32_t l2_way_val; uint32_t l2_way_val;
int retval; int retval;
@@ -62,8 +62,8 @@ int armv7a_l2x_cache_flush_virt(struct target *target, target_addr_t virt,
uint32_t size) uint32_t size)
{ {
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) struct armv7a_l2x_cache *l2x_cache =
(armv7a->armv7a_mmu.armv7a_cache.outer_cache); armv7a->armv7a_mmu.armv7a_cache.outer_cache;
/* FIXME: different controllers have different linelen? */ /* FIXME: different controllers have different linelen? */
uint32_t i, linelen = 32; uint32_t i, linelen = 32;
int retval; int retval;
@@ -97,8 +97,8 @@ static int armv7a_l2x_cache_inval_virt(struct target *target, target_addr_t virt
uint32_t size) uint32_t size)
{ {
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) struct armv7a_l2x_cache *l2x_cache =
(armv7a->armv7a_mmu.armv7a_cache.outer_cache); armv7a->armv7a_mmu.armv7a_cache.outer_cache;
/* FIXME: different controllers have different linelen */ /* FIXME: different controllers have different linelen */
uint32_t i, linelen = 32; uint32_t i, linelen = 32;
int retval; int retval;
@@ -132,8 +132,8 @@ static int armv7a_l2x_cache_clean_virt(struct target *target, target_addr_t virt
unsigned int size) unsigned int size)
{ {
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) struct armv7a_l2x_cache *l2x_cache =
(armv7a->armv7a_mmu.armv7a_cache.outer_cache); armv7a->armv7a_mmu.armv7a_cache.outer_cache;
/* FIXME: different controllers have different linelen */ /* FIXME: different controllers have different linelen */
uint32_t i, linelen = 32; uint32_t i, linelen = 32;
int retval; int retval;
@@ -166,8 +166,7 @@ done:
static int arm7a_handle_l2x_cache_info_command(struct command_invocation *cmd, static int arm7a_handle_l2x_cache_info_command(struct command_invocation *cmd,
struct armv7a_cache_common *armv7a_cache) struct armv7a_cache_common *armv7a_cache)
{ {
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) struct armv7a_l2x_cache *l2x_cache = armv7a_cache->outer_cache;
(armv7a_cache->outer_cache);
if (armv7a_cache->info == -1) { if (armv7a_cache->info == -1) {
command_print(cmd, "cache not yet identified"); command_print(cmd, "cache not yet identified");

View File

@@ -316,3 +316,9 @@ proc _post_init_target_cortex_a_cache_auto {} {
} }
} }
lappend post_init_commands _post_init_target_cortex_a_cache_auto lappend post_init_commands _post_init_target_cortex_a_cache_auto
lappend _telnet_autocomplete_skip "cache_config l2x"
proc "cache_config l2x" {args} {
echo "DEPRECATED! use 'cache l2x conf' not 'cache_config l2x'"
eval cache_config l2x $args
}

View File

@@ -4889,16 +4889,18 @@ static COMMAND_HELPER(target_configure, struct target *target, unsigned int inde
goi.is_configure = is_configure; goi.is_configure = is_configure;
int e = (*target->type->target_jim_configure)(target, &goi); int e = (*target->type->target_jim_configure)(target, &goi);
index = CMD_ARGC - goi.argc; index = CMD_ARGC - goi.argc;
int reslen;
const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen);
if (reslen > 0)
command_print(CMD, "%s", result);
if (e == JIM_OK) { if (e == JIM_OK) {
/* more? */ /* more? */
continue; continue;
} }
if (e == JIM_ERR) { if (e == JIM_ERR) {
/* An error */ /* An error */
int reslen;
const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen);
if (reslen > 0)
command_print(CMD, "%s", result);
return ERROR_FAIL; return ERROR_FAIL;
} }
/* otherwise we 'continue' below */ /* otherwise we 'continue' below */
@@ -4924,7 +4926,8 @@ static COMMAND_HELPER(target_configure, struct target *target, unsigned int inde
case TCFG_EVENT: case TCFG_EVENT:
if (index == CMD_ARGC) { if (index == CMD_ARGC) {
command_print(CMD, "missing event-name"); command_print(CMD, "expecting %s event-name event-body",
CMD_ARGV[index - 1]);
return ERROR_COMMAND_ARGUMENT_INVALID; return ERROR_COMMAND_ARGUMENT_INVALID;
} }
@@ -4937,7 +4940,8 @@ static COMMAND_HELPER(target_configure, struct target *target, unsigned int inde
if (is_configure) { if (is_configure) {
if (index == CMD_ARGC) { if (index == CMD_ARGC) {
command_print(CMD, "missing event-body"); command_print(CMD, "expecting %s %s event-body",
CMD_ARGV[index - 2], CMD_ARGV[index - 1]);
return ERROR_COMMAND_ARGUMENT_INVALID; return ERROR_COMMAND_ARGUMENT_INVALID;
} }
} }
@@ -5176,17 +5180,10 @@ static COMMAND_HELPER(target_configure, struct target *target, unsigned int inde
command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]);
return ERROR_COMMAND_ARGUMENT_INVALID; return ERROR_COMMAND_ARGUMENT_INVALID;
} }
struct jim_getopt_info goi; retval = rtos_create(CMD, target, CMD_ARGV[index]);
jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC - index, CMD_JIMTCL_ARGV + index); if (retval != ERROR_OK)
return retval;
index++; index++;
goi.is_configure = true;
int resval = rtos_create(&goi, target);
int reslen;
const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen);
if (reslen > 0)
command_print(CMD, "%s", result);
if (resval != JIM_OK)
return ERROR_FAIL;
} else { } else {
if (index != CMD_ARGC) if (index != CMD_ARGC)
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
@@ -5711,7 +5708,7 @@ COMMAND_HANDLER(handle_target_create)
int retval = ERROR_OK; int retval = ERROR_OK;
int x; int x;
if (CMD_ARGC < 4) if (CMD_ARGC < 2)
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
/* check if the target name clashes with an existing command name */ /* check if the target name clashes with an existing command name */
@@ -6056,7 +6053,7 @@ static const struct command_registration target_subcommand_handlers[] = {
.name = "create", .name = "create",
.mode = COMMAND_CONFIG, .mode = COMMAND_CONFIG,
.handler = handle_target_create, .handler = handle_target_create,
.usage = "name type '-chain-position' name [options ...]", .usage = "name type [options ...]",
.help = "Creates and selects a new target", .help = "Creates and selects a new target",
}, },
{ {

View File

@@ -258,7 +258,7 @@ struct transport *get_current_transport(void)
const char *get_current_transport_name(void) const char *get_current_transport_name(void)
{ {
if (!session || !is_transport_id_valid(session->id)) if (!session || !is_transport_id_valid(session->id))
NULL; return NULL;
return transport_full_name(session->id); return transport_full_name(session->id);
} }

View File

@@ -5,7 +5,7 @@
source [find interface/stlink.cfg] source [find interface/stlink.cfg]
transport select dapdirect_swd transport select swd
source [find target/stm32u0x.cfg] source [find target/stm32u0x.cfg]

View File

@@ -2,7 +2,7 @@
source [find interface/stlink.cfg] source [find interface/stlink.cfg]
transport select dapdirect_swd transport select swd
source [find target/stm32c0x.cfg] source [find target/stm32c0x.cfg]

View File

@@ -133,7 +133,7 @@ proc enable_apetap {} {
set status [$_TARGETNAME_1 curstate] set status [$_TARGETNAME_1 curstate]
if {[string equal "unknown" $status]} { if {[string equal "unknown" $status]} {
$_TARGETNAME_1 arp_examine $_TARGETNAME_1 arp_examine
cache_config l2x 0xa0412000 8 cache l2x conf 0xa0412000 8
} }
set status [$_TARGETNAME_2 curstate] set status [$_TARGETNAME_2 curstate]

4
testing/Makefile.am Normal file
View File

@@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-or-later
SUBDIRS = tcl_commands
DIST_SUBDIRS = tcl_commands

View File

@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-or-later
TESTS =
if DUMMY
TESTS += \
test-target-create-command.cfg \
test-target-configure-cget-command.cfg
endif
EXTRA_DIST = utils.tcl $(TESTS)
TEST_EXTENSIONS = .cfg
CFG_LOG_COMPILER = $(top_builddir)/src/openocd
AM_CFG_LOG_FLAGS = -f $(abs_srcdir)/utils.tcl -f

View File

@@ -0,0 +1,31 @@
# SPDX-License-Identifier: GPL-2.0-or-later
namespace import testing_helpers::*
namespace import configure_testing::*
adapter driver dummy
jtag newtap tap cpu -irlen 5
{*}[target_create_first_args] {*}[simple_configure_options]
set target_name [lindex [target names] 0]
check_matches testee {$target_name cget -type}
foreach {opt arg} [simple_configure_options] {
check_syntax_err {$target_name cget $opt extra_arg}
check_matches [dict get [simple_configure_options] $opt] \
{$target_name cget $opt}
}
check_error_matches .*-event.* {$target_name cget -event}
$target_name cget -event examine-start
check_syntax_err {$target_name cget -event examine-start extra_arg}
check_syntax_err {$target_name configure}
foreach {opt arg} [simple_configure_options] {
$target_name configure $opt [$target_name cget $opt]
}
shutdown

View File

@@ -0,0 +1,54 @@
# SPDX-License-Identifier: GPL-2.0-or-later
namespace import testing_helpers::*
namespace import configure_testing::*
adapter driver dummy
jtag newtap tap cpu -irlen 5
check_syntax_err {target create}
check_syntax_err {target create}
check_syntax_err {target create test.target}
check_error_matches -chain-position {target create test.target testee}
{*}[target_create_first_args] {*}[simple_configure_options]
foreach {opt arg} [simple_configure_options] {
check_error_matches ".*${opt}.*" {{*}[target_create_first_args] $opt}
}
foreach {opt1 arg1} [simple_configure_options] {
foreach {opt2 arg2} [simple_configure_options] {
check_error_matches ".*${opt2}.*" \
{{*}[target_create_first_args] $opt1 $arg1 $opt2}
check_error_matches {} \
{{*}[target_create_first_args] $opt1 $opt2 $arg2}
}
}
check_error_matches ".*-type.*" \
{{*}[target_create_first_args] -type}
check_error_matches ".*-type.*" \
{{*}[target_create_first_args] {*}[simple_configure_options] -type}
check_error_matches {.*-event [^ ]+ .*} \
{{*}[target_create_first_args] -event}
check_error_matches {.*not-an-event.*} \
{{*}[target_create_first_args] -event not-an-event}
check_error_matches {.*-event examine-start [^ ]+.*} \
{{*}[target_create_first_args] -event examine-start}
{*}[target_create_first_args] {*}[simple_configure_options] \
-event examine-start body
{*}[target_create_first_args] {*}[simple_configure_options] \
-event examine-start body \
-event examine-end another-body \
-event examine-start new-body
{*}[target_create_first_args] -event examine-start body {*}[simple_configure_options]
{*}[target_create_first_args] {*}[simple_configure_options] -defer-examine
shutdown

View File

@@ -0,0 +1,80 @@
# SPDX-License-Identifier: GPL-2.0-or-later
namespace eval testing_helpers {
proc test_failure message {
echo $message
shutdown error
}
proc check_for_error {expctd_code msg_ptrn script} {
set code [catch {uplevel $script} msg]
set expanded_script [uplevel subst \"$script\"]
if {!$code} {
test_failure \
"'$expanded_script' finished successfully. \
Was expecting an error."
}
if {$expctd_code ne "" && $code != $expctd_code} {
test_failure \
"'$expanded_script' returned unexpected error code $code. \
Was expecting $expctd_code. Error message: '$msg'"
}
if {$msg_ptrn ne "" && ![regexp -- $msg_ptrn $msg]} {
test_failure \
"'$expanded_script' returned unexpected error message '$msg'. \
Was expecting '$msg_ptrn'. Error code: $code"
}
}
proc check_error_matches {pattern script} {
tailcall check_for_error {} $pattern $script
}
proc check_syntax_err script {
tailcall check_for_error -601 {} $script
}
proc check_matches {pattern script} {
set result [uplevel $script]
if {[regexp $pattern $result]} {return}
test_failure \
"'$script' produced unexpected result '$result'. \
Was expecting '$pattern'."
}
namespace export check_error_matches check_syntax_err check_matches
}
namespace eval configure_testing {
variable target_idx 0
proc unique_tgt_name {} {
variable target_idx
incr target_idx
return test_target$target_idx
}
proc target_create_first_args {} {
return "target create [unique_tgt_name] testee"
}
proc simple_configure_options {} {
return {
-work-area-virt 0
-work-area-phys 0
-work-area-size 1
-work-area-backup 0
-endian little
-coreid 1
-chain-position tap.cpu
-dbgbase 0
-rtos hwthread
-gdb-port 0
-gdb-max-connections 1
}
}
namespace export target_create_first_args simple_configure_options
}

View File

@@ -50,7 +50,7 @@ def read_spdxdata(repo):
# The subdirectories of LICENSES in the kernel source # The subdirectories of LICENSES in the kernel source
# Note: exceptions needs to be parsed as last directory. # Note: exceptions needs to be parsed as last directory.
# OpenOCD specific: Begin # OpenOCD specific: Begin
license_dirs = [ "preferred", "stand-alone", "exceptions" ] license_dirs = [ "preferred", "dual", "exceptions", "stand-alone" ]
# OpenOCD specific: End # OpenOCD specific: End
lictree = repo.head.commit.tree['LICENSES'] lictree = repo.head.commit.tree['LICENSES']