forked from auracaster/openocd
Compare commits
94 Commits
change-881
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b80f554fd9 | ||
|
|
3d83e9546e | ||
|
|
232cd0b0f1 | ||
|
|
a22e4331e7 | ||
|
|
faab1de8b1 | ||
|
|
944fb35b70 | ||
|
|
ea07cc74ce | ||
|
|
607a16f20c | ||
|
|
4894527eec | ||
|
|
4c072f0d0a | ||
|
|
0f6616ac00 | ||
|
|
48f57a72ce | ||
|
|
b8cfd06368 | ||
|
|
231aa88ee5 | ||
|
|
49e75c74d5 | ||
|
|
bd17a59fd1 | ||
|
|
0e41ac862d | ||
|
|
b215fe8621 | ||
|
|
92dc88978a | ||
|
|
4e23bf155f | ||
|
|
e4c49d8605 | ||
|
|
22e1e1b33e | ||
|
|
092282c7d2 | ||
|
|
c3b4bcc6e6 | ||
|
|
a5a9121ad6 | ||
|
|
687dd5c5df | ||
|
|
0c6fe74351 | ||
|
|
5b3db97c42 | ||
|
|
84f8814003 | ||
|
|
7052573187 | ||
|
|
129e9d3005 | ||
|
|
aaceff81f0 | ||
|
|
9e1db0e8c7 | ||
|
|
22bad00b9b | ||
|
|
0e4d6d202a | ||
|
|
c11a325ed8 | ||
|
|
a02550bafa | ||
|
|
b164b65b3b | ||
|
|
e135ffe205 | ||
|
|
86bdd88282 | ||
|
|
0163d9ddba | ||
|
|
e85f9b2954 | ||
|
|
a7d31c87e1 | ||
|
|
2374db956b | ||
|
|
9b21a31eb7 | ||
|
|
2b986178cf | ||
|
|
8ee7cb12cf | ||
|
|
3c1bd50217 | ||
|
|
5151c98455 | ||
|
|
078a6b1f9f | ||
|
|
6eaf951b20 | ||
|
|
1967f85548 | ||
|
|
0f67341e15 | ||
|
|
eaa04836dc | ||
|
|
718eb22bfc | ||
|
|
b4518ab78b | ||
|
|
db34f6f0a7 | ||
|
|
92b482af50 | ||
|
|
95bd9093b1 | ||
|
|
294538f0d4 | ||
|
|
62f49b7fe2 | ||
|
|
8bc12d98e7 | ||
|
|
91799d0579 | ||
|
|
7d6f3ede0e | ||
|
|
c348b9f2d7 | ||
|
|
3ba83c76a2 | ||
|
|
bcfa2bc6b5 | ||
|
|
5e7182368e | ||
|
|
00e4fb653d | ||
|
|
b10372f0d2 | ||
|
|
70d4ac0395 | ||
|
|
f275432b27 | ||
|
|
b9e4016161 | ||
|
|
b36de4f539 | ||
|
|
eea1bb4d30 | ||
|
|
c60bb56bb6 | ||
|
|
f36ab02a80 | ||
|
|
22a7bda336 | ||
|
|
f9ec0ed51f | ||
|
|
ab718d66ce | ||
|
|
46f7b185a1 | ||
|
|
8f22bf7712 | ||
|
|
60d11a881f | ||
|
|
ea9afa9e3e | ||
|
|
50fdce21a0 | ||
|
|
7d688bc500 | ||
|
|
df14f58662 | ||
|
|
b074fea079 | ||
|
|
dab933b3ae | ||
|
|
c36f59d9b4 | ||
|
|
89ded3d2f0 | ||
|
|
2389c28ea8 | ||
|
|
28eb4c37b9 | ||
|
|
587c783103 |
17
.editorconfig
Normal file
17
.editorconfig
Normal file
@@ -0,0 +1,17 @@
|
||||
# EditorConfig: https://editorconfig.org/
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# All (Defaults)
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
|
||||
[*.patch,*.diff]
|
||||
trim_trailing_whitespace = false
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
AUTOMAKE_OPTIONS = gnu 1.14
|
||||
AUTOMAKE_OPTIONS = foreign 1.14
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
@@ -63,8 +63,8 @@ EXTRA_DIST += \
|
||||
BUGS \
|
||||
HACKING \
|
||||
NEWTAPS \
|
||||
README.Windows \
|
||||
README.macOS \
|
||||
README.Windows.md \
|
||||
README.macOS.md \
|
||||
$(EXTRA_DIST_NEWS) \
|
||||
Doxyfile.in \
|
||||
LICENSES/license-rules.txt \
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
Building OpenOCD for Windows
|
||||
----------------------------
|
||||
# OpenOCD for Windows
|
||||
|
||||
This README contains instructions that are specific to Windows.
|
||||
|
||||
## Building
|
||||
|
||||
You can build OpenOCD for Windows natively with either MinGW-w64/MSYS
|
||||
or Cygwin (plain MinGW might work with --disable-werror but is not
|
||||
or Cygwin (plain MinGW might work with `--disable-werror` but is not
|
||||
recommended as it doesn't provide enough C99 compatibility).
|
||||
Alternatively, one can cross-compile it using MinGW-w64 on a *nix
|
||||
host. See README for the generic instructions.
|
||||
host. See [README](README.md) for the generic instructions.
|
||||
|
||||
Also, the MSYS2 project provides both ready-made binaries and an easy
|
||||
way to self-compile from their software repository out of the box.
|
||||
|
||||
USB adapters
|
||||
------------
|
||||
## USB adapters
|
||||
|
||||
For the adapters that use a HID-based protocol, e.g. CMSIS-DAP, you do
|
||||
not need to perform any additional configuration.
|
||||
@@ -19,9 +21,7 @@ not need to perform any additional configuration.
|
||||
For all the others you usually need to have WinUSB.sys (or
|
||||
libusbK.sys) driver installed. Some vendor software (e.g. for
|
||||
ST-LINKv2) does it on its own. For the other cases the easiest way to
|
||||
assign WinUSB to a device is to use the latest Zadig installer:
|
||||
|
||||
http://zadig.akeo.ie
|
||||
assign WinUSB to a device is to use the latest Zadig installer: <https://zadig.akeo.ie>
|
||||
|
||||
When using a composite USB device, it's often necessary to assign
|
||||
WinUSB.sys to the composite parent instead of the specific
|
||||
@@ -30,7 +30,7 @@ Zadig installer.
|
||||
|
||||
If you need to use the same adapter with other applications that may
|
||||
require another driver, a solution for Windows Vista and above is to
|
||||
activate the IgnoreHWSerNum registry setting for the USB device.
|
||||
activate the `IgnoreHWSerNum` registry setting for the USB device.
|
||||
|
||||
That setting forces Windows to associate the driver per port instead of
|
||||
per serial number, the same behaviour as when the device does not contain
|
||||
@@ -40,5 +40,5 @@ port depending on which application to use.
|
||||
|
||||
For more information, see:
|
||||
|
||||
https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-device-specific-registry-settings
|
||||
http://www.ftdichip.com/Support/Knowledgebase/index.html?ignorehardwareserialnumber.htm
|
||||
- <https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-device-specific-registry-settings>
|
||||
- <https://www.ftdichip.com/Support/Knowledgebase/index.html?ignorehardwareserialnumber.htm>
|
||||
54
README.macOS
54
README.macOS
@@ -1,54 +0,0 @@
|
||||
Building OpenOCD for macOS
|
||||
--------------------------
|
||||
|
||||
There are a few prerequisites you will need first:
|
||||
|
||||
- Xcode (install from the AppStore)
|
||||
- Command Line Tools (install from Xcode -> Preferences -> Downloads)
|
||||
- Gentoo Prefix (http://www.gentoo.org/proj/en/gentoo-alt/prefix/bootstrap.xml)
|
||||
or
|
||||
- Homebrew (http://mxcl.github.io/homebrew/)
|
||||
or
|
||||
- MacPorts (http://www.macports.org/install.php)
|
||||
|
||||
|
||||
If you're building manually you need Texinfo version 5.0 or later. The
|
||||
simplest way to get it is to use Homebrew (brew install texinfo) and
|
||||
then ``export PATH=/usr/local/opt/texinfo/bin:$PATH``.
|
||||
|
||||
|
||||
With Gentoo Prefix you can build the release version or the latest
|
||||
devel version (-9999) the usual way described in the Gentoo
|
||||
documentation. Alternatively, install the prerequisites and build
|
||||
manually from the sources.
|
||||
|
||||
|
||||
With Homebrew you can either run:
|
||||
brew install [--HEAD] openocd (where optional --HEAD asks brew to
|
||||
install the current git version)
|
||||
or
|
||||
brew install libtool automake libusb [hidapi] [libftdi]
|
||||
(to install the needed dependencies and then proceed with the
|
||||
manual building procedure)
|
||||
|
||||
|
||||
For building with MacPorts you need to run:
|
||||
sudo port install libtool automake autoconf pkgconfig \
|
||||
libusb [libftdi1]
|
||||
|
||||
You should also specify LDFLAGS and CPPFLAGS to allow configure to use
|
||||
MacPorts' libraries, so run configure like this:
|
||||
LDFLAGS=-L/opt/local/lib CPPFLAGS=-I/opt/local/include ./configure [options]
|
||||
|
||||
|
||||
See README for the generic building instructions.
|
||||
|
||||
If you're using a USB adapter and have a driver kext matched to it,
|
||||
you will need to unload it prior to running OpenOCD. E.g. with Apple
|
||||
driver (OS X 10.9 or later) for FTDI run:
|
||||
sudo kextunload -b com.apple.driver.AppleUSBFTDI
|
||||
for FTDI vendor driver use:
|
||||
sudo kextunload FTDIUSBSerialDriver.kext
|
||||
|
||||
To learn more on the topic please refer to the official libusb FAQ:
|
||||
https://github.com/libusb/libusb/wiki/FAQ
|
||||
72
README.macOS.md
Normal file
72
README.macOS.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# OpenOCD for macOS
|
||||
|
||||
This README contains instructions that are specific to macOS.
|
||||
|
||||
## Building
|
||||
|
||||
There are a few prerequisites you will need first:
|
||||
|
||||
- Xcode (install from the AppStore)
|
||||
- Command Line Tools (install from Xcode -> Preferences -> Downloads)
|
||||
- One of the following tools:
|
||||
- Gentoo Prefix (<https://wiki.gentoo.org/wiki/Project:Prefix/Bootstrap>)
|
||||
- Homebrew (<https://brew.sh/>)
|
||||
- MacPorts (<https://www.macports.org/install.php>)
|
||||
|
||||
If you're building manually you need Texinfo version 5.0 or later. The
|
||||
simplest way to get it is to use Homebrew (`brew install texinfo`) and
|
||||
then `export PATH=/usr/local/opt/texinfo/bin:$PATH`.
|
||||
|
||||
With Gentoo Prefix you can build the release version or the latest
|
||||
devel version (-9999) the usual way described in the Gentoo
|
||||
documentation. Alternatively, install the prerequisites and build
|
||||
manually from the sources.
|
||||
|
||||
With Homebrew you can either run:
|
||||
|
||||
```sh
|
||||
brew install [--HEAD] open-ocd
|
||||
```
|
||||
|
||||
Where ``--HEAD`` asks ``brew`` to install the current Git version instead of the
|
||||
lastest release.
|
||||
|
||||
You can also run:
|
||||
|
||||
```sh
|
||||
brew install libtool automake libusb [hidapi] [libftdi]
|
||||
```
|
||||
|
||||
to install the needed dependencies and then proceed with the manual building
|
||||
procedure.
|
||||
|
||||
For building with MacPorts you need to run:
|
||||
|
||||
```sh
|
||||
sudo port install libtool automake autoconf pkgconfig libusb [libftdi1]
|
||||
```
|
||||
|
||||
You should also specify LDFLAGS and CPPFLAGS to allow `configure` to use
|
||||
MacPorts' libraries, so run configure like this:
|
||||
|
||||
```sh
|
||||
LDFLAGS=-L/opt/local/lib CPPFLAGS=-I/opt/local/include ./configure [options]
|
||||
```
|
||||
|
||||
See [README](README.md) for the generic building instructions.
|
||||
|
||||
If you're using a USB adapter and have a driver kext matched to it,
|
||||
you will need to unload it prior to running OpenOCD. E.g. with Apple
|
||||
driver (OS X 10.9 or later) for FTDI run:
|
||||
|
||||
```sh
|
||||
sudo kextunload -b com.apple.driver.AppleUSBFTDI
|
||||
```
|
||||
|
||||
for FTDI vendor driver use:
|
||||
|
||||
```sh
|
||||
sudo kextunload FTDIUSBSerialDriver.kext
|
||||
```
|
||||
|
||||
To learn more on the topic please refer to the official libusb FAQ: <https://github.com/libusb/libusb/wiki/FAQ>
|
||||
@@ -1,4 +1,4 @@
|
||||
# Welcome to OpenOCD!
|
||||
# Welcome to OpenOCD
|
||||
|
||||
OpenOCD provides on-chip programming and debugging support with a
|
||||
layered architecture of JTAG interface and TAP support including:
|
||||
@@ -24,138 +24,76 @@ This README file contains an overview of the following topics:
|
||||
- the installation and build process,
|
||||
- packaging tips.
|
||||
|
||||
|
||||
# Quickstart for the impatient
|
||||
## Quickstart for the impatient
|
||||
|
||||
If you have a popular board then just start OpenOCD with its config,
|
||||
e.g.:
|
||||
|
||||
openocd -f board/stm32f4discovery.cfg
|
||||
```sh
|
||||
openocd -f board/stm32f4discovery.cfg
|
||||
```
|
||||
|
||||
If you are connecting a particular adapter with some specific target,
|
||||
you need to source both the jtag interface and the target configs,
|
||||
e.g.:
|
||||
|
||||
```
|
||||
```sh
|
||||
openocd -f interface/ftdi/jtagkey2.cfg -c "transport select jtag" \
|
||||
-f target/ti/calypso.cfg
|
||||
```
|
||||
|
||||
```
|
||||
```sh
|
||||
openocd -f interface/stlink.cfg -c "transport select swd" \
|
||||
-f target/stm32l0.cfg
|
||||
```
|
||||
|
||||
After OpenOCD startup, connect GDB with
|
||||
|
||||
(gdb) target extended-remote localhost:3333
|
||||
```gdb
|
||||
(gdb) target extended-remote localhost:3333
|
||||
```
|
||||
|
||||
## Installing OpenOCD
|
||||
|
||||
# OpenOCD Documentation
|
||||
The easiest way to install OpenOCD is through your operating system's package
|
||||
manager.
|
||||
|
||||
In addition to the in-tree documentation, the latest manuals may be
|
||||
viewed online at the following URLs:
|
||||
- Debian / Ubuntu
|
||||
|
||||
OpenOCD User's Guide:
|
||||
http://openocd.org/doc/html/index.html
|
||||
```sh
|
||||
sudo apt install openocd
|
||||
```
|
||||
|
||||
OpenOCD Developer's Manual:
|
||||
http://openocd.org/doc/doxygen/html/index.html
|
||||
- Fedora
|
||||
|
||||
These reflect the latest development versions, so the following section
|
||||
introduces how to build the complete documentation from the package.
|
||||
```sh
|
||||
sudo dnf install openocd
|
||||
```
|
||||
|
||||
For more information, refer to these documents or contact the developers
|
||||
by subscribing to the OpenOCD developer mailing list:
|
||||
- macOS (via Homebrew)
|
||||
|
||||
openocd-devel@lists.sourceforge.net
|
||||
```sh
|
||||
brew install open-ocd
|
||||
```
|
||||
|
||||
## Building the OpenOCD Documentation
|
||||
- Windows (via MSYS2)
|
||||
|
||||
By default the OpenOCD build process prepares documentation in the
|
||||
"Info format" and installs it the standard way, so that `info openocd`
|
||||
can access it.
|
||||
```sh
|
||||
pacman -S mingw-w64-x86_64-openocd
|
||||
```
|
||||
|
||||
Additionally, the OpenOCD User's Guide can be produced in the
|
||||
following different formats:
|
||||
These packages are often more stable than the bleeding-edge Git mainline, where
|
||||
active development happens.
|
||||
"Packagers" create binary releases of OpenOCD after the developers publish new
|
||||
source code releases.
|
||||
Older OpenOCD versions are not suitable for diagnosing issues in the current
|
||||
release.
|
||||
Users should stay in touch with their distribution maintainers or interface
|
||||
vendors to ensure that appropriate updates are provided regularly.
|
||||
|
||||
If `PDFVIEWER` is set, this creates and views the PDF User Guide.
|
||||
|
||||
make pdf && ${PDFVIEWER} doc/openocd.pdf
|
||||
|
||||
If `HTMLVIEWER` is set, this creates and views the HTML User Guide.
|
||||
|
||||
make html && ${HTMLVIEWER} doc/openocd.html/index.html
|
||||
|
||||
The OpenOCD Developer Manual contains information about the internal
|
||||
architecture and other details about the code:
|
||||
|
||||
Note: make sure doxygen is installed, type doxygen --version
|
||||
|
||||
make doxygen && ${HTMLVIEWER} doxygen/index.html
|
||||
|
||||
|
||||
# Supported hardware
|
||||
|
||||
## JTAG adapters
|
||||
|
||||
AM335x, ARM-JTAG-EW, ARM-USB-OCD, ARM-USB-TINY, AT91RM9200, axm0432, BCM2835,
|
||||
Bus Blaster, Buspirate, Cadence DPI, Cadence vdebug, Chameleon, CMSIS-DAP,
|
||||
Cortino, Cypress KitProg, DENX, Digilent JTAG-SMT2, DLC 5, DLP-USB1232H,
|
||||
embedded projects, Espressif USB JTAG Programmer,
|
||||
eStick, FlashLINK, FlossJTAG, Flyswatter, Flyswatter2,
|
||||
FTDI FT232R, Gateworks, Hoegl, ICDI, ICEBear, J-Link, JTAG VPI, JTAGkey,
|
||||
JTAGkey2, JTAG-lock-pick, KT-Link, Linux GPIOD, Lisa/L, LPC1768-Stick,
|
||||
Mellanox rshim, MiniModule, NGX, Nuvoton Nu-Link, Nu-Link2, NXHX, NXP IMX GPIO,
|
||||
OOCDLink, Opendous, OpenJTAG, Openmoko, OpenRD, OSBDM, Presto, Redbee,
|
||||
Remote Bitbang, RLink, SheevaPlug devkit, Stellaris evkits,
|
||||
ST-LINK (SWO tracing supported), STM32-PerformanceStick, STR9-comStick,
|
||||
sysfsgpio, Tigard, TI XDS110, TUMPA, Turtelizer, ULINK, USB-A9260, USB-Blaster,
|
||||
USB-JTAG, USBprog, VPACLink, VSLLink, Wiggler, XDS100v2, Xilinx XVC/PCIe,
|
||||
Xverve.
|
||||
|
||||
## Debug targets
|
||||
|
||||
ARM: AArch64, ARM11, ARM7, ARM9, Cortex-A/R (v7-A/R), Cortex-M (ARMv{6/7/8}-M),
|
||||
FA526, Feroceon/Dragonite, XScale.
|
||||
ARCv2, AVR32, DSP563xx, DSP5680xx, EnSilica eSi-RISC, EJTAG (MIPS32, MIPS64),
|
||||
ESP32, ESP32-S2, ESP32-S3, Intel Quark, LS102x-SAP, RISC-V, ST STM8,
|
||||
Xtensa.
|
||||
|
||||
## Flash drivers
|
||||
|
||||
ADUC702x, AT91SAM, AT91SAM9 (NAND), ATH79, ATmega128RFA1, Atmel SAM, AVR, CFI,
|
||||
DSP5680xx, EFM32, EM357, eSi-RISC, eSi-TSMC, EZR32HG, FM3, FM4, Freedom E SPI,
|
||||
GD32, i.MX31, Kinetis, LPC8xx/LPC1xxx/LPC2xxx/LPC541xx, LPC2900, LPC3180, LPC32xx,
|
||||
LPCSPIFI, Marvell QSPI, MAX32, Milandr, MXC, NIIET, nRF51, nRF52 , NuMicro,
|
||||
NUC910, Nuvoton NPCX, onsemi RSL10, Orion/Kirkwood, PIC32mx, PSoC4/5LP/6,
|
||||
Raspberry RP2040, Renesas RPC HF and SH QSPI,
|
||||
S3C24xx, S3C6400, SiM3x, SiFive Freedom E, Stellaris, ST BlueNRG, STM32,
|
||||
STM32 QUAD/OCTO-SPI for Flash/FRAM/EEPROM, STMSMI, STR7x, STR9x, SWM050,
|
||||
TI CC13xx, TI CC26xx, TI CC32xx, TI MSP432, Winner Micro w600, Xilinx XCF,
|
||||
XMC1xxx, XMC4xxx.
|
||||
|
||||
|
||||
# Installing OpenOCD
|
||||
|
||||
## A Note to OpenOCD Users
|
||||
|
||||
If you would rather be working "with" OpenOCD rather than "on" it, your
|
||||
operating system or JTAG interface supplier may provide binaries for
|
||||
you in a convenient-enough package.
|
||||
|
||||
Such packages may be more stable than git mainline, where
|
||||
bleeding-edge development takes place. These "Packagers" produce
|
||||
binary releases of OpenOCD after the developers produces new "release"
|
||||
versions of the source code. Previous versions of OpenOCD cannot be
|
||||
used to diagnose problems with the current release, so users are
|
||||
encouraged to keep in contact with their distribution package
|
||||
maintainers or interface vendors to ensure suitable upgrades appear
|
||||
regularly.
|
||||
|
||||
Users of these binary versions of OpenOCD must contact their Packager to
|
||||
ask for support or newer versions of the binaries; the OpenOCD
|
||||
developers do not support packages directly.
|
||||
If you use one of these binary packages, you must contact the Packager for
|
||||
support or for newer binary versions.
|
||||
The OpenOCD developers do not provide direct support for packaged binaries.
|
||||
|
||||
## A Note to OpenOCD Packagers
|
||||
|
||||
@@ -183,8 +121,92 @@ suggestions:
|
||||
particular hardware;
|
||||
- Use "ftdi" interface adapter driver for the FTDI-based devices.
|
||||
|
||||
## OpenOCD Documentation
|
||||
|
||||
# Building OpenOCD
|
||||
In addition to the in-tree documentation, the latest manuals may be
|
||||
viewed online at the following URLs:
|
||||
|
||||
- OpenOCD User's Guide: <http://openocd.org/doc/html/index.html>
|
||||
|
||||
- OpenOCD Developer's Manual: <http://openocd.org/doc/doxygen/html/index.html>
|
||||
|
||||
These reflect the latest development versions, so the following section
|
||||
introduces how to build the complete documentation from the package.
|
||||
|
||||
For more information, refer to these documents or contact the developers
|
||||
by subscribing to the OpenOCD developer mailing list: openocd-devel@lists.sourceforge.net
|
||||
|
||||
### Building the OpenOCD Documentation
|
||||
|
||||
By default the OpenOCD build process prepares documentation in the
|
||||
"Info format" and installs it the standard way, so that `info openocd`
|
||||
can access it.
|
||||
|
||||
Additionally, the OpenOCD User's Guide can be produced in the
|
||||
following different formats:
|
||||
|
||||
If `PDFVIEWER` is set, this creates and views the PDF User Guide.
|
||||
|
||||
```sh
|
||||
make pdf && ${PDFVIEWER} doc/openocd.pdf
|
||||
```
|
||||
|
||||
If `HTMLVIEWER` is set, this creates and views the HTML User Guide.
|
||||
|
||||
```sh
|
||||
make html && ${HTMLVIEWER} doc/openocd.html/index.html
|
||||
```
|
||||
|
||||
The OpenOCD Developer Manual contains information about the internal
|
||||
architecture and other details about the code:
|
||||
|
||||
Note: make sure doxygen is installed, type doxygen --version
|
||||
|
||||
```sh
|
||||
make doxygen && ${HTMLVIEWER} doxygen/index.html
|
||||
```
|
||||
|
||||
## Supported hardware
|
||||
|
||||
### JTAG adapters
|
||||
|
||||
AM335x, ARM-JTAG-EW, ARM-USB-OCD, ARM-USB-TINY, AT91RM9200, axm0432, BCM2835,
|
||||
Bus Blaster, Buspirate, Cadence DPI, Cadence vdebug, Chameleon, CMSIS-DAP,
|
||||
Cortino, Cypress KitProg, DENX, Digilent JTAG-SMT2, DLC 5, DLP-USB1232H,
|
||||
embedded projects, Espressif USB JTAG Programmer,
|
||||
eStick, FlashLINK, FlossJTAG, Flyswatter, Flyswatter2,
|
||||
FTDI FT232R, Gateworks, Hoegl, ICDI, ICEBear, J-Link, JTAG VPI, JTAGkey,
|
||||
JTAGkey2, JTAG-lock-pick, KT-Link, Linux GPIOD, Lisa/L, LPC1768-Stick,
|
||||
Mellanox rshim, MiniModule, NGX, Nuvoton Nu-Link, Nu-Link2, NXHX, NXP IMX GPIO,
|
||||
OOCDLink, Opendous, OpenJTAG, Openmoko, OpenRD, OSBDM, Presto, Redbee,
|
||||
Remote Bitbang, RLink, SheevaPlug devkit, Stellaris evkits,
|
||||
ST-LINK (SWO tracing supported), STM32-PerformanceStick, STR9-comStick,
|
||||
sysfsgpio, Tigard, TI XDS110, TUMPA, Turtelizer, ULINK, USB-A9260, USB-Blaster,
|
||||
USB-JTAG, USBprog, VPACLink, VSLLink, Wiggler, XDS100v2, Xilinx XVC/PCIe,
|
||||
Xverve.
|
||||
|
||||
### Debug targets
|
||||
|
||||
ARM: AArch64, ARM11, ARM7, ARM9, Cortex-A/R (v7-A/R), Cortex-M (ARMv{6/7/8}-M),
|
||||
FA526, Feroceon/Dragonite, XScale.
|
||||
ARCv2, AVR32, DSP563xx, DSP5680xx, EnSilica eSi-RISC, EJTAG (MIPS32, MIPS64),
|
||||
ESP32, ESP32-S2, ESP32-S3, Intel Quark, LS102x-SAP, RISC-V, ST STM8,
|
||||
Xtensa.
|
||||
|
||||
### Flash drivers
|
||||
|
||||
ADUC702x, AT91SAM, AT91SAM9 (NAND), ATH79, ATmega128RFA1, Atmel SAM, AVR, CFI,
|
||||
DSP5680xx, EFM32, EM357, eSi-RISC, eSi-TSMC, EZR32HG, FM3, FM4, Freedom E SPI,
|
||||
GD32, i.MX31, Kinetis, LPC8xx/LPC1xxx/LPC2xxx/LPC541xx, LPC2900, LPC3180, LPC32xx,
|
||||
LPCSPIFI, Marvell QSPI, MAX32, Milandr, MXC, NIIET, nRF51, nRF52 , NuMicro,
|
||||
NUC910, Nuvoton NPCX, onsemi RSL10, Orion/Kirkwood, PIC32mx, PSoC4/5LP/6,
|
||||
Raspberry RP2040, Renesas RPC HF and SH QSPI,
|
||||
S3C24xx, S3C6400, SiM3x, SiFive Freedom E, Stellaris, ST BlueNRG, STM32,
|
||||
STM32 QUAD/OCTO-SPI for Flash/FRAM/EEPROM, STMSMI, STR7x, STR9x, SWM050,
|
||||
TI CC13xx, TI CC26xx, TI CC32xx, TI MSP432, Winner Micro w600, Xilinx XCF,
|
||||
XMC1xxx, XMC4xxx.
|
||||
|
||||
## Building OpenOCD
|
||||
|
||||
The INSTALL file contains generic instructions for running `configure`
|
||||
and compiling the OpenOCD source code. That file is provided by
|
||||
@@ -194,12 +216,12 @@ the GNU autotools, then you should read those instructions first.
|
||||
Note: if the INSTALL file is not present, it means you are using the
|
||||
source code from a development branch, not from an OpenOCD release.
|
||||
In this case, follow the instructions 'Compiling OpenOCD' below and
|
||||
the file will be created by the first command './bootstrap'.
|
||||
the file will be created by the first command `./bootstrap`.
|
||||
|
||||
The remainder of this document tries to provide some instructions for
|
||||
those looking for a quick-install.
|
||||
|
||||
## OpenOCD Dependencies
|
||||
### OpenOCD Dependencies
|
||||
|
||||
GCC or Clang is currently required to build OpenOCD. The developers
|
||||
have begun to enforce strict code warnings (-Wall, -Werror, -Wextra,
|
||||
@@ -216,7 +238,7 @@ You'll also need:
|
||||
- pkg-config >= 0.23 or pkgconf
|
||||
- libjim >= 0.79
|
||||
|
||||
Additionally, for building from git:
|
||||
Additionally, for building from Git:
|
||||
|
||||
- autoconf >= 2.69
|
||||
- automake >= 1.14
|
||||
@@ -224,9 +246,8 @@ Additionally, for building from git:
|
||||
|
||||
Optional USB-based adapter drivers need libusb-1.0.
|
||||
|
||||
Optional USB-Blaster, ASIX Presto and OpenJTAG interface adapter
|
||||
drivers need:
|
||||
- libftdi: http://www.intra2net.com/en/developer/libftdi/index.php
|
||||
Optional USB-Blaster, ASIX Presto and OpenJTAG interface adapter drivers need
|
||||
[libftdi](http://www.intra2net.com/en/developer/libftdi/index.php) library.
|
||||
|
||||
Optional CMSIS-DAP adapter driver needs HIDAPI library.
|
||||
|
||||
@@ -241,6 +262,84 @@ Optional development script checkpatch needs:
|
||||
- perl
|
||||
- python
|
||||
- python-ply
|
||||
- pymarkdownlnt
|
||||
|
||||
### Compiling OpenOCD
|
||||
|
||||
To build OpenOCD, use the following sequence of commands:
|
||||
|
||||
```sh
|
||||
./bootstrap
|
||||
./configure [options]
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
The `bootstrap` command is only necessary when building from the Git repository.
|
||||
The `configure` step generates the Makefiles required to build OpenOCD, usually
|
||||
with one or more options provided to it.
|
||||
The first 'make' step will build OpenOCD and place the final executable in './src/'.
|
||||
The final (optional) step, `make install`, places all of the files in the
|
||||
required location.
|
||||
|
||||
To see the list of all the supported options, run `./configure --help`
|
||||
|
||||
### Cross-compiling Options
|
||||
|
||||
Cross-compiling is supported the standard autotools way, you just need
|
||||
to specify the cross-compiling target triplet in the --host option,
|
||||
e.g. for cross-building for Windows 32-bit with MinGW on Debian:
|
||||
|
||||
```sh
|
||||
./configure --host=i686-w64-mingw32 [options]
|
||||
```
|
||||
|
||||
To make pkg-config work nicely for cross-compiling, you might need an additional
|
||||
wrapper script as described at <https://autotools.io/pkgconfig/cross-compiling.html>.
|
||||
|
||||
This is needed to tell pkg-config where to look for the target
|
||||
libraries that OpenOCD depends on. Alternatively, you can specify
|
||||
`*_CFLAGS` and `*_LIBS` environment variables directly, see `./configure
|
||||
--help` for the details.
|
||||
|
||||
For a more or less complete script that does all this for you, see `contrib/cross-build.sh`.
|
||||
|
||||
### Parallel Port Dongles
|
||||
|
||||
If you want to access the parallel port using the PPDEV interface you
|
||||
have to specify both `--enable-parport` and `--enable-parport-ppdev`, since
|
||||
the later option is an option to the parport driver.
|
||||
|
||||
The same is true for the `--enable-parport-giveio` option, you have to
|
||||
use both the `--enable-parport` and the `--enable-parport-giveio` option
|
||||
if you want to use giveio instead of ioperm parallel port access
|
||||
method.
|
||||
|
||||
### Obtaining OpenOCD From Git
|
||||
|
||||
You can download the current Git version with a Git client of your
|
||||
choice from the main repository: `git://git.code.sf.net/p/openocd/code`
|
||||
|
||||
You may prefer to use a mirror:
|
||||
|
||||
- <http://repo.or.cz/r/openocd.git>
|
||||
- git://repo.or.cz/openocd.git
|
||||
|
||||
Using the Git command line client, you might use the following command
|
||||
to set up a local copy of the current repository (make sure there is no
|
||||
directory called "openocd" in the current directory):
|
||||
|
||||
```sh
|
||||
git clone git://git.code.sf.net/p/openocd/code openocd
|
||||
```
|
||||
|
||||
Then you can update that at your convenience using `git pull`.
|
||||
|
||||
There is also a gitweb interface, which you can use either to browse the
|
||||
repository or to download arbitrary snapshots using HTTP: <http://repo.or.cz/w/openocd.git>.
|
||||
|
||||
Snapshots are compressed tarballs of the source tree, about 1.3 MBytes
|
||||
each at this writing.
|
||||
|
||||
## Permissions delegation
|
||||
|
||||
@@ -258,82 +357,3 @@ For parallel port adapters on GNU/Linux and FreeBSD please change your
|
||||
For parport adapters on Windows you need to run install_giveio.bat
|
||||
(it's also possible to use "ioperm" with Cygwin instead) to give
|
||||
ordinary users permissions for accessing the "LPT" registers directly.
|
||||
|
||||
## Compiling OpenOCD
|
||||
|
||||
To build OpenOCD, use the following sequence of commands:
|
||||
|
||||
./bootstrap
|
||||
./configure [options]
|
||||
make
|
||||
sudo make install
|
||||
|
||||
The `bootstrap` command is only necessary when building from the Git repository. The `configure` step generates the Makefiles required to build
|
||||
OpenOCD, usually with one or more options provided to it. The first
|
||||
'make' step will build OpenOCD and place the final executable in
|
||||
'./src/'. The final (optional) step, `make install`, places all of
|
||||
the files in the required location.
|
||||
|
||||
To see the list of all the supported options, run `./configure --help`
|
||||
|
||||
## Cross-compiling Options
|
||||
|
||||
Cross-compiling is supported the standard autotools way, you just need
|
||||
to specify the cross-compiling target triplet in the --host option,
|
||||
e.g. for cross-building for Windows 32-bit with MinGW on Debian:
|
||||
|
||||
./configure --host=i686-w64-mingw32 [options]
|
||||
|
||||
To make pkg-config work nicely for cross-compiling, you might need an
|
||||
additional wrapper script as described at
|
||||
|
||||
https://autotools.io/pkgconfig/cross-compiling.html
|
||||
|
||||
This is needed to tell pkg-config where to look for the target
|
||||
libraries that OpenOCD depends on. Alternatively, you can specify
|
||||
`*_CFLAGS` and `*_LIBS` environment variables directly, see `./configure
|
||||
--help` for the details.
|
||||
|
||||
For a more or less complete script that does all this for you, see
|
||||
|
||||
contrib/cross-build.sh
|
||||
|
||||
## Parallel Port Dongles
|
||||
|
||||
If you want to access the parallel port using the PPDEV interface you
|
||||
have to specify both `--enable-parport` and `--enable-parport-ppdev`, since
|
||||
the later option is an option to the parport driver.
|
||||
|
||||
The same is true for the `--enable-parport-giveio` option, you have to
|
||||
use both the `--enable-parport` and the `--enable-parport-giveio` option
|
||||
if you want to use giveio instead of ioperm parallel port access
|
||||
method.
|
||||
|
||||
|
||||
# Obtaining OpenOCD From GIT
|
||||
|
||||
You can download the current GIT version with a GIT client of your
|
||||
choice from the main repository:
|
||||
|
||||
git://git.code.sf.net/p/openocd/code
|
||||
|
||||
You may prefer to use a mirror:
|
||||
|
||||
http://repo.or.cz/r/openocd.git
|
||||
git://repo.or.cz/openocd.git
|
||||
|
||||
Using the GIT command line client, you might use the following command
|
||||
to set up a local copy of the current repository (make sure there is no
|
||||
directory called "openocd" in the current directory):
|
||||
|
||||
git clone git://git.code.sf.net/p/openocd/code openocd
|
||||
|
||||
Then you can update that at your convenience using `git pull`.
|
||||
|
||||
There is also a gitweb interface, which you can use either to browse
|
||||
the repository or to download arbitrary snapshots using HTTP:
|
||||
|
||||
http://repo.or.cz/w/openocd.git
|
||||
|
||||
Snapshots are compressed tarballs of the source tree, about 1.3 MBytes
|
||||
each at this writing.
|
||||
48
configure.ac
48
configure.ac
@@ -16,7 +16,7 @@ AS_IF([test "x$MAKEINFO" = "x"], [
|
||||
])
|
||||
AC_SUBST([MAKEINFO])
|
||||
|
||||
AM_INIT_AUTOMAKE([-Wall -Wno-portability dist-bzip2 dist-zip subdir-objects])
|
||||
AM_INIT_AUTOMAKE([foreign -Wall -Wno-portability dist-bzip2 dist-zip subdir-objects])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
@@ -56,15 +56,9 @@ AC_CHECK_TYPE([Elf64_Ehdr],
|
||||
AC_DEFINE([HAVE_ELF64], [1], [Define to 1 if the system has the type 'Elf64_Ehdr'.]),
|
||||
[], [[#include <elf.h>]])
|
||||
|
||||
AC_MSG_CHECKING([for glibc])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <features.h>]], [[int v = __GLIBC__;return 0;]])],
|
||||
[have_glibc=yes], [have_glibc=no])
|
||||
AC_MSG_RESULT($have_glibc)
|
||||
|
||||
AC_CHECK_HEADERS([fcntl.h])
|
||||
AC_CHECK_HEADERS([linux/pci.h])
|
||||
AC_CHECK_HEADERS([linux/spi/spidev.h])
|
||||
AC_CHECK_HEADERS([malloc.h])
|
||||
AC_CHECK_HEADERS([netdb.h])
|
||||
AC_CHECK_HEADERS([poll.h])
|
||||
AC_CHECK_HEADERS([strings.h])
|
||||
@@ -102,6 +96,8 @@ AC_CHECK_FUNCS([strnlen])
|
||||
AC_CHECK_FUNCS([gettimeofday])
|
||||
AC_CHECK_FUNCS([usleep])
|
||||
AC_CHECK_FUNCS([realpath])
|
||||
AC_CHECK_FUNCS([mallinfo])
|
||||
AC_CHECK_FUNCS([mallinfo2])
|
||||
|
||||
# guess-rev.sh only exists in the repository, not in the released archives
|
||||
AC_MSG_CHECKING([whether to build a release])
|
||||
@@ -268,39 +264,6 @@ AS_IF([test "x$enable_gcov" = "xyes"], [
|
||||
AC_DEFINE([USE_GCOV], [0], [0 to leave coverage collection disabled.])
|
||||
])
|
||||
|
||||
# set default for debug_usb_comms, overridden by following options
|
||||
debug_usb_comms=no
|
||||
|
||||
AC_ARG_ENABLE([verbose],
|
||||
AS_HELP_STRING([--enable-verbose],
|
||||
[Enable verbose JTAG I/O messages (for debugging).]),
|
||||
[
|
||||
debug_usb_comms=$enableval
|
||||
], [])
|
||||
|
||||
AC_ARG_ENABLE([verbose_usb_comms],
|
||||
AS_HELP_STRING([--enable-verbose-usb-comms],
|
||||
[Enable verbose USB communication messages (for debugging)]),
|
||||
[debug_usb_comms=$enableval], [])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable verbose USB communication messages]);
|
||||
AC_MSG_RESULT([$debug_usb_comms])
|
||||
AS_IF([test "x$debug_usb_comms" = "xyes"], [
|
||||
AC_DEFINE([_DEBUG_USB_COMMS_],[1], [Print verbose USB communication messages])
|
||||
])
|
||||
|
||||
debug_malloc=no
|
||||
AC_ARG_ENABLE([malloc_logging],
|
||||
AS_HELP_STRING([--enable-malloc-logging],
|
||||
[Include free space in logging messages (requires malloc.h).]),
|
||||
[debug_malloc=$enableval], [])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable malloc free space logging]);
|
||||
AC_MSG_RESULT([$debug_malloc])
|
||||
AS_IF([test "x$debug_malloc" = "xyes" -a "x$have_glibc" = "xyes"], [
|
||||
AC_DEFINE([_DEBUG_FREE_SPACE_],[1], [Include malloc free space in logging])
|
||||
])
|
||||
|
||||
m4_define([AC_ARG_ADAPTERS], [
|
||||
m4_foreach([adapter_driver], [$1],
|
||||
[AC_ARG_ENABLE(ADAPTER_OPT([adapter_driver]),
|
||||
@@ -564,10 +527,6 @@ AS_IF([test "x$enable_capstone" != xno], [
|
||||
])
|
||||
])
|
||||
|
||||
AS_IF([test "x$enable_capstone" == xno], [
|
||||
AC_DEFINE([HAVE_CAPSTONE], [0], [0 if you don't have Capstone disassembly framework.])
|
||||
])
|
||||
|
||||
for hidapi_lib in hidapi hidapi-hidraw hidapi-libusb; do
|
||||
PKG_CHECK_MODULES([HIDAPI],[$hidapi_lib],[
|
||||
use_hidapi=yes
|
||||
@@ -785,6 +744,7 @@ AC_DEFINE([_GNU_SOURCE],[1],[Use GNU C library extensions (e.g. stdndup).])
|
||||
GCC_WARNINGS="-Wall -Wstrict-prototypes -Wformat-security -Wshadow"
|
||||
AS_IF([test "x${gcc_wextra}" = "xyes"], [
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Wextra -Wno-unused-parameter"
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Wno-gnu-folding-constant"
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Wbad-function-cast"
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Wcast-align"
|
||||
GCC_WARNINGS="${GCC_WARNINGS} -Wredundant-decls"
|
||||
|
||||
@@ -239,7 +239,7 @@ needing a Git client:
|
||||
|
||||
@uref{http://repo.or.cz/w/openocd.git}
|
||||
|
||||
The @file{README} file contains the instructions for building the project
|
||||
The @file{README.md} file contains the instructions for building the project
|
||||
from the repository or a snapshot.
|
||||
|
||||
Developers that want to contribute patches to the OpenOCD system are
|
||||
@@ -6160,7 +6160,7 @@ Some drivers also activate driver-specific commands.
|
||||
This is a special driver that maps a previously defined bank to another
|
||||
address. All bank settings will be copied from the master physical bank.
|
||||
|
||||
The @var{virtual} driver defines one mandatory parameters,
|
||||
The @var{virtual} driver defines one mandatory parameter,
|
||||
|
||||
@itemize
|
||||
@item @var{master_bank} The bank that this virtual address refers to.
|
||||
@@ -6178,6 +6178,28 @@ flash bank vbank1 virtual 0x9fc00000 0 0 0 \
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Flash Driver} ro_alias
|
||||
Similar as @var{virtual} driver but suppresses write
|
||||
and erase. Use to build a complete memory map for gdb.
|
||||
Bank size will be copied from the master physical bank.
|
||||
|
||||
The @var{virtual} driver defines one mandatory parameter,
|
||||
|
||||
@itemize
|
||||
@item @var{master_bank} The bank that this virtual address refers to.
|
||||
@end itemize
|
||||
@end deffn
|
||||
|
||||
@deffn {Flash Driver} read_only
|
||||
A stub driver without write and erase.
|
||||
Use to define a ROM region for the gdb memory map.
|
||||
|
||||
@example
|
||||
flash bank $_CHIPNAME.sysrom read_only 0x1ff00000 0xedc0 0 0 \
|
||||
$_TARGETNAME
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@subsection External Flash
|
||||
|
||||
@deffn {Flash Driver} {cfi}
|
||||
@@ -7032,6 +7054,11 @@ All members of the ATSAMV7x, ATSAMS70, and ATSAME70 families from
|
||||
Atmel include internal flash and use ARM's Cortex-M7 core.
|
||||
This driver uses the same command names/syntax as @xref{at91sam3}.
|
||||
|
||||
The same driver provides interface for PIC32CZ CA70 series. This
|
||||
Cortex-M7 family from Microchip is both binary and pin to pin compatible
|
||||
with Atmel's SAM series. The PIC series is a replacement of the original
|
||||
SAM series from Atmel after the company acquisition by Microchip.
|
||||
|
||||
@example
|
||||
flash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME
|
||||
@end example
|
||||
@@ -8504,7 +8531,7 @@ The @var{num} parameter is a value shown by @command{flash banks}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Flash Driver} {stm32l4x}
|
||||
All members of the STM32 C0, G0, G4, L4, L4+, L5, U0, U5, WB and WL
|
||||
All members of the STM32 C0, G0, G4, L4, L4+, L5, U0, U5, WB, WBA and WL
|
||||
microcontroller families from STMicroelectronics include internal flash
|
||||
and use ARM Cortex-M0+, M4 and M33 cores.
|
||||
The driver automatically recognizes a number of these chips using
|
||||
@@ -9502,7 +9529,12 @@ port is 6666.
|
||||
@section Server Commands
|
||||
|
||||
@deffn {Command} {exit}
|
||||
Exits the current telnet session.
|
||||
Exits the current telnet or Tcl session but the OpenOCD process remains running.
|
||||
This command should only be used in telnet or Tcl sessions (and not directly
|
||||
in Tcl scripts).
|
||||
|
||||
Note: To terminate the whole OpenOCD process, use the
|
||||
@command{shutdown} command instead.
|
||||
@end deffn
|
||||
|
||||
@deffn {Command} {help} [string]
|
||||
@@ -9561,7 +9593,9 @@ Level 0 is error messages only;
|
||||
level 1 adds warnings;
|
||||
level 2 adds informational messages;
|
||||
level 3 adds debugging messages;
|
||||
and level 4 adds verbose low-level debug messages.
|
||||
level 4 adds verbose low-level debug messages;
|
||||
and level 5 adds USB communication messages
|
||||
and amount of free heap space if mallinfo is available.
|
||||
The default is level 2, but that can be overridden on
|
||||
the command line along with the location of that log
|
||||
file (which is normally the server's standard output).
|
||||
|
||||
@@ -21,7 +21,7 @@ void nand_device_add(struct nand_device *c)
|
||||
{
|
||||
if (nand_devices) {
|
||||
struct nand_device *p = nand_devices;
|
||||
while (p && p->next)
|
||||
while (p->next)
|
||||
p = p->next;
|
||||
p->next = c;
|
||||
} else
|
||||
|
||||
@@ -60,6 +60,7 @@ NOR_DRIVERS = \
|
||||
%D%/psoc5lp.c \
|
||||
%D%/psoc6.c \
|
||||
%D%/qn908x.c \
|
||||
%D%/read_only.c \
|
||||
%D%/renesas_rpchf.c \
|
||||
%D%/rp2xxx.c \
|
||||
%D%/rsl10.c \
|
||||
|
||||
@@ -87,6 +87,16 @@ static const struct flash_ctrl_priv_data flash_priv_data_lpf = {
|
||||
.part_name = "STM32WB09 (BLUENRG-LPF)",
|
||||
};
|
||||
|
||||
static const struct flash_ctrl_priv_data flash_priv_data_spirit3 = {
|
||||
.die_id_reg = 0x40000000,
|
||||
.jtag_idcode_reg = 0x40000004,
|
||||
.flash_base = 0x10040000,
|
||||
.flash_regs_base = 0x40001000,
|
||||
.flash_page_size = 2048,
|
||||
.jtag_idcode = 0x02027041,
|
||||
.part_name = "STM32WL33 (SPIRIT3)",
|
||||
};
|
||||
|
||||
struct bluenrgx_flash_bank {
|
||||
bool probed;
|
||||
uint32_t die_id;
|
||||
@@ -98,7 +108,8 @@ static const struct flash_ctrl_priv_data *flash_ctrl[] = {
|
||||
&flash_priv_data_2,
|
||||
&flash_priv_data_lp,
|
||||
&flash_priv_data_lps,
|
||||
&flash_priv_data_lpf
|
||||
&flash_priv_data_lpf,
|
||||
&flash_priv_data_spirit3
|
||||
};
|
||||
|
||||
/* flash_bank bluenrg-x 0 0 0 0 <target#> */
|
||||
@@ -476,7 +487,8 @@ static int bluenrgx_probe(struct flash_bank *bank)
|
||||
return retval;
|
||||
|
||||
if (idcode != flash_priv_data_lp.jtag_idcode && idcode != flash_priv_data_lps.jtag_idcode
|
||||
&& idcode != flash_priv_data_lpf.jtag_idcode) {
|
||||
&& idcode != flash_priv_data_lpf.jtag_idcode
|
||||
&& idcode != flash_priv_data_spirit3.jtag_idcode) {
|
||||
retval = target_read_u32(bank->target, BLUENRG2_JTAG_REG, &idcode);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
@@ -563,4 +575,5 @@ const struct flash_driver bluenrgx_flash = {
|
||||
.protect_check = NULL,
|
||||
.auto_probe = bluenrgx_auto_probe,
|
||||
.info = bluenrgx_get_info,
|
||||
.free_driver_priv = default_flash_free_driver_priv,
|
||||
};
|
||||
|
||||
@@ -44,6 +44,11 @@ int flash_driver_protect(struct flash_bank *bank, int set, unsigned int first,
|
||||
int retval;
|
||||
unsigned int num_blocks;
|
||||
|
||||
if (!bank->driver->protect) {
|
||||
LOG_ERROR("Flash protection is not supported");
|
||||
return ERROR_FLASH_OPER_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (bank->num_prot_blocks)
|
||||
num_blocks = bank->num_prot_blocks;
|
||||
else
|
||||
@@ -59,11 +64,6 @@ int flash_driver_protect(struct flash_bank *bank, int set, unsigned int first,
|
||||
/* force "set" to 0/1 */
|
||||
set = !!set;
|
||||
|
||||
if (!bank->driver->protect) {
|
||||
LOG_ERROR("Flash protection is not supported.");
|
||||
return ERROR_FLASH_OPER_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* DANGER!
|
||||
*
|
||||
* We must not use any cached information about protection state!!!!
|
||||
@@ -223,15 +223,8 @@ void flash_free_all_banks(void)
|
||||
else
|
||||
LOG_WARNING("Flash driver of %s does not support free_driver_priv()", bank->name);
|
||||
|
||||
/* For 'virtual' flash driver bank->sectors and bank->prot_blocks pointers are copied from
|
||||
* master flash_bank structure. They point to memory locations allocated by master flash driver
|
||||
* so master driver is responsible for releasing them.
|
||||
* Avoid UB caused by double-free memory corruption if flash bank is 'virtual'. */
|
||||
|
||||
if (strcmp(bank->driver->name, "virtual") != 0) {
|
||||
free(bank->sectors);
|
||||
free(bank->prot_blocks);
|
||||
}
|
||||
free(bank->sectors);
|
||||
free(bank->prot_blocks);
|
||||
|
||||
free(bank->name);
|
||||
free(bank);
|
||||
@@ -343,6 +336,10 @@ static int default_flash_mem_blank_check(struct flash_bank *bank)
|
||||
}
|
||||
|
||||
uint8_t *buffer = malloc(buffer_size);
|
||||
if (!buffer) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < bank->num_sectors; i++) {
|
||||
uint32_t j;
|
||||
@@ -389,8 +386,10 @@ int default_flash_blank_check(struct flash_bank *bank)
|
||||
|
||||
struct target_memory_check_block *block_array;
|
||||
block_array = malloc(bank->num_sectors * sizeof(struct target_memory_check_block));
|
||||
if (!block_array)
|
||||
if (!block_array) {
|
||||
LOG_WARNING("Running slow fallback erase check - limited host memory available");
|
||||
return default_flash_mem_blank_check(bank);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < bank->num_sectors; i++) {
|
||||
block_array[i].address = bank->base + bank->sectors[i].offset;
|
||||
@@ -400,17 +399,18 @@ int default_flash_blank_check(struct flash_bank *bank)
|
||||
|
||||
bool fast_check = true;
|
||||
for (unsigned int i = 0; i < bank->num_sectors; ) {
|
||||
unsigned int checked;
|
||||
retval = target_blank_check_memory(target,
|
||||
block_array + i, bank->num_sectors - i,
|
||||
bank->erased_value);
|
||||
if (retval < 1) {
|
||||
bank->erased_value, &checked);
|
||||
if (retval != ERROR_OK) {
|
||||
/* Run slow fallback if the first run gives no result
|
||||
* otherwise use possibly incomplete results */
|
||||
if (i == 0)
|
||||
fast_check = false;
|
||||
break;
|
||||
}
|
||||
i += retval; /* add number of blocks done this round */
|
||||
i += checked; /* add number of blocks done this round */
|
||||
}
|
||||
|
||||
if (fast_check) {
|
||||
@@ -419,9 +419,9 @@ int default_flash_blank_check(struct flash_bank *bank)
|
||||
retval = ERROR_OK;
|
||||
} else {
|
||||
if (retval == ERROR_NOT_IMPLEMENTED)
|
||||
LOG_USER("Running slow fallback erase check");
|
||||
LOG_DEBUG("Running slow fallback erase check");
|
||||
else
|
||||
LOG_USER("Running slow fallback erase check - add working memory");
|
||||
LOG_WARNING("Running slow fallback erase check - add working memory");
|
||||
|
||||
retval = default_flash_mem_blank_check(bank);
|
||||
}
|
||||
@@ -735,11 +735,25 @@ int flash_write_unlock_verify(struct target *target, struct image *image,
|
||||
unsigned int section;
|
||||
uint32_t section_offset;
|
||||
struct flash_bank *c;
|
||||
int *padding;
|
||||
|
||||
section = 0;
|
||||
section_offset = 0;
|
||||
|
||||
/* allocate padding array */
|
||||
int *padding = calloc(image->num_sections, sizeof(*padding));
|
||||
|
||||
/* This fn requires all sections to be in ascending order of addresses,
|
||||
* whereas an image can have sections out of order. */
|
||||
struct imagesection **sections = malloc(sizeof(struct imagesection *) *
|
||||
image->num_sections);
|
||||
|
||||
if (!padding || !sections) {
|
||||
LOG_ERROR("Out of memory");
|
||||
free(padding);
|
||||
free(sections);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (written)
|
||||
*written = 0;
|
||||
|
||||
@@ -750,14 +764,6 @@ int flash_write_unlock_verify(struct target *target, struct image *image,
|
||||
flash_set_dirty();
|
||||
}
|
||||
|
||||
/* allocate padding array */
|
||||
padding = calloc(image->num_sections, sizeof(*padding));
|
||||
|
||||
/* This fn requires all sections to be in ascending order of addresses,
|
||||
* whereas an image can have sections out of order. */
|
||||
struct imagesection **sections = malloc(sizeof(struct imagesection *) *
|
||||
image->num_sections);
|
||||
|
||||
for (unsigned int i = 0; i < image->num_sections; i++)
|
||||
sections[i] = &image->sections[i];
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ struct flash_bank {
|
||||
target_addr_t base; /**< The base address of this bank */
|
||||
uint32_t size; /**< The size of this chip bank, in bytes */
|
||||
|
||||
bool read_only; /**< a ROM region - mainly to list in gdb memory map */
|
||||
|
||||
unsigned int chip_width; /**< Width of the chip in bytes (1,2,4 bytes) */
|
||||
unsigned int bus_width; /**< Maximum bus width, in bytes (1,2,4 bytes) */
|
||||
|
||||
|
||||
@@ -292,7 +292,9 @@ extern const struct flash_driver psoc5lp_flash;
|
||||
extern const struct flash_driver psoc5lp_nvl_flash;
|
||||
extern const struct flash_driver psoc6_flash;
|
||||
extern const struct flash_driver qn908x_flash;
|
||||
extern const struct flash_driver read_only_flash;
|
||||
extern const struct flash_driver renesas_rpchf_flash;
|
||||
extern const struct flash_driver ro_alias_flash;
|
||||
extern const struct flash_driver rp2xxx_flash;
|
||||
extern const struct flash_driver rsl10_flash;
|
||||
extern const struct flash_driver sh_qspi_flash;
|
||||
|
||||
@@ -71,6 +71,8 @@ static const struct flash_driver * const flash_drivers[] = {
|
||||
&psoc5lp_nvl_flash,
|
||||
&psoc6_flash,
|
||||
&qn908x_flash,
|
||||
&read_only_flash,
|
||||
&ro_alias_flash,
|
||||
&renesas_rpchf_flash,
|
||||
&rp2xxx_flash,
|
||||
&rsl10_flash,
|
||||
|
||||
@@ -605,7 +605,7 @@ static bool fm4_name_match(const char *s, const char *pattern)
|
||||
if (!pattern[i])
|
||||
return true;
|
||||
/* Use x as wildcard */
|
||||
if (pattern[i] != 'x' && tolower(s[i]) != tolower(pattern[i]))
|
||||
if (pattern[i] != 'x' && tolower((unsigned char)s[i]) != tolower((unsigned char)pattern[i]))
|
||||
return false;
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ struct mspm0_family_info {
|
||||
|
||||
/* https://www.ti.com/lit/ds/symlink/mspm0l1346.pdf Table 8-13 and so on */
|
||||
static const struct mspm0_part_info mspm0l_parts[] = {
|
||||
/* MSPM0L110x */
|
||||
{ "MSPM0L1105TDGS20R", 0x51DB, 0x16 },
|
||||
{ "MSPM0L1105TDGS28R", 0x51DB, 0x83 },
|
||||
{ "MSPM0L1105TDYYR", 0x51DB, 0x54 },
|
||||
@@ -138,6 +139,7 @@ static const struct mspm0_part_info mspm0l_parts[] = {
|
||||
{ "MSPM0L1106TDYYR", 0x5552, 0x9D },
|
||||
{ "MSPM0L1106TRGER", 0x5552, 0x90 },
|
||||
{ "MSPM0L1106TRHBR", 0x5552, 0x53 },
|
||||
/* MSPM0L130x (covers MSPM0L134x) */
|
||||
{ "MSPM0L1303SRGER", 0xef0, 0x17 },
|
||||
{ "MSPM0L1303TRGER", 0xef0, 0xe2 },
|
||||
{ "MSPM0L1304QDGS20R", 0xd717, 0x91 },
|
||||
@@ -188,20 +190,24 @@ static const struct mspm0_part_info mspm0l_parts[] = {
|
||||
{ "MSPM0L1346TDGS28R", 0xf2b5, 0xef },
|
||||
};
|
||||
|
||||
/* https://www.ti.com/lit/ds/symlink/mspm0g3506.pdf Table 8-20 */
|
||||
static const struct mspm0_part_info mspm0g_parts[] = {
|
||||
/* https://www.ti.com/lit/ds/symlink/mspm0g3506.pdf Table 8-22 */
|
||||
static const struct mspm0_part_info mspm0g_parts_bb88[] = {
|
||||
/* MSPM0G110x */
|
||||
{ "MSPM0G1105TPTR", 0x8934, 0xD },
|
||||
{ "MSPM0G1105TRGZR", 0x8934, 0xFE },
|
||||
{ "MSPM0G1106TPMR", 0x477B, 0xD4 },
|
||||
{ "MSPM0G1106TPTR", 0x477B, 0x71 },
|
||||
{ "MSPM0G1106TRGZR", 0x477B, 0xBB },
|
||||
{ "MSPM0G1106TRHBR", 0x477B, 0x0 },
|
||||
{ "MSPM0G1106TRHBR", 0x477B, 0x01 },
|
||||
{ "MSPM0G1106TYCJR", 0x477B, 0x09 },
|
||||
{ "MSPM0G1107TDGS28R", 0x807B, 0x82 },
|
||||
{ "MSPM0G1107TPMR", 0x807B, 0xB3 },
|
||||
{ "MSPM0G1107TPTR", 0x807B, 0x32 },
|
||||
{ "MSPM0G1107TRGER", 0x807B, 0x79 },
|
||||
{ "MSPM0G1107TRGZR", 0x807B, 0x20 },
|
||||
{ "MSPM0G1107TRHBR", 0x807B, 0xBC },
|
||||
{ "MSPM0G1107TYCJR", 0x807B, 0x7A },
|
||||
/* MSPM0G150x */
|
||||
{ "MSPM0G1505SDGS28R", 0x13C4, 0x73 },
|
||||
{ "MSPM0G1505SPMR", 0x13C4, 0x53 },
|
||||
{ "MSPM0G1505SPTR", 0x13C4, 0x3E },
|
||||
@@ -213,11 +219,16 @@ static const struct mspm0_part_info mspm0g_parts[] = {
|
||||
{ "MSPM0G1506SRGER", 0x5AE0, 0x67 },
|
||||
{ "MSPM0G1506SRGZR", 0x5AE0, 0x75 },
|
||||
{ "MSPM0G1506SRHBR", 0x5AE0, 0x57 },
|
||||
{ "MSPM0G1506SRPTR", 0x5AE0, 0x36 },
|
||||
{ "MSPM0G1506SYCJR", 0x5AE0, 0x9E },
|
||||
{ "MSPM0G1507SDGS28R", 0x2655, 0x6D },
|
||||
{ "MSPM0G1507SPMR", 0x2655, 0x97 },
|
||||
{ "MSPM0G1507SPTR", 0x2655, 0x2E },
|
||||
{ "MSPM0G1507SRGER", 0x2655, 0x83 },
|
||||
{ "MSPM0G1507SRGZR", 0x2655, 0xD3 },
|
||||
{ "MSPM0G1507SRHBR", 0x2655, 0x4D },
|
||||
{ "MSPM0G1507SYCJR", 0x2655, 0x65 },
|
||||
/* MSPM0G310x */
|
||||
{ "MSPM0G3105SDGS20R", 0x4749, 0x21 },
|
||||
{ "MSPM0G3105SDGS28R", 0x4749, 0xDD },
|
||||
{ "MSPM0G3105SRHBR", 0x4749, 0xBE },
|
||||
@@ -227,12 +238,12 @@ static const struct mspm0_part_info mspm0g_parts[] = {
|
||||
{ "MSPM0G3107SDGS20R", 0xAB39, 0x5C },
|
||||
{ "MSPM0G3107SDGS28R", 0xAB39, 0xCC },
|
||||
{ "MSPM0G3107SRHBR", 0xAB39, 0xB7 },
|
||||
/* MSPM0G350x */
|
||||
{ "MSPM0G3505SDGS28R", 0xc504, 0x8e },
|
||||
{ "MSPM0G3505SPMR", 0xc504, 0x1d },
|
||||
{ "MSPM0G3505SPTR", 0xc504, 0x93 },
|
||||
{ "MSPM0G3505SRGZR", 0xc504, 0xc7 },
|
||||
{ "MSPM0G3505SRHBR", 0xc504, 0xe7 },
|
||||
{ "MSPM0G3505TDGS28R", 0xc504, 0xdf },
|
||||
{ "MSPM0G3506SDGS28R", 0x151f, 0x8 },
|
||||
{ "MSPM0G3506SPMR", 0x151f, 0xd4 },
|
||||
{ "MSPM0G3506SPTR", 0x151f, 0x39 },
|
||||
@@ -243,27 +254,109 @@ static const struct mspm0_part_info mspm0g_parts[] = {
|
||||
{ "MSPM0G3507SPTR", 0xae2d, 0x3f },
|
||||
{ "MSPM0G3507SRGZR", 0xae2d, 0xf7 },
|
||||
{ "MSPM0G3507SRHBR", 0xae2d, 0x4c },
|
||||
{ "M0G3107QPMRQ1", 0x4e2f, 0x51 },
|
||||
{ "M0G3107QPTRQ1", 0x4e2f, 0xc7},
|
||||
{ "M0G3107QRGZRQ1", 0x4e2f, 0x8a },
|
||||
{ "M0G3107QRHBRQ1", 0x4e2f, 0x9a},
|
||||
{ "M0G3107QDGS28RQ1", 0x4e2f, 0xd5},
|
||||
{ "M0G3107QDGS28RQ1", 0x4e2f, 0x67},
|
||||
{ "M0G3107QDGS20RQ1", 0x4e2f, 0xfd},
|
||||
{ "M0G3106QPMRQ1", 0x54C7, 0x08},
|
||||
{ "M0G3105QDGS32RQ1", 0x1349, 0x08},
|
||||
{ "M0G3106QPTRQ1", 0x54C7, 0x3F},
|
||||
{ "M0G3105QDGS28RQ1", 0x1349, 0x1B},
|
||||
{ "M0G3106QRGZRQ1", 0x94AD, 0xE6},
|
||||
/* MSPM0G310x-Q1 */
|
||||
{ "M0G3105QDGS20RQ1", 0x1349, 0xFB},
|
||||
{ "M0G3106QRHBRQ1", 0x94AD, 0x20},
|
||||
{ "M0G3106QDGS32RQ1", 0x94AD, 0x8D},
|
||||
{ "M0G3106QDGS28RQ1", 0x94AD, 0x03},
|
||||
{ "M0G3106QDGS20RQ1", 0x94AD, 0x6F},
|
||||
{ "M0G3105QDGS28RQ1", 0x1349, 0x1B},
|
||||
{ "M0G3105QDGS32RQ1", 0x1349, 0x08},
|
||||
{ "M0G3105QPMRQ1", 0x1349, 0xD0},
|
||||
{ "M0G3105QPTRQ1", 0x1349, 0xEF},
|
||||
{ "M0G3105QRGZRQ1", 0x1349, 0x70},
|
||||
{ "M0G3105QRHBRQ1", 0x1349, 0x01},
|
||||
{ "M0G3106QDGS20RQ1", 0x94AD, 0x6F},
|
||||
{ "M0G3106QDGS28RQ1", 0x94AD, 0x03},
|
||||
{ "M0G3106QDGS32RQ1", 0x94AD, 0x8D},
|
||||
{ "M0G3106QPMRQ1", 0x54C7, 0x08},
|
||||
{ "M0G3106QPTRQ1", 0x54C7, 0x3F},
|
||||
{ "M0G3106QRGZRQ1", 0x94AD, 0xE6},
|
||||
{ "M0G3106QRHBRQ1", 0x94AD, 0x20},
|
||||
{ "M0G3107QDGS20RQ1", 0x4e2f, 0xfd},
|
||||
{ "M0G3107QDGS28RQ1", 0x4e2f, 0x67},
|
||||
{ "M0G3107QDGS28RQ1", 0x4e2f, 0xd5},
|
||||
{ "M0G3107QPMRQ1", 0x4e2f, 0x51 },
|
||||
{ "M0G3107QPTRQ1", 0x4e2f, 0xc7},
|
||||
{ "M0G3107QRGZRQ1", 0x4e2f, 0x8a },
|
||||
{ "M0G3107QRHBRQ1", 0x4e2f, 0x9a},
|
||||
/* MSPM0G350x-Q1 */
|
||||
{ "M0G3505QDGS28RQ1", 0x704E, 0x4C },
|
||||
{ "M0G3505QDGS32RQ1", 0x704E, 0x7F },
|
||||
{ "M0G3505QPMRQ1", 0x704E, 0x7B },
|
||||
{ "M0G3505QPTRQ1", 0x704E, 0x9C },
|
||||
{ "M0G3505QRGZRQ1", 0x704E, 0xC9 },
|
||||
{ "M0G3505QRHBRQ1", 0x704E, 0x26 },
|
||||
{ "M0G3506QDGS28RQ1", 0xEE12, 0x71 },
|
||||
{ "M0G3506QDGS32RQ1", 0xEE12, 0x6C },
|
||||
{ "M0G3506QPMRQ1", 0xEE12, 0x7B },
|
||||
{ "M0G3506QPTRQ1", 0xEE12, 0x5A },
|
||||
{ "M0G3506QRGZRQ1", 0xEE12, 0xD2 },
|
||||
{ "M0G3506QRHBRQ1", 0xEE12, 0xFC },
|
||||
{ "M0G3507QDGS28RQ1", 0x34E0, 0xEA },
|
||||
{ "M0G3507QDGS32RQ1", 0x34E0, 0xF6 },
|
||||
{ "M0G3507QPMRQ1", 0x34E0, 0x26 },
|
||||
{ "M0G3507QRGZRQ1", 0x34E0, 0xC5 },
|
||||
{ "M0G3507QRHBRQ1", 0x34E0, 0xAC },
|
||||
{ "M0G3507QSPTRQ1", 0x34E0, 0xE3 },
|
||||
};
|
||||
|
||||
/* https://www.ti.com/lit/gpn/mspm0g1518 Table 8-21 and so on */
|
||||
static const struct mspm0_part_info mspm0g_parts_bba9[] = {
|
||||
/* MSPM0Gx51x */
|
||||
{ "MSPM0G1518SPMR", 0x2120, 0x13 },
|
||||
{ "MSPM0G1518SPNR", 0x2120, 0x16 },
|
||||
{ "MSPM0G1518SPTR", 0x2120, 0x12 },
|
||||
{ "MSPM0G1518SPZR", 0x2120, 0x18 },
|
||||
{ "MSPM0G1518SRGZR", 0x2120, 0x11 },
|
||||
{ "MSPM0G1518SRHBR", 0x2120, 0x10 },
|
||||
{ "MSPM0G1518SZAWR", 0x2120, 0x19 },
|
||||
{ "MSPM0G1519SPMR", 0x2407, 0x13 },
|
||||
{ "MSPM0G1519SPNR", 0x2407, 0x16 },
|
||||
{ "MSPM0G1519SPTR", 0x2407, 0x12 },
|
||||
{ "MSPM0G1519SPZR", 0x2407, 0x18 },
|
||||
{ "MSPM0G1519SRGZR", 0x2407, 0x11 },
|
||||
{ "MSPM0G1519SRHBR", 0x2407, 0x10 },
|
||||
{ "MSPM0G1519SZAWR", 0x2407, 0x19 },
|
||||
{ "MSPM0G3518SPMR", 0x1205, 0x13 },
|
||||
{ "MSPM0G3518SPNR", 0x1205, 0x15 },
|
||||
{ "MSPM0G3518SPTR", 0x1205, 0x12 },
|
||||
{ "MSPM0G3518SPZR", 0x1205, 0x16 },
|
||||
{ "MSPM0G3518SRGZR", 0x1205, 0x11 },
|
||||
{ "MSPM0G3518SRHBR", 0x1205, 0x10 },
|
||||
{ "MSPM0G3518SZAWR", 0x1205, 0x19 },
|
||||
{ "MSPM0G3519SPMR", 0x1508, 0x13 },
|
||||
{ "MSPM0G3519SPNR", 0x1508, 0x15 },
|
||||
{ "MSPM0G3519SPTR", 0x1508, 0x12 },
|
||||
{ "MSPM0G3519SPZR", 0x1508, 0x16 },
|
||||
{ "MSPM0G3519SRGZR", 0x1508, 0x11 },
|
||||
{ "MSPM0G3519SRHBR", 0x1508, 0x10 },
|
||||
{ "MSPM0G3519SZAWR", 0x1508, 0x19 },
|
||||
/* MSPM0G351x-Q1 */
|
||||
{ "M0G3518QPMRQ1", 0x4009, 0x13 },
|
||||
{ "M0G3518QPNRQ1", 0x4009, 0x14 },
|
||||
{ "M0G3518QPTRQ1", 0x4009, 0x12 },
|
||||
{ "M0G3518QPZRQ1", 0x4009, 0x15 },
|
||||
{ "M0G3518QRGZRQ1", 0x4009, 0x11 },
|
||||
{ "M0G3518QRHBRQ1", 0x4009, 0x10 },
|
||||
{ "M0G3519QPMRQ1", 0x3512, 0x13 },
|
||||
{ "M0G3519AQPMRQ1", 0x3512, 0x16 },
|
||||
{ "M0G3519QPNRQ1", 0x3512, 0x14 },
|
||||
{ "M0G3519QPTRQ1", 0x3512, 0x12 },
|
||||
{ "M0G3519QPZRQ1", 0x3512, 0x15 },
|
||||
{ "M0G3519QRGZRQ1", 0x3512, 0x11 },
|
||||
{ "M0G3519QRHBRQ1", 0x3512, 0x10 },
|
||||
/* MSPM0G352x-Q1 */
|
||||
{ "M0G3529QPMRQ1", 0xF8D1, 0x13 },
|
||||
};
|
||||
|
||||
/* https://www.ti.com/lit/gpn/mspm0g5187 Table 8-24*/
|
||||
static const struct mspm0_part_info mspm0g_parts_bbbc[] = {
|
||||
/* MSPM0G5187 */
|
||||
{ "MSPM0G5187S28YCJR", 0x5610, 0x18 },
|
||||
{ "MSPM0G5187SDGS20R", 0x5610, 0x16 },
|
||||
{ "MSPM0G5187SPMR", 0x5610, 0x10 },
|
||||
{ "MSPM0G5187SPTR", 0x5610, 0x11 },
|
||||
{ "MSPM0G5187SRHBR", 0x5610, 0x13 },
|
||||
{ "MSPM0G5187SRGER", 0x5610, 0x14 },
|
||||
{ "MSPM0G5187SRGZR", 0x5610, 0x12 },
|
||||
{ "MSPM0G5187SRUYR", 0x5610, 0x17 },
|
||||
};
|
||||
|
||||
/* https://www.ti.com/lit/gpn/mspm0c1104 Table 8-12 and so on */
|
||||
@@ -305,7 +398,9 @@ static const struct mspm0_part_info mspm0lx22x_parts[] = {
|
||||
static const struct mspm0_family_info mspm0_finf[] = {
|
||||
{ "MSPM0L", 0xbb82, ARRAY_SIZE(mspm0l_parts), mspm0l_parts },
|
||||
{ "MSPM0Lx22x", 0xbb9f, ARRAY_SIZE(mspm0lx22x_parts), mspm0lx22x_parts },
|
||||
{ "MSPM0G", 0xbb88, ARRAY_SIZE(mspm0g_parts), mspm0g_parts },
|
||||
{ "MSPM0G", 0xbb88, ARRAY_SIZE(mspm0g_parts_bb88), mspm0g_parts_bb88 },
|
||||
{ "MSPM0G", 0xbba9, ARRAY_SIZE(mspm0g_parts_bba9), mspm0g_parts_bba9 },
|
||||
{ "MSPM0G", 0xbbbc, ARRAY_SIZE(mspm0g_parts_bbbc), mspm0g_parts_bbbc },
|
||||
{ "MSPM0C", 0xbba1, ARRAY_SIZE(mspm0c_parts), mspm0c_parts },
|
||||
};
|
||||
|
||||
|
||||
@@ -1081,17 +1081,18 @@ static int psoc5lp_erase_check(struct flash_bank *bank)
|
||||
|
||||
bool fast_check = true;
|
||||
for (unsigned int i = 0; i < num_sectors; ) {
|
||||
unsigned int checked;
|
||||
retval = armv7m_blank_check_memory(target,
|
||||
block_array + i, num_sectors - i,
|
||||
bank->erased_value);
|
||||
if (retval < 1) {
|
||||
bank->erased_value, &checked);
|
||||
if (retval != ERROR_OK) {
|
||||
/* Run slow fallback if the first run gives no result
|
||||
* otherwise use possibly incomplete results */
|
||||
if (i == 0)
|
||||
fast_check = false;
|
||||
break;
|
||||
}
|
||||
i += retval; /* add number of blocks done this round */
|
||||
i += checked; /* add number of blocks done this round */
|
||||
}
|
||||
|
||||
if (fast_check) {
|
||||
|
||||
51
src/flash/nor/read_only.c
Normal file
51
src/flash/nor/read_only.c
Normal file
@@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 by Tomas Vanek <vanekt@fbl.cz>
|
||||
*
|
||||
* To declare a read-only region for GDB memory map.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "imp.h"
|
||||
|
||||
FLASH_BANK_COMMAND_HANDLER(rom_bank_command)
|
||||
{
|
||||
bank->read_only = true;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int rom_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
|
||||
{
|
||||
LOG_ERROR("Erase of read-only memory refused");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static int rom_write(struct flash_bank *bank, const uint8_t *buffer,
|
||||
uint32_t offset, uint32_t count)
|
||||
{
|
||||
LOG_ERROR("Write to read-only memory refused");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static int rom_probe(struct flash_bank *bank)
|
||||
{
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
const struct flash_driver read_only_flash = {
|
||||
.name = "read_only",
|
||||
.flash_bank_command = rom_bank_command,
|
||||
.erase = rom_erase,
|
||||
.write = rom_write,
|
||||
.read = default_flash_read,
|
||||
.probe = rom_probe,
|
||||
.auto_probe = rom_probe,
|
||||
.erase_check = default_flash_blank_check,
|
||||
|
||||
// ROM driver doesn't set driver_priv, free(NULL) makes no harm
|
||||
.free_driver_priv = default_flash_free_driver_priv,
|
||||
};
|
||||
@@ -125,6 +125,8 @@ const struct flash_device flash_devices[] = {
|
||||
FLASH_ID("micron mt25ql01", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0021ba20, 0x100, 0x10000, 0x8000000),
|
||||
FLASH_ID("micron mt25qu01", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0021bb20, 0x100, 0x10000, 0x8000000),
|
||||
FLASH_ID("micron mt25ql02", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0022ba20, 0x100, 0x10000, 0x10000000),
|
||||
FLASH_ID("bsemi by25q16es", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x00154068, 0x100, 0x10000, 0x200000),
|
||||
FLASH_ID("boya by25q128as", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x00184068, 0x100, 0x10000, 0x1000000),
|
||||
FLASH_ID("win w25q80bv", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001440ef, 0x100, 0x10000, 0x100000),
|
||||
FLASH_ID("win w25q16jv", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001540ef, 0x100, 0x10000, 0x200000),
|
||||
FLASH_ID("win w25q16jv", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001570ef, 0x100, 0x10000, 0x200000), /* QPI / DTR */
|
||||
|
||||
@@ -287,7 +287,7 @@ struct stm32l4_wrp {
|
||||
};
|
||||
|
||||
/* human readable list of families this drivers supports (sorted alphabetically) */
|
||||
static const char *device_families = "STM32C0/G0/G4/L4/L4+/L5/U0/U3/U5/WB/WL";
|
||||
static const char *device_families = "STM32C0/G0/G4/L4/L4+/L5/U0/U3/U5/WB/WBA/WL";
|
||||
|
||||
static const struct stm32l4_rev stm32l47_l48xx_revs[] = {
|
||||
{ 0x1000, "1" }, { 0x1001, "2" }, { 0x1003, "3" }, { 0x1007, "4" }
|
||||
@@ -400,6 +400,10 @@ static const struct stm32l4_rev stm32wba5x_revs[] = {
|
||||
{ 0x1000, "A" },
|
||||
};
|
||||
|
||||
static const struct stm32l4_rev stm32wba6x_revs[] = {
|
||||
{ 0x1000, "A" }, { 0x1001, "Z" },
|
||||
};
|
||||
|
||||
static const struct stm32l4_rev stm32wb1xx_revs[] = {
|
||||
{ 0x1000, "A" }, { 0x2000, "B" },
|
||||
};
|
||||
@@ -754,8 +758,21 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
|
||||
.flags = F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS
|
||||
| F_WRP_HAS_LOCK,
|
||||
.flash_regs_base = 0x40022000,
|
||||
.fsize_addr = 0x0FF907A0,
|
||||
.otp_base = 0x0FF90000,
|
||||
.fsize_addr = 0x0BF907A0,
|
||||
.otp_base = 0x0BF90000,
|
||||
.otp_size = 512,
|
||||
},
|
||||
{
|
||||
.id = DEVID_STM32WBA6X,
|
||||
.revs = stm32wba6x_revs,
|
||||
.num_revs = ARRAY_SIZE(stm32wba6x_revs),
|
||||
.device_str = "STM32WBA6x",
|
||||
.max_flash_size_kb = 2048,
|
||||
.flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ
|
||||
| F_HAS_L5_FLASH_REGS | F_WRP_HAS_LOCK,
|
||||
.flash_regs_base = 0x40022000,
|
||||
.fsize_addr = 0x0BFA07A0,
|
||||
.otp_base = 0x0BFA0000,
|
||||
.otp_size = 512,
|
||||
},
|
||||
{
|
||||
@@ -2210,10 +2227,21 @@ static int stm32l4_probe(struct flash_bank *bank)
|
||||
}
|
||||
break;
|
||||
case DEVID_STM32WBA5X:
|
||||
/* single bank flash */
|
||||
case DEVID_STM32WBA6X:
|
||||
/* according to RM0493 Rev 7, Chapter 7.3.1
|
||||
* WBA5xx have 8K page size and are always
|
||||
* single bank.
|
||||
* According to RM0515 Rev 4, Chapter 7.3.1
|
||||
* WBA6xx have 8K page size and are always
|
||||
* DUAL BANK
|
||||
*/
|
||||
page_size_kb = 8;
|
||||
num_pages = flash_size_kb / page_size_kb;
|
||||
stm32l4_info->bank1_sectors = num_pages;
|
||||
if (stm32l4_info->optr & FLASH_U5_DUALBANK) {
|
||||
stm32l4_info->dual_bank_mode = true;
|
||||
stm32l4_info->bank1_sectors = num_pages / 2;
|
||||
}
|
||||
break;
|
||||
case DEVID_STM32WB5XX:
|
||||
case DEVID_STM32WB3XX:
|
||||
|
||||
@@ -120,6 +120,7 @@
|
||||
#define DEVID_STM32WB5XX 0x495
|
||||
#define DEVID_STM32WB3XX 0x496
|
||||
#define DEVID_STM32WLE_WL5XX 0x497
|
||||
#define DEVID_STM32WBA6X 0x4B0
|
||||
|
||||
/* known Flash base addresses */
|
||||
#define STM32_FLASH_BANK_BASE 0x08000000
|
||||
|
||||
@@ -736,7 +736,7 @@ COMMAND_HANDLER(str7x_handle_disable_jtag_command)
|
||||
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), ®);
|
||||
protection_regs = ~(reg >> 16);
|
||||
|
||||
while (((protection_regs) != 0) && (protection_level < 16)) {
|
||||
while ((protection_regs != 0) && (protection_level < 16)) {
|
||||
protection_regs >>= 1;
|
||||
protection_level++;
|
||||
}
|
||||
@@ -753,7 +753,7 @@ COMMAND_HANDLER(str7x_handle_disable_jtag_command)
|
||||
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
|
||||
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
|
||||
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0),
|
||||
~(1 << (15 + protection_level)));
|
||||
~(1U << (15 + protection_level)));
|
||||
flash_cmd = FLASH_SPR | FLASH_WMS;
|
||||
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
|
||||
}
|
||||
|
||||
@@ -1460,7 +1460,7 @@ COMMAND_HANDLER(handle_flash_list)
|
||||
for (struct flash_bank *p = flash_bank_list(); p; p = p->next) {
|
||||
command_print(CMD,
|
||||
"{\n"
|
||||
" name %s\n"
|
||||
" name {%s}\n"
|
||||
" driver %s\n"
|
||||
" base " TARGET_ADDR_FMT "\n"
|
||||
" size 0x%" PRIx32 "\n"
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2010 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
***************************************************************************/
|
||||
/*
|
||||
* Copyright (C) 2010 by Spencer Oliver <spen@spen-soft.co.uk>
|
||||
*
|
||||
* Copyright (C) 2019 by Tomas Vanek <vanekt@fbl.cz>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@@ -31,6 +32,9 @@ static void virtual_update_bank_info(struct flash_bank *bank)
|
||||
|
||||
/* update the info we do not have */
|
||||
bank->size = master_bank->size;
|
||||
if (bank->read_only)
|
||||
return;
|
||||
|
||||
bank->chip_width = master_bank->chip_width;
|
||||
bank->bus_width = master_bank->bus_width;
|
||||
bank->erased_value = master_bank->erased_value;
|
||||
@@ -93,34 +97,24 @@ static int virtual_erase(struct flash_bank *bank, unsigned int first,
|
||||
unsigned int last)
|
||||
{
|
||||
struct flash_bank *master_bank = virtual_get_master_bank(bank);
|
||||
int retval;
|
||||
|
||||
if (!master_bank)
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
|
||||
/* call master handler */
|
||||
retval = master_bank->driver->erase(master_bank, first, last);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return ERROR_OK;
|
||||
return master_bank->driver->erase(master_bank, first, last);
|
||||
}
|
||||
|
||||
static int virtual_write(struct flash_bank *bank, const uint8_t *buffer,
|
||||
uint32_t offset, uint32_t count)
|
||||
{
|
||||
struct flash_bank *master_bank = virtual_get_master_bank(bank);
|
||||
int retval;
|
||||
|
||||
if (!master_bank)
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
|
||||
/* call master handler */
|
||||
retval = master_bank->driver->write(master_bank, buffer, offset, count);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return ERROR_OK;
|
||||
return master_bank->driver->write(master_bank, buffer, offset, count);
|
||||
}
|
||||
|
||||
static int virtual_probe(struct flash_bank *bank)
|
||||
@@ -177,34 +171,37 @@ static int virtual_info(struct flash_bank *bank, struct command_invocation *cmd)
|
||||
static int virtual_blank_check(struct flash_bank *bank)
|
||||
{
|
||||
struct flash_bank *master_bank = virtual_get_master_bank(bank);
|
||||
int retval;
|
||||
|
||||
if (!master_bank)
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
|
||||
/* call master handler */
|
||||
retval = master_bank->driver->erase_check(master_bank);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return ERROR_OK;
|
||||
return master_bank->driver->erase_check(master_bank);
|
||||
}
|
||||
|
||||
static int virtual_flash_read(struct flash_bank *bank,
|
||||
uint8_t *buffer, uint32_t offset, uint32_t count)
|
||||
{
|
||||
struct flash_bank *master_bank = virtual_get_master_bank(bank);
|
||||
int retval;
|
||||
|
||||
if (!master_bank)
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
|
||||
/* call master handler */
|
||||
retval = master_bank->driver->read(master_bank, buffer, offset, count);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
return master_bank->driver->read(master_bank, buffer, offset, count);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
void virtual_flash_free_driver_priv(struct flash_bank *bank)
|
||||
{
|
||||
free(bank->driver_priv);
|
||||
bank->driver_priv = NULL;
|
||||
|
||||
/* For 'virtual' flash driver bank->sectors and bank->prot_blocks pointers are copied from
|
||||
* master flash_bank structure. They point to memory locations allocated by master flash driver
|
||||
* so master driver is responsible for releasing them.
|
||||
* Avoid UB caused by double-free memory corruption if flash bank is 'virtual'. */
|
||||
bank->sectors = NULL;
|
||||
bank->prot_blocks = NULL;
|
||||
}
|
||||
|
||||
const struct flash_driver virtual_flash = {
|
||||
@@ -219,5 +216,62 @@ const struct flash_driver virtual_flash = {
|
||||
.erase_check = virtual_blank_check,
|
||||
.protect_check = virtual_protect_check,
|
||||
.info = virtual_info,
|
||||
.free_driver_priv = default_flash_free_driver_priv,
|
||||
.free_driver_priv = virtual_flash_free_driver_priv,
|
||||
};
|
||||
|
||||
FLASH_BANK_COMMAND_HANDLER(ro_alias_bank_command)
|
||||
{
|
||||
if (CMD_ARGC < 7)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
// get the master flash bank
|
||||
const char *bank_name = CMD_ARGV[6];
|
||||
struct flash_bank *master_bank = get_flash_bank_by_name_noprobe(bank_name);
|
||||
|
||||
if (!master_bank) {
|
||||
LOG_ERROR("master flash bank '%s' does not exist", bank_name);
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
// save master bank name - use this to get settings later
|
||||
bank->driver_priv = strdup(bank_name);
|
||||
|
||||
bank->read_only = true;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ro_alias_erase(struct flash_bank *bank,
|
||||
unsigned int first, unsigned int last)
|
||||
{
|
||||
char *bank_name = bank->driver_priv;
|
||||
|
||||
LOG_ERROR("Erase of read-only flash alias refused. Use master flash bank '%s'",
|
||||
bank_name);
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static int ro_alias_write(struct flash_bank *bank, const uint8_t *buffer,
|
||||
uint32_t offset, uint32_t count)
|
||||
{
|
||||
char *bank_name = bank->driver_priv;
|
||||
|
||||
LOG_ERROR("Write to read-only flash alias refused. Use master flash bank '%s'",
|
||||
bank_name);
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
const struct flash_driver ro_alias_flash = {
|
||||
.name = "ro_alias",
|
||||
.flash_bank_command = ro_alias_bank_command,
|
||||
.erase = ro_alias_erase,
|
||||
.write = ro_alias_write,
|
||||
.read = virtual_flash_read,
|
||||
.probe = virtual_probe,
|
||||
.auto_probe = virtual_auto_probe,
|
||||
.erase_check = virtual_blank_check,
|
||||
.info = virtual_info,
|
||||
.free_driver_priv = virtual_flash_free_driver_priv,
|
||||
};
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
/*
|
||||
* The manufacturer's standard identification code list appears in JEP106.
|
||||
* Copyright (c) 2025 JEDEC. All rights reserved.
|
||||
* Copyright (c) 2026 JEDEC. All rights reserved.
|
||||
*
|
||||
* JEP106 is regularly updated. For the current manufacturer's standard
|
||||
* identification code list, please visit the JEDEC website at www.jedec.org .
|
||||
*/
|
||||
|
||||
/* This file is aligned to revision JEP106BM June 2025. */
|
||||
/* This file is aligned to revision JEP106BN January 2026. */
|
||||
|
||||
[0][0x01 - 1] = "AMD",
|
||||
[0][0x02 - 1] = "AMI",
|
||||
@@ -205,7 +205,7 @@
|
||||
[1][0x43 - 1] = "Suwa Electronics",
|
||||
[1][0x44 - 1] = "Transmeta",
|
||||
[1][0x45 - 1] = "Micron CMS",
|
||||
[1][0x46 - 1] = "American Computer & Digital Components Inc",
|
||||
[1][0x46 - 1] = "American Computer Digital Components",
|
||||
[1][0x47 - 1] = "Enhance 3000 Inc",
|
||||
[1][0x48 - 1] = "Tower Semiconductor",
|
||||
[1][0x49 - 1] = "CPU Design",
|
||||
@@ -1450,7 +1450,7 @@
|
||||
[11][0x34 - 1] = "Acacia Communications",
|
||||
[11][0x35 - 1] = "Beijinjinshengyihe Technology Co Ltd",
|
||||
[11][0x36 - 1] = "Zyzyx",
|
||||
[11][0x37 - 1] = "C-SKY Microsystems Co Ltd",
|
||||
[11][0x37 - 1] = "C-SKY Microsystems Co Ltd (XuanTie)",
|
||||
[11][0x38 - 1] = "Shenzhen Hystou Technology Co Ltd",
|
||||
[11][0x39 - 1] = "Syzexion",
|
||||
[11][0x3a - 1] = "Kembona",
|
||||
@@ -1900,7 +1900,7 @@
|
||||
[14][0x7c - 1] = "ForwardEdge ASIC",
|
||||
[14][0x7d - 1] = "Beijing Future Signet Technology Co Ltd",
|
||||
[14][0x7e - 1] = "Fine Made Microelectronics Group Co Ltd",
|
||||
[15][0x01 - 1] = "Changxin Memory Technology (Shanghai)",
|
||||
[15][0x01 - 1] = "CXSH",
|
||||
[15][0x02 - 1] = "Synconv",
|
||||
[15][0x03 - 1] = "MULTIUNIT",
|
||||
[15][0x04 - 1] = "Zero ASIC Corporation",
|
||||
@@ -2084,4 +2084,68 @@
|
||||
[16][0x38 - 1] = "Shanghai Yunsilicon Technology Co Ltd",
|
||||
[16][0x39 - 1] = "Shenzhen Wolongtai Technology Co Ltd.",
|
||||
[16][0x3a - 1] = "Vervesemi Microelectronics",
|
||||
[16][0x3b - 1] = "HRDWYR Ventures Private Limited",
|
||||
[16][0x3c - 1] = "ENE Technology Inc",
|
||||
[16][0x3d - 1] = "GOFATOO",
|
||||
[16][0x3e - 1] = "Shenzhen Jingchu Technology Co Ltd",
|
||||
[16][0x3f - 1] = "NEVETA",
|
||||
[16][0x40 - 1] = "RZX",
|
||||
[16][0x41 - 1] = "Shenzhen Zhongcheng Qingcong Technology Co",
|
||||
[16][0x42 - 1] = "Shenzhen Heyloo Electronic Technology Co",
|
||||
[16][0x43 - 1] = "Shenzhen Shanghaowang Electronic Technology",
|
||||
[16][0x44 - 1] = "Shanghai Qimingxin Semiconductor Technology",
|
||||
[16][0x45 - 1] = "Henan Great Wall Computer System Co Ltd",
|
||||
[16][0x46 - 1] = "Beijing Memsilicon Technology Co Ltd",
|
||||
[16][0x47 - 1] = "Openchip & Software Technologies S L",
|
||||
[16][0x48 - 1] = "FlashLeap Tech (Shenzhen) Co Ltd",
|
||||
[16][0x49 - 1] = "Shenzhen JinShanDe Technology Co Ltd",
|
||||
[16][0x4a - 1] = "RUIBOHU",
|
||||
[16][0x4b - 1] = "ETA Semiconductor Ltd",
|
||||
[16][0x4c - 1] = "L&T Semiconductor Technologies Limited",
|
||||
[16][0x4d - 1] = "RAYSMEM",
|
||||
[16][0x4e - 1] = "Sichuan Zhongzhao Yongye Semiconductor",
|
||||
[16][0x4f - 1] = "Shenzhen Ruiyuanchuangxin Technology",
|
||||
[16][0x50 - 1] = "CSSI South Africa (Pty) Ltd",
|
||||
[16][0x51 - 1] = "Jeju Semiconductor Corp",
|
||||
[16][0x52 - 1] = "Origin Code LLC",
|
||||
[16][0x53 - 1] = "Chengdu Masscore Microelectronics Tech",
|
||||
[16][0x54 - 1] = "Shenzhen Whalekom Technology Co Ltd",
|
||||
[16][0x55 - 1] = "femtoAI",
|
||||
[16][0x56 - 1] = "Shanghai Chip4Tao Technology Co Ltd",
|
||||
[16][0x57 - 1] = "Shenzhenshijimokkejiyouxiangongsi",
|
||||
[16][0x58 - 1] = "DEGUA",
|
||||
[16][0x59 - 1] = "TENGYIN CELESTIALSTORAGE",
|
||||
[16][0x5a - 1] = "Shenzhen Minder Semiconductor Co Ltd",
|
||||
[16][0x5b - 1] = "GUANGSUJIE",
|
||||
[16][0x5c - 1] = "HVLANYN Technology",
|
||||
[16][0x5d - 1] = "Theo End (Shenzhen) Computing Tech Co",
|
||||
[16][0x5e - 1] = "Shenzhen Heroje Electronics Co Ltd",
|
||||
[16][0x5f - 1] = "Guangdong Yuecun Microelectronics Co",
|
||||
[16][0x60 - 1] = "Foxin Technology",
|
||||
[16][0x61 - 1] = "JinTech Semiconductor Co Limited",
|
||||
[16][0x62 - 1] = "Shenzhen Hongred Information Technology Co",
|
||||
[16][0x63 - 1] = "ZST Inc",
|
||||
[16][0x64 - 1] = "Veris Danismanlik Limited Sirketi",
|
||||
[16][0x65 - 1] = "Starblaze",
|
||||
[16][0x66 - 1] = "Siptechx",
|
||||
[16][0x67 - 1] = "Djelec",
|
||||
[16][0x68 - 1] = "Ambarella Corporation",
|
||||
[16][0x69 - 1] = "SiliconX",
|
||||
[16][0x6a - 1] = "Shenzhen Tencent Computer System Co",
|
||||
[16][0x6b - 1] = "Shenzhen Econo Electronic Co Ltd (China)",
|
||||
[16][0x6c - 1] = "Pu Sl Technology (Shenzhen) Co Limited",
|
||||
[16][0x6d - 1] = "Shenzhen Kimviking Technology Co Ltd",
|
||||
[16][0x6e - 1] = "Shenzhen Touch Think Intelligence Co Ltd",
|
||||
[16][0x6f - 1] = "Beijing Institute of Open Source Chip",
|
||||
[16][0x70 - 1] = "BYTE International Co Ltd",
|
||||
[16][0x71 - 1] = "Shenzhen ITZR Technology Co Ltd",
|
||||
[16][0x72 - 1] = "Centre Development Advanced Computing",
|
||||
[16][0x73 - 1] = "Overlord Labs",
|
||||
[16][0x74 - 1] = "Shenzhen Chaocun Technology Co Ltd",
|
||||
[16][0x75 - 1] = "Shenzhen Yuqi Electronics Co Ltd",
|
||||
[16][0x76 - 1] = "Transsemi Miceoelectronics Co Ltd",
|
||||
[16][0x77 - 1] = "Pu Sl Technology (Shenzhen) Co Limited",
|
||||
[16][0x78 - 1] = "Shenzhen Xingjiachen Electronics Co Ltd",
|
||||
[16][0x79 - 1] = "Shenzhen Xingjiachen Electronics Co Ltd",
|
||||
[16][0x7a - 1] = "Shenyang Lianxin Chuangxiang Technology",
|
||||
/* EOF */
|
||||
|
||||
@@ -24,24 +24,8 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef _DEBUG_FREE_SPACE_
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#if defined(HAVE_MALLINFO) || defined(HAVE_MALLINFO2)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#error "malloc.h is required to use --enable-malloc-logging"
|
||||
#endif
|
||||
|
||||
#ifdef __GLIBC__
|
||||
#if __GLIBC_PREREQ(2, 33)
|
||||
#define FORDBLKS_FORMAT " %zu"
|
||||
#else
|
||||
/* glibc older than 2.33 (2021-02-01) use mallinfo(). Overwrite it */
|
||||
#define mallinfo2 mallinfo
|
||||
#define FORDBLKS_FORMAT " %d"
|
||||
#endif
|
||||
#else
|
||||
#error "GNU glibc is required to use --enable-malloc-logging"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int debug_level = LOG_LVL_INFO;
|
||||
@@ -53,16 +37,17 @@ static int64_t last_time;
|
||||
|
||||
static int64_t start;
|
||||
|
||||
static const char * const log_strings[6] = {
|
||||
static const char * const log_strings[7] = {
|
||||
"User : ",
|
||||
"Error: ",
|
||||
"Warn : ", /* want a space after each colon, all same width, colons aligned */
|
||||
"Info : ",
|
||||
"Debug: ",
|
||||
"Debug: "
|
||||
"Debug: ",
|
||||
"Debug: ", /* corresponds to LOG_LVL_DEBUG_USB */
|
||||
};
|
||||
|
||||
static int count;
|
||||
static unsigned int count;
|
||||
|
||||
/* forward the log to the listeners */
|
||||
static void log_forward(const char *file, unsigned int line, const char *function, const char *string)
|
||||
@@ -77,6 +62,32 @@ static void log_forward(const char *file, unsigned int line, const char *functio
|
||||
}
|
||||
}
|
||||
|
||||
// whitespace + SIZE_MAX + zero termination
|
||||
#define MEM_STR_LEN (1 + 21 + 1)
|
||||
static void get_free_memory_space(char *s)
|
||||
{
|
||||
#if defined(HAVE_MALLINFO2)
|
||||
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_MALLOC)) {
|
||||
struct mallinfo2 info = mallinfo2();
|
||||
snprintf(s, MEM_STR_LEN, " %zu", info.fordblks);
|
||||
return;
|
||||
}
|
||||
#elif defined(HAVE_MALLINFO)
|
||||
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_MALLOC)) {
|
||||
struct mallinfo info = mallinfo();
|
||||
#if IS_CYGWIN
|
||||
snprintf(s, MEM_STR_LEN, " %zu", info.fordblks);
|
||||
#else
|
||||
snprintf(s, MEM_STR_LEN, " %d", info.fordblks);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// empty string
|
||||
*s = 0;
|
||||
}
|
||||
|
||||
/* The log_puts() serves two somewhat different goals:
|
||||
*
|
||||
* - logging
|
||||
@@ -116,18 +127,13 @@ static void log_puts(enum log_levels level,
|
||||
if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
|
||||
/* print with count and time information */
|
||||
int64_t t = timeval_ms() - start;
|
||||
#ifdef _DEBUG_FREE_SPACE_
|
||||
struct mallinfo2 info = mallinfo2();
|
||||
#endif
|
||||
fprintf(log_output, "%s%d %" PRId64 " %s:%d %s()"
|
||||
#ifdef _DEBUG_FREE_SPACE_
|
||||
FORDBLKS_FORMAT
|
||||
#endif
|
||||
": %s", log_strings[level + 1], count, t, file, line, function,
|
||||
#ifdef _DEBUG_FREE_SPACE_
|
||||
info.fordblks,
|
||||
#endif
|
||||
string);
|
||||
|
||||
char free_memory[MEM_STR_LEN];
|
||||
get_free_memory_space(free_memory);
|
||||
|
||||
fprintf(log_output, "%s%u %" PRId64 " %s:%d %s()%s: %s",
|
||||
log_strings[level + 1], count, t, file, line, function,
|
||||
free_memory, string);
|
||||
} else {
|
||||
/* if we are using gdb through pipes then we do not want any output
|
||||
* to the pipe otherwise we get repeated strings */
|
||||
@@ -152,10 +158,11 @@ void log_printf(enum log_levels level,
|
||||
char *string;
|
||||
va_list ap;
|
||||
|
||||
count++;
|
||||
if (level > debug_level)
|
||||
return;
|
||||
|
||||
count++;
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
string = alloc_vprintf(format, ap);
|
||||
@@ -172,11 +179,11 @@ void log_vprintf_lf(enum log_levels level, const char *file, unsigned int line,
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
count++;
|
||||
|
||||
if (level > debug_level)
|
||||
return;
|
||||
|
||||
count++;
|
||||
|
||||
tmp = alloc_vprintf(format, args);
|
||||
|
||||
if (!tmp)
|
||||
@@ -212,8 +219,8 @@ COMMAND_HANDLER(handle_debug_level_command)
|
||||
} else if (CMD_ARGC == 1) {
|
||||
int new_level;
|
||||
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], new_level);
|
||||
if ((new_level > LOG_LVL_DEBUG_IO) || (new_level < LOG_LVL_SILENT)) {
|
||||
command_print(CMD, "level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG_IO);
|
||||
if (new_level > LOG_LVL_DEBUG_USB || new_level < LOG_LVL_SILENT) {
|
||||
command_print(CMD, "level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG_USB);
|
||||
return ERROR_COMMAND_ARGUMENT_INVALID;
|
||||
}
|
||||
debug_level = new_level;
|
||||
@@ -523,7 +530,7 @@ void log_socket_error(const char *socket_desc)
|
||||
const char *find_nonprint_char(const char *buf, unsigned int buf_len)
|
||||
{
|
||||
for (unsigned int i = 0; i < buf_len; i++) {
|
||||
if (!isprint(buf[i]))
|
||||
if (!isprint((unsigned char)buf[i]))
|
||||
return buf + i;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
@@ -37,6 +37,13 @@
|
||||
* LOG_LVL_INFO - state information, etc.
|
||||
* LOG_LVL_DEBUG - debug statements, execution trace
|
||||
* LOG_LVL_DEBUG_IO - verbose debug, low-level I/O trace
|
||||
* LOG_LVL_DEBUG_USB - verbose USB trace
|
||||
* In the past this corresponded to build configuration options
|
||||
--enable-verbose and --enable-verbose-usb-comms.
|
||||
* LOG_LVL_DEBUG_MALLOC - log messages will include the amount of free heap space
|
||||
* maintained by malloc in its free list, if mallinfo is available.
|
||||
* In the past this corresponded to build configuration
|
||||
* option --enable-malloc-logging.
|
||||
*/
|
||||
enum log_levels {
|
||||
LOG_LVL_SILENT = -3,
|
||||
@@ -47,6 +54,10 @@ enum log_levels {
|
||||
LOG_LVL_INFO = 2,
|
||||
LOG_LVL_DEBUG = 3,
|
||||
LOG_LVL_DEBUG_IO = 4,
|
||||
// LOG_LVL_DEBUG_USB and LOG_LVL_DEBUG_MALLOC have the same value at the moment.
|
||||
// In the future, these logging categories will be individually switchable.
|
||||
LOG_LVL_DEBUG_USB = 5,
|
||||
LOG_LVL_DEBUG_MALLOC = 5,
|
||||
};
|
||||
|
||||
void log_printf(enum log_levels level, const char *file, unsigned int line,
|
||||
@@ -100,10 +111,12 @@ extern int debug_level;
|
||||
|
||||
#define LOG_LEVEL_IS(FOO) ((debug_level) >= (FOO))
|
||||
|
||||
#define LOG_DEBUG_USB(expr, ...) LOG_CUSTOM_LEVEL(LOG_LVL_DEBUG_USB, expr, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_DEBUG_IO(expr ...) \
|
||||
do { \
|
||||
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) \
|
||||
log_printf_lf(LOG_LVL_DEBUG, \
|
||||
log_printf_lf(LOG_LVL_DEBUG_IO, \
|
||||
__FILE__, __LINE__, __func__, \
|
||||
expr); \
|
||||
} while (0)
|
||||
|
||||
@@ -47,7 +47,7 @@ proc find {filename} {
|
||||
return $t
|
||||
}
|
||||
|
||||
foreach vendor {nordic ti sifive st} {
|
||||
foreach vendor {gigadevice nordic sifive st ti} {
|
||||
# - path/to/a/certain/config_file
|
||||
# replaced either with
|
||||
# - path/to/a/certain/${vendor}/config_file
|
||||
|
||||
@@ -970,7 +970,7 @@ COMMAND_HANDLER(adapter_gpio_config_handler)
|
||||
while (i < CMD_ARGC) {
|
||||
LOG_DEBUG("Processing %s", CMD_ARGV[i]);
|
||||
|
||||
if (isdigit(*CMD_ARGV[i])) {
|
||||
if (isdigit((unsigned char)*CMD_ARGV[i])) {
|
||||
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[i], gpio_config->gpio_num);
|
||||
++i;
|
||||
continue;
|
||||
|
||||
@@ -129,6 +129,8 @@ const char *adapter_gpio_get_name(enum adapter_gpio_config_index idx);
|
||||
*/
|
||||
const struct adapter_gpio_config *adapter_gpio_get_config(void);
|
||||
|
||||
extern struct adapter_driver *adapter_driver;
|
||||
|
||||
#define ADAPTER_GPIO_NOT_SET UINT_MAX
|
||||
|
||||
#endif /* OPENOCD_JTAG_ADAPTER_H */
|
||||
|
||||
@@ -115,8 +115,6 @@ struct jtag_event_callback {
|
||||
/* callbacks to inform high-level handlers about JTAG state changes */
|
||||
static struct jtag_event_callback *jtag_event_callbacks;
|
||||
|
||||
extern struct adapter_driver *adapter_driver;
|
||||
|
||||
void jtag_set_flush_queue_sleep(int ms)
|
||||
{
|
||||
jtag_flush_queue_sleep = ms;
|
||||
|
||||
@@ -76,9 +76,7 @@ static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length);
|
||||
/* helper functions */
|
||||
static int armjtagew_get_version_info(void);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
static void armjtagew_debug_buffer(uint8_t *buffer, int length);
|
||||
#endif
|
||||
|
||||
static struct armjtagew *armjtagew_handle;
|
||||
|
||||
@@ -127,9 +125,8 @@ static int armjtagew_execute_queue(struct jtag_command *cmd_queue)
|
||||
scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
|
||||
LOG_DEBUG_IO("scan input, length = %d", scan_size);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
armjtagew_debug_buffer(buffer, (scan_size + 7) / 8);
|
||||
#endif
|
||||
|
||||
type = jtag_scan_type(cmd->cmd.scan);
|
||||
armjtagew_scan(cmd->cmd.scan->ir_scan,
|
||||
type, buffer,
|
||||
@@ -641,9 +638,7 @@ static int armjtagew_tap_execute(void)
|
||||
|
||||
LOG_DEBUG_IO("pending scan result, length = %d", length);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
armjtagew_debug_buffer(buffer, byte_length);
|
||||
#endif
|
||||
|
||||
if (jtag_read_buffer(buffer, command) != ERROR_OK) {
|
||||
armjtagew_tap_init();
|
||||
@@ -743,9 +738,8 @@ static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length)
|
||||
|
||||
LOG_DEBUG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length, result);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
armjtagew_debug_buffer(usb_out_buffer, out_length);
|
||||
#endif
|
||||
|
||||
if (result != ERROR_OK)
|
||||
return -1;
|
||||
return transferred;
|
||||
@@ -760,29 +754,29 @@ static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length)
|
||||
|
||||
LOG_DEBUG_IO("armjtagew_usb_read, result = %d", result);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
armjtagew_debug_buffer(usb_in_buffer, result);
|
||||
#endif
|
||||
|
||||
if (result != ERROR_OK)
|
||||
return -1;
|
||||
return transferred;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
#define BYTES_PER_LINE 16
|
||||
|
||||
static void armjtagew_debug_buffer(uint8_t *buffer, int length)
|
||||
{
|
||||
if (!LOG_LEVEL_IS(LOG_LVL_DEBUG_USB))
|
||||
return;
|
||||
|
||||
char line[8 + 3 * BYTES_PER_LINE + 1];
|
||||
|
||||
for (int i = 0; i < length; i += BYTES_PER_LINE) {
|
||||
int n = snprintf(line, 9, "%04x", i);
|
||||
for (int j = i; j < i + BYTES_PER_LINE && j < length; j++)
|
||||
n += snprintf(line + n, 4, " %02x", buffer[j]);
|
||||
LOG_DEBUG("%s", line);
|
||||
LOG_DEBUG_USB("%s", line);
|
||||
|
||||
/* Prevent GDB timeout (writing to log might take some time) */
|
||||
keep_alive();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -504,7 +504,7 @@ static int jaylink_log_handler(const struct jaylink_context *ctx,
|
||||
tmp = LOG_LVL_DEBUG;
|
||||
break;
|
||||
case JAYLINK_LOG_LEVEL_DEBUG_IO:
|
||||
tmp = LOG_LVL_DEBUG_IO;
|
||||
tmp = LOG_LVL_DEBUG_USB;
|
||||
break;
|
||||
default:
|
||||
tmp = LOG_LVL_WARNING;
|
||||
|
||||
@@ -134,10 +134,7 @@ static int opendous_usb_read(struct opendous_jtag *opendous_jtag);
|
||||
|
||||
/* helper functions */
|
||||
static int opendous_get_version_info(void);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
static void opendous_debug_buffer(uint8_t *buffer, int length);
|
||||
#endif
|
||||
|
||||
static struct opendous_jtag *opendous_jtag_handle;
|
||||
|
||||
@@ -282,9 +279,8 @@ static int opendous_execute_queue(struct jtag_command *cmd_queue)
|
||||
scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
|
||||
LOG_DEBUG_IO("scan input, length = %d", scan_size);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
opendous_debug_buffer(buffer, (scan_size + 7) / 8);
|
||||
#endif
|
||||
|
||||
type = jtag_scan_type(cmd->cmd.scan);
|
||||
opendous_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan);
|
||||
break;
|
||||
@@ -604,10 +600,7 @@ int opendous_tap_execute(void)
|
||||
int byte_length;
|
||||
int i, j;
|
||||
int result;
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
int byte_length_out;
|
||||
#endif
|
||||
|
||||
if (tap_length > 0) {
|
||||
|
||||
@@ -615,10 +608,8 @@ int opendous_tap_execute(void)
|
||||
/* LOG_INFO("OPENDOUS tap execute %d",tap_length); */
|
||||
byte_length = (tap_length + 3) / 4;
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
byte_length_out = (tap_length + 7) / 8;
|
||||
LOG_DEBUG("opendous is sending %d bytes", byte_length);
|
||||
#endif
|
||||
LOG_DEBUG_USB("opendous is sending %d bytes", byte_length);
|
||||
|
||||
for (j = 0, i = 0; j < byte_length;) {
|
||||
|
||||
@@ -647,10 +638,8 @@ int opendous_tap_execute(void)
|
||||
j += transmit;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
LOG_DEBUG("opendous tap result %d", byte_length_out);
|
||||
LOG_DEBUG_USB("opendous tap result %d", byte_length_out);
|
||||
opendous_debug_buffer(tdo_buffer, byte_length_out);
|
||||
#endif
|
||||
|
||||
/* LOG_INFO("eStick tap execute %d",tap_length); */
|
||||
for (i = 0; i < pending_scan_results_length; i++) {
|
||||
@@ -666,9 +655,7 @@ int opendous_tap_execute(void)
|
||||
|
||||
LOG_DEBUG_IO("pending scan result, length = %d", length);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
opendous_debug_buffer(buffer, byte_length_out);
|
||||
#endif
|
||||
|
||||
if (jtag_read_buffer(buffer, command) != ERROR_OK) {
|
||||
opendous_tap_init();
|
||||
@@ -739,9 +726,8 @@ int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
LOG_DEBUG("USB write begin");
|
||||
#endif
|
||||
LOG_DEBUG_USB("USB write begin");
|
||||
|
||||
if (opendous_probe->CONTROL_TRANSFER) {
|
||||
result = jtag_libusb_control_transfer(opendous_jtag->usb_handle,
|
||||
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
|
||||
@@ -754,15 +740,13 @@ int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length)
|
||||
jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT,
|
||||
(char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT, &result);
|
||||
}
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
LOG_DEBUG("USB write end: %d bytes", result);
|
||||
#endif
|
||||
|
||||
LOG_DEBUG_USB("USB write end: %d bytes", result);
|
||||
|
||||
LOG_DEBUG_IO("opendous_usb_write, out_length = %d, result = %d", out_length, result);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
opendous_debug_buffer(usb_out_buffer, out_length);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -771,9 +755,8 @@ int opendous_usb_read(struct opendous_jtag *opendous_jtag)
|
||||
{
|
||||
int transferred;
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
LOG_DEBUG("USB read begin");
|
||||
#endif
|
||||
LOG_DEBUG_USB("USB read begin");
|
||||
|
||||
int result;
|
||||
if (opendous_probe->CONTROL_TRANSFER) {
|
||||
result = jtag_libusb_control_transfer(opendous_jtag->usb_handle,
|
||||
@@ -787,29 +770,29 @@ int opendous_usb_read(struct opendous_jtag *opendous_jtag)
|
||||
jtag_libusb_bulk_read(opendous_jtag->usb_handle, OPENDOUS_READ_ENDPOINT,
|
||||
(char *)usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT, &result);
|
||||
}
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
LOG_DEBUG("USB read end: %d bytes", result);
|
||||
#endif
|
||||
|
||||
LOG_DEBUG_USB("USB read end: %d bytes", result);
|
||||
|
||||
LOG_DEBUG_IO("opendous_usb_read, result = %d", result);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
opendous_debug_buffer(usb_in_buffer, result);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
#define BYTES_PER_LINE 16
|
||||
|
||||
void opendous_debug_buffer(uint8_t *buffer, int length)
|
||||
{
|
||||
if (!LOG_LEVEL_IS(LOG_LVL_DEBUG_USB))
|
||||
return;
|
||||
|
||||
char line[8 + 3 * BYTES_PER_LINE + 1];
|
||||
|
||||
for (int i = 0; i < length; i += BYTES_PER_LINE) {
|
||||
int n = snprintf(line, 9, "%04x", i);
|
||||
for (int j = i; j < i + BYTES_PER_LINE && j < length; j++)
|
||||
n += snprintf(line + n, 4, " %02x", buffer[j]);
|
||||
LOG_DEBUG("%s", line);
|
||||
LOG_DEBUG_USB("%s", line);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -119,8 +119,6 @@ static const uint16_t cy7c65215_pids[] = {0x0007, 0};
|
||||
|
||||
static unsigned int ep_in, ep_out;
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
|
||||
#define DEBUG_TYPE_READ 0
|
||||
#define DEBUG_TYPE_WRITE 1
|
||||
#define DEBUG_TYPE_OCD_READ 2
|
||||
@@ -129,6 +127,9 @@ static unsigned int ep_in, ep_out;
|
||||
#define LINE_LEN 16
|
||||
static void openjtag_debug_buffer(uint8_t *buffer, int length, uint8_t type)
|
||||
{
|
||||
if (!LOG_LEVEL_IS(LOG_LVL_DEBUG_USB))
|
||||
return;
|
||||
|
||||
char line[128];
|
||||
char s[4];
|
||||
int i;
|
||||
@@ -149,7 +150,7 @@ static void openjtag_debug_buffer(uint8_t *buffer, int length, uint8_t type)
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_DEBUG("%s", line);
|
||||
LOG_DEBUG_USB("%s", line);
|
||||
|
||||
for (i = 0; i < length; i += LINE_LEN) {
|
||||
switch (type) {
|
||||
@@ -171,13 +172,11 @@ static void openjtag_debug_buffer(uint8_t *buffer, int length, uint8_t type)
|
||||
sprintf(s, " %02x", buffer[j]);
|
||||
strcat(line, s);
|
||||
}
|
||||
LOG_DEBUG("%s", line);
|
||||
LOG_DEBUG_USB("%s", line);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int8_t openjtag_get_tap_state(int8_t state)
|
||||
{
|
||||
|
||||
@@ -207,9 +206,8 @@ static int openjtag_buf_write_standard(
|
||||
uint8_t *buf, int size, uint32_t *bytes_written)
|
||||
{
|
||||
int retval;
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
|
||||
openjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);
|
||||
#endif
|
||||
|
||||
retval = ftdi_write_data(&ftdic, buf, size);
|
||||
if (retval < 0) {
|
||||
@@ -228,9 +226,7 @@ static int openjtag_buf_write_cy7c65215(
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
openjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);
|
||||
#endif
|
||||
|
||||
if (size == 0) {
|
||||
*bytes_written = 0;
|
||||
@@ -287,9 +283,7 @@ static int openjtag_buf_read_standard(
|
||||
*bytes_read += retval;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);
|
||||
#endif
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -320,9 +314,7 @@ static int openjtag_buf_read_cy7c65215(
|
||||
*bytes_read = ret;
|
||||
|
||||
out:
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);
|
||||
#endif
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -585,10 +577,9 @@ static int openjtag_execute_tap_queue(void)
|
||||
count++;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
openjtag_debug_buffer(buffer,
|
||||
DIV_ROUND_UP(openjtag_scan_result_buffer[res_count].bits, 8), DEBUG_TYPE_OCD_READ);
|
||||
#endif
|
||||
|
||||
jtag_read_buffer(buffer, openjtag_scan_result_buffer[res_count].command);
|
||||
|
||||
free(openjtag_scan_result_buffer[res_count].buffer);
|
||||
@@ -725,9 +716,8 @@ static void openjtag_execute_scan(struct jtag_command *cmd)
|
||||
tap_set_end_state(cmd->cmd.scan->end_state);
|
||||
scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
openjtag_debug_buffer(buffer, (scan_size + 7) / 8, DEBUG_TYPE_BUFFER);
|
||||
#endif
|
||||
|
||||
/* set state */
|
||||
old_state = tap_get_end_state();
|
||||
openjtag_set_state(cmd->cmd.scan->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
|
||||
|
||||
@@ -451,7 +451,7 @@ static struct bitq_interface presto_bitq = {
|
||||
|
||||
static int presto_adapter_khz(int khz, int *jtag_speed)
|
||||
{
|
||||
if (khz < 0) {
|
||||
if (khz <= 0) {
|
||||
*jtag_speed = 0;
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
@@ -126,17 +126,17 @@ static int icdi_send_packet(void *handle, int len)
|
||||
|
||||
len += sprintf(&h->write_buffer[len], PACKET_END "%02x", cksum);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
char buffer[50];
|
||||
char ch = h->write_buffer[1];
|
||||
if (ch == 'x' || ch == 'X')
|
||||
LOG_DEBUG("writing packet: <binary>");
|
||||
else {
|
||||
memcpy(buffer, h->write_buffer, len >= 50 ? 50-1 : len);
|
||||
buffer[len] = 0;
|
||||
LOG_DEBUG("writing packet: %s", buffer);
|
||||
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_USB)) {
|
||||
char buffer[50];
|
||||
char ch = h->write_buffer[1];
|
||||
if (ch == 'x' || ch == 'X') {
|
||||
LOG_DEBUG_USB("writing packet: <binary>");
|
||||
} else {
|
||||
memcpy(buffer, h->write_buffer, len >= 50 ? 50 - 1 : len);
|
||||
buffer[len] = 0;
|
||||
LOG_DEBUG_USB("writing packet: %s", buffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
|
||||
@@ -155,9 +155,7 @@ static int icdi_send_packet(void *handle, int len)
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
LOG_DEBUG("received reply: '%c' : count %d", h->read_buffer[0], transferred);
|
||||
#endif
|
||||
LOG_DEBUG_USB("received reply: '%c' : count %d", h->read_buffer[0], transferred);
|
||||
|
||||
if (h->read_buffer[0] == '-') {
|
||||
LOG_DEBUG("Resending packet %d", ++retry);
|
||||
@@ -182,9 +180,7 @@ static int icdi_send_packet(void *handle, int len)
|
||||
result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer + h->read_count,
|
||||
h->max_packet - h->read_count, &transferred, ICDI_READ_TIMEOUT);
|
||||
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
LOG_DEBUG("received data: count %d", transferred);
|
||||
#endif
|
||||
LOG_DEBUG_USB("received data: count %d", transferred);
|
||||
|
||||
/* check for errors but retry for timeout */
|
||||
if (result != 0) {
|
||||
|
||||
@@ -2175,12 +2175,10 @@ static int ulink_init(void)
|
||||
ulink_handle = NULL;
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
#ifdef _DEBUG_USB_COMMS_
|
||||
else {
|
||||
/* Successfully received Bulk IN packet -> continue */
|
||||
LOG_INFO("Recovered from lost Bulk IN packet");
|
||||
LOG_DEBUG_USB("Recovered from lost Bulk IN packet");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
ulink_clear_queue(ulink_handle);
|
||||
|
||||
|
||||
@@ -12,13 +12,12 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "adapter.h"
|
||||
#include "interface.h"
|
||||
#include "swim.h"
|
||||
#include <helper/command.h>
|
||||
#include <transport/transport.h>
|
||||
|
||||
extern struct adapter_driver *adapter_driver;
|
||||
|
||||
int swim_system_reset(void)
|
||||
{
|
||||
assert(adapter_driver->swim_ops);
|
||||
|
||||
@@ -82,7 +82,8 @@ static int efinix_read_bit_file(struct raw_bit_file *bit_file, const char *filen
|
||||
return ERROR_PLD_FILE_LOAD_FAILED;
|
||||
}
|
||||
|
||||
if (!isxdigit(buffer[0]) || !isxdigit(buffer[1])) {
|
||||
if (!isxdigit((unsigned char)buffer[0]) ||
|
||||
!isxdigit((unsigned char)buffer[1])) {
|
||||
fclose(input_file);
|
||||
free(bit_file->data);
|
||||
bit_file->data = NULL;
|
||||
|
||||
@@ -57,7 +57,8 @@ static int gatemate_read_cfg_line(struct gatemate_bit_file *bit_file, const char
|
||||
} else if (line_buffer[idx] == 0) {
|
||||
break;
|
||||
} else if (idx + 1 < nread) {
|
||||
if (isxdigit(line_buffer[idx]) && isxdigit(line_buffer[idx + 1])) {
|
||||
if (isxdigit((unsigned char)line_buffer[idx]) &&
|
||||
isxdigit((unsigned char)line_buffer[idx + 1])) {
|
||||
uint8_t byte;
|
||||
unhexify(&byte, line_buffer + idx, 2);
|
||||
int retval = gatemate_add_byte_to_bitfile(bit_file, byte);
|
||||
@@ -138,11 +139,11 @@ static int gatemate_read_cfg_file(struct gatemate_bit_file *bit_file, const char
|
||||
|
||||
static int gatemate_read_file(struct gatemate_bit_file *bit_file, const char *filename)
|
||||
{
|
||||
memset(bit_file, 0, sizeof(struct gatemate_bit_file));
|
||||
|
||||
if (!filename || !bit_file)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
memset(bit_file, 0, sizeof(struct gatemate_bit_file));
|
||||
|
||||
/* check if binary .bit or ascii .cfg */
|
||||
const char *file_suffix_pos = strrchr(filename, '.');
|
||||
if (!file_suffix_pos) {
|
||||
|
||||
@@ -172,11 +172,11 @@ static int gowin_read_fs_file(struct gowin_bit_file *bit_file, const char *filen
|
||||
|
||||
static int gowin_read_file(struct gowin_bit_file *bit_file, const char *filename, bool *is_fs)
|
||||
{
|
||||
memset(bit_file, 0, sizeof(struct gowin_bit_file));
|
||||
|
||||
if (!filename || !bit_file)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
memset(bit_file, 0, sizeof(struct gowin_bit_file));
|
||||
|
||||
const char *file_suffix_pos = strrchr(filename, '.');
|
||||
if (!file_suffix_pos) {
|
||||
LOG_ERROR("Unable to detect filename suffix");
|
||||
|
||||
@@ -94,12 +94,13 @@ static int hwthread_update_threads(struct rtos *rtos)
|
||||
struct target_list *head;
|
||||
struct target *target;
|
||||
int64_t current_thread = 0;
|
||||
int64_t current_threadid = rtos->current_threadid; /* thread selected by GDB */
|
||||
int64_t current_threadid;
|
||||
enum target_debug_reason current_reason = DBG_REASON_UNDEFINED;
|
||||
|
||||
if (!rtos)
|
||||
return -1;
|
||||
|
||||
current_threadid = rtos->current_threadid; /* thread selected by GDB */
|
||||
target = rtos->target;
|
||||
|
||||
/* wipe out previous thread details if any */
|
||||
|
||||
@@ -2004,52 +2004,67 @@ static int gdb_memory_map(struct connection *connection,
|
||||
"length=\"" TARGET_ADDR_FMT "\"/>\n",
|
||||
ram_start, p->base - ram_start);
|
||||
|
||||
/* Report adjacent groups of same-size sectors. So for
|
||||
* example top boot CFI flash will list an initial region
|
||||
* with several large sectors (maybe 128KB) and several
|
||||
* smaller ones at the end (maybe 32KB). STR7 will have
|
||||
* regions with 8KB, 32KB, and 64KB sectors; etc.
|
||||
*/
|
||||
for (unsigned int j = 0; j < p->num_sectors; j++) {
|
||||
|
||||
/* Maybe start a new group of sectors. */
|
||||
if (sector_size == 0) {
|
||||
if (p->sectors[j].offset + p->sectors[j].size > p->size) {
|
||||
LOG_WARNING("The flash sector at offset 0x%08" PRIx32
|
||||
" overflows the end of %s bank.",
|
||||
p->sectors[j].offset, p->name);
|
||||
LOG_WARNING("The rest of bank will not show in gdb memory map.");
|
||||
break;
|
||||
}
|
||||
target_addr_t start;
|
||||
start = p->base + p->sectors[j].offset;
|
||||
if (p->read_only) {
|
||||
xml_printf(&retval, &xml, &pos, &size,
|
||||
"<memory type=\"rom\" start=\"" TARGET_ADDR_FMT "\" "
|
||||
"length=\"0x%x\"/>\n",
|
||||
p->base, p->size);
|
||||
} else {
|
||||
if (p->num_sectors == 0) {
|
||||
xml_printf(&retval, &xml, &pos, &size,
|
||||
"<memory type=\"flash\" "
|
||||
"start=\"" TARGET_ADDR_FMT "\" ",
|
||||
start);
|
||||
sector_size = p->sectors[j].size;
|
||||
group_len = sector_size;
|
||||
} else {
|
||||
group_len += sector_size; /* equal to p->sectors[j].size */
|
||||
"start=\"" TARGET_ADDR_FMT "\" "
|
||||
"length=\"0x%x\">"
|
||||
"<property name=\"blocksize\">0x%x</property>\n"
|
||||
"</memory>\n", p->base, p->size, p->size);
|
||||
}
|
||||
|
||||
/* Does this finish a group of sectors?
|
||||
* If not, continue an already-started group.
|
||||
/* Report adjacent groups of same-size sectors. So for
|
||||
* example top boot CFI flash will list an initial region
|
||||
* with several large sectors (maybe 128KB) and several
|
||||
* smaller ones at the end (maybe 32KB). STR7 will have
|
||||
* regions with 8KB, 32KB, and 64KB sectors; etc.
|
||||
*/
|
||||
if (j < p->num_sectors - 1
|
||||
&& p->sectors[j + 1].size == sector_size
|
||||
&& p->sectors[j + 1].offset == p->sectors[j].offset + sector_size
|
||||
&& p->sectors[j + 1].offset + p->sectors[j + 1].size <= p->size)
|
||||
continue;
|
||||
for (unsigned int j = 0; j < p->num_sectors; j++) {
|
||||
// Maybe start a new group of sectors
|
||||
if (sector_size == 0) {
|
||||
if (p->sectors[j].offset + p->sectors[j].size > p->size) {
|
||||
LOG_WARNING("The flash sector at offset 0x%08" PRIx32
|
||||
" overflows the end of %s bank.",
|
||||
p->sectors[j].offset, p->name);
|
||||
LOG_WARNING("The rest of bank will not show in gdb memory map.");
|
||||
break;
|
||||
}
|
||||
target_addr_t start;
|
||||
start = p->base + p->sectors[j].offset;
|
||||
xml_printf(&retval, &xml, &pos, &size,
|
||||
"<memory type=\"flash\" "
|
||||
"start=\"" TARGET_ADDR_FMT "\" ",
|
||||
start);
|
||||
sector_size = p->sectors[j].size;
|
||||
group_len = sector_size;
|
||||
} else {
|
||||
group_len += sector_size; /* equal to p->sectors[j].size */
|
||||
}
|
||||
|
||||
xml_printf(&retval, &xml, &pos, &size,
|
||||
"length=\"0x%x\">\n"
|
||||
"<property name=\"blocksize\">"
|
||||
"0x%x</property>\n"
|
||||
"</memory>\n",
|
||||
group_len,
|
||||
sector_size);
|
||||
sector_size = 0;
|
||||
/* Does this finish a group of sectors?
|
||||
* If not, continue an already-started group.
|
||||
*/
|
||||
if (j < p->num_sectors - 1
|
||||
&& p->sectors[j + 1].size == sector_size
|
||||
&& p->sectors[j + 1].offset == p->sectors[j].offset + sector_size
|
||||
&& p->sectors[j + 1].offset + p->sectors[j + 1].size <= p->size)
|
||||
continue;
|
||||
|
||||
xml_printf(&retval, &xml, &pos, &size,
|
||||
"length=\"0x%x\">\n"
|
||||
"<property name=\"blocksize\">"
|
||||
"0x%x</property>\n"
|
||||
"</memory>\n",
|
||||
group_len,
|
||||
sector_size);
|
||||
sector_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ram_start = p->base + p->size;
|
||||
@@ -3738,18 +3753,30 @@ static int gdb_input_inner(struct connection *connection)
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
/* DEPRECATED */
|
||||
/* packet supported only by smp target i.e cortex_a.c*/
|
||||
/* handle smp packet replying coreid played to gbd */
|
||||
gdb_read_smp_packet(connection, packet, packet_size);
|
||||
if (strncmp(packet, "jc", 2) == 0) {
|
||||
/* DEPRECATED */
|
||||
/* packet supported only by smp target i.e cortex_a.c*/
|
||||
/* handle smp packet replying coreid played to gbd */
|
||||
gdb_read_smp_packet(connection, packet, packet_size);
|
||||
} else {
|
||||
/* ignore unknown packets */
|
||||
LOG_DEBUG("ignoring 0x%2.2x packet", packet[0]);
|
||||
retval = gdb_put_packet(connection, "", 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
/* DEPRECATED */
|
||||
/* packet supported only by smp target i.e cortex_a.c */
|
||||
/* handle smp packet setting coreid to be played at next
|
||||
* resume to gdb */
|
||||
gdb_write_smp_packet(connection, packet, packet_size);
|
||||
if (strncmp(packet, "jc", 2) == 0) {
|
||||
/* DEPRECATED */
|
||||
/* packet supported only by smp target i.e cortex_a.c */
|
||||
/* handle smp packet setting coreid to be played at next
|
||||
* resume to gdb */
|
||||
gdb_read_smp_packet(connection, packet, packet_size);
|
||||
} else {
|
||||
/* ignore unknown packets */
|
||||
LOG_DEBUG("ignoring 0x%2.2x packet", packet[0]);
|
||||
retval = gdb_put_packet(connection, "", 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
@@ -3881,12 +3908,11 @@ static const struct service_driver gdb_service_driver = {
|
||||
|
||||
static int gdb_target_start(struct target *target, const char *port)
|
||||
{
|
||||
struct gdb_service *gdb_service;
|
||||
int ret;
|
||||
gdb_service = malloc(sizeof(struct gdb_service));
|
||||
|
||||
if (!gdb_service)
|
||||
return -ENOMEM;
|
||||
struct gdb_service *gdb_service = malloc(sizeof(struct gdb_service));
|
||||
if (!gdb_service) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
LOG_TARGET_INFO(target, "starting gdb server on %s", port);
|
||||
|
||||
@@ -3895,17 +3921,22 @@ static int gdb_target_start(struct target *target, const char *port)
|
||||
gdb_service->core[1] = -1;
|
||||
target->gdb_service = gdb_service;
|
||||
|
||||
ret = add_service(&gdb_service_driver, port, target->gdb_max_connections, gdb_service);
|
||||
/* initialize all targets gdb service with the same pointer */
|
||||
{
|
||||
struct target_list *head;
|
||||
foreach_smp_target(head, target->smp_targets) {
|
||||
struct target *curr = head->target;
|
||||
if (curr != target)
|
||||
curr->gdb_service = gdb_service;
|
||||
}
|
||||
int retval = add_service(&gdb_service_driver, port,
|
||||
target->gdb_max_connections, gdb_service);
|
||||
if (retval != ERROR_OK) {
|
||||
free(gdb_service);
|
||||
return retval;
|
||||
}
|
||||
return ret;
|
||||
|
||||
/* initialize all targets gdb service with the same pointer */
|
||||
struct target_list *head;
|
||||
foreach_smp_target(head, target->smp_targets) {
|
||||
struct target *curr = head->target;
|
||||
if (curr != target)
|
||||
curr->gdb_service = gdb_service;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int gdb_target_add_one(struct target *target)
|
||||
|
||||
@@ -193,6 +193,8 @@ static void free_service(struct service *c)
|
||||
{
|
||||
if (c->type == CONNECTION_PIPE && c->fd != -1)
|
||||
close(c->fd);
|
||||
if (c->type == CONNECTION_TCP && c->fd != -1)
|
||||
close_socket(c->fd);
|
||||
if (c->service_dtor)
|
||||
c->service_dtor(c);
|
||||
free(c->name);
|
||||
@@ -208,7 +210,11 @@ int add_service(const struct service_driver *driver, const char *port,
|
||||
struct hostent *hp;
|
||||
int so_reuseaddr_option = 1;
|
||||
|
||||
c = malloc(sizeof(struct service));
|
||||
c = calloc(1, sizeof(*c));
|
||||
if (!c) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
c->name = strdup(driver->name);
|
||||
c->port = strdup(port);
|
||||
@@ -223,6 +229,12 @@ int add_service(const struct service_driver *driver, const char *port,
|
||||
c->service_dtor = driver->service_dtor_handler;
|
||||
c->priv = priv;
|
||||
c->next = NULL;
|
||||
|
||||
if (!c->name || !c->port) {
|
||||
LOG_ERROR("Out of memory");
|
||||
goto error;
|
||||
}
|
||||
|
||||
long portnumber;
|
||||
if (strcmp(c->port, "pipe") == 0)
|
||||
c->type = CONNECTION_STDINOUT;
|
||||
@@ -242,8 +254,7 @@ int add_service(const struct service_driver *driver, const char *port,
|
||||
c->fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (c->fd == -1) {
|
||||
LOG_ERROR("error creating socket: %s", strerror(errno));
|
||||
free_service(c);
|
||||
return ERROR_FAIL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
setsockopt(c->fd,
|
||||
@@ -264,8 +275,7 @@ int add_service(const struct service_driver *driver, const char *port,
|
||||
if (!hp) {
|
||||
LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
|
||||
close_socket(c->fd);
|
||||
free_service(c);
|
||||
return ERROR_FAIL;
|
||||
goto error;
|
||||
}
|
||||
memcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);
|
||||
}
|
||||
@@ -274,8 +284,7 @@ int add_service(const struct service_driver *driver, const char *port,
|
||||
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
|
||||
LOG_ERROR("couldn't bind %s to socket on port %d: %s", c->name, c->portnumber, strerror(errno));
|
||||
close_socket(c->fd);
|
||||
free_service(c);
|
||||
return ERROR_FAIL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -294,8 +303,7 @@ int add_service(const struct service_driver *driver, const char *port,
|
||||
if (listen(c->fd, 1) == -1) {
|
||||
LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
|
||||
close_socket(c->fd);
|
||||
free_service(c);
|
||||
return ERROR_FAIL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr_in;
|
||||
@@ -323,15 +331,13 @@ int add_service(const struct service_driver *driver, const char *port,
|
||||
/* we currently do not support named pipes under win32
|
||||
* so exit openocd for now */
|
||||
LOG_ERROR("Named pipes currently not supported under this os");
|
||||
free_service(c);
|
||||
return ERROR_FAIL;
|
||||
goto error;
|
||||
#else
|
||||
/* Pipe we're reading from */
|
||||
c->fd = open(c->port, O_RDONLY | O_NONBLOCK);
|
||||
if (c->fd == -1) {
|
||||
LOG_ERROR("could not open %s", c->port);
|
||||
free_service(c);
|
||||
return ERROR_FAIL;
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -342,6 +348,14 @@ int add_service(const struct service_driver *driver, const char *port,
|
||||
*p = c;
|
||||
|
||||
return ERROR_OK;
|
||||
|
||||
error:
|
||||
// Only free() what has been locally allocated
|
||||
free(c->port);
|
||||
free(c->name);
|
||||
free(c);
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static void remove_connections(struct service *service)
|
||||
@@ -599,7 +613,6 @@ static void sig_handler(int sig)
|
||||
/* store only first signal that hits us */
|
||||
if (shutdown_openocd == CONTINUE_MAIN_LOOP) {
|
||||
shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;
|
||||
assert(sig >= SIG_ATOMIC_MIN && sig <= SIG_ATOMIC_MAX);
|
||||
last_signal = sig;
|
||||
LOG_DEBUG("Terminating on Signal %d", sig);
|
||||
} else
|
||||
@@ -769,6 +782,23 @@ COMMAND_HANDLER(handle_shutdown_command)
|
||||
return ERROR_COMMAND_CLOSE_CONNECTION;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_exit_command)
|
||||
{
|
||||
if (!tcl_is_from_tcl_session(CMD_CTX)
|
||||
&& !telnet_is_from_telnet_session(CMD_CTX)) {
|
||||
LOG_WARNING("DEPRECATED: 'exit' should only be used in telnet or Tcl "
|
||||
"sessions to close the session");
|
||||
LOG_WARNING("Did you mean 'shutdown'?");
|
||||
return command_run_line(CMD_CTX, "shutdown");
|
||||
}
|
||||
|
||||
if (CMD_ARGC != 0)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
/* Disconnect telnet / Tcl session */
|
||||
return ERROR_COMMAND_CLOSE_CONNECTION;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_poll_period_command)
|
||||
{
|
||||
if (CMD_ARGC == 0)
|
||||
@@ -805,6 +835,13 @@ static const struct command_registration server_command_handlers[] = {
|
||||
.usage = "",
|
||||
.help = "shut the server down",
|
||||
},
|
||||
{
|
||||
.name = "exit",
|
||||
.handler = &handle_exit_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.usage = "",
|
||||
.help = "exit (disconnect) telnet or Tcl session",
|
||||
},
|
||||
{
|
||||
.name = "poll_period",
|
||||
.handler = &handle_poll_period_command,
|
||||
|
||||
@@ -230,12 +230,22 @@ static int tcl_input(struct connection *connection)
|
||||
#undef ESTR
|
||||
} else {
|
||||
tclc->tc_line[tclc->tc_lineoffset-1] = '\0';
|
||||
command_run_line(connection->cmd_ctx, tclc->tc_line);
|
||||
retval = command_run_line(connection->cmd_ctx, tclc->tc_line);
|
||||
|
||||
if (retval == ERROR_COMMAND_CLOSE_CONNECTION) {
|
||||
/* "shutdown" or "exit" executed.
|
||||
* Send an empty response - just the response termination character.
|
||||
*/
|
||||
tcl_output(connection, "\x1a", 1);
|
||||
return ERROR_SERVER_REMOTE_CLOSED;
|
||||
}
|
||||
|
||||
result = Jim_GetString(Jim_GetResult(interp), &reslen);
|
||||
retval = tcl_output(connection, result, reslen);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
/* Always output ctrl-z as end of line to allow multiline results */
|
||||
|
||||
/* Signal the end of response by a termination character (ctrl-z) */
|
||||
tcl_output(connection, "\x1a", 1);
|
||||
}
|
||||
|
||||
@@ -284,6 +294,15 @@ int tcl_init(void)
|
||||
return add_service(&tcl_service_driver, tcl_port, CONNECTION_LIMIT_UNLIMITED, NULL);
|
||||
}
|
||||
|
||||
bool tcl_is_from_tcl_session(struct command_context *cmd_ctx)
|
||||
{
|
||||
if (!cmd_ctx->output_handler_priv)
|
||||
return false;
|
||||
|
||||
struct connection *conn = (struct connection *)cmd_ctx->output_handler_priv;
|
||||
return strcmp(conn->service->name, "tcl") == 0;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_tcl_port_command)
|
||||
{
|
||||
return CALL_COMMAND_HANDLER(server_pipe_command, &tcl_port);
|
||||
@@ -297,7 +316,7 @@ COMMAND_HANDLER(handle_tcl_notifications_command)
|
||||
if (CMD_CTX->output_handler_priv)
|
||||
connection = CMD_CTX->output_handler_priv;
|
||||
|
||||
if (connection && !strcmp(connection->service->name, "tcl")) {
|
||||
if (connection && tcl_is_from_tcl_session(CMD_CTX)) {
|
||||
tclc = connection->priv;
|
||||
return CALL_COMMAND_HANDLER(handle_command_parse_bool, &tclc->tc_notify, "Target Notification output ");
|
||||
} else {
|
||||
@@ -314,7 +333,7 @@ COMMAND_HANDLER(handle_tcl_trace_command)
|
||||
if (CMD_CTX->output_handler_priv)
|
||||
connection = CMD_CTX->output_handler_priv;
|
||||
|
||||
if (connection && !strcmp(connection->service->name, "tcl")) {
|
||||
if (connection && tcl_is_from_tcl_session(CMD_CTX)) {
|
||||
tclc = connection->priv;
|
||||
return CALL_COMMAND_HANDLER(handle_command_parse_bool, &tclc->tc_trace, "Target trace output ");
|
||||
} else {
|
||||
|
||||
@@ -12,5 +12,6 @@
|
||||
int tcl_init(void);
|
||||
int tcl_register_commands(struct command_context *cmd_ctx);
|
||||
void tcl_service_free(void);
|
||||
bool tcl_is_from_tcl_session(struct command_context *ctx);
|
||||
|
||||
#endif /* OPENOCD_SERVER_TCL_SERVER_H */
|
||||
|
||||
@@ -519,6 +519,7 @@ static int telnet_exec_line(struct connection *connection)
|
||||
t_con->prompt_visible = true;
|
||||
|
||||
if (retval == ERROR_COMMAND_CLOSE_CONNECTION)
|
||||
/* "shutdown" or "exit" executed. */
|
||||
return ERROR_SERVER_REMOTE_CLOSED;
|
||||
|
||||
/* the prompt is always placed at the line beginning */
|
||||
@@ -601,7 +602,8 @@ static void telnet_auto_complete(struct connection *connection)
|
||||
|
||||
/* user command position in the line, ignore leading spaces */
|
||||
size_t usr_cmd_pos = seq_start;
|
||||
while ((usr_cmd_pos < t_con->line_cursor) && isspace(t_con->line[usr_cmd_pos]))
|
||||
while ((usr_cmd_pos < t_con->line_cursor) &&
|
||||
isspace((unsigned char)t_con->line[usr_cmd_pos]))
|
||||
usr_cmd_pos++;
|
||||
|
||||
/* check user command length */
|
||||
@@ -615,9 +617,10 @@ static void telnet_auto_complete(struct connection *connection)
|
||||
* because info commands does not tolerate multiple spaces */
|
||||
size_t optimized_spaces = 0;
|
||||
char query[usr_cmd_len + 1];
|
||||
|
||||
for (size_t i = 0; i < usr_cmd_len; i++) {
|
||||
if ((i < usr_cmd_len - 1) && isspace(t_con->line[usr_cmd_pos + i])
|
||||
&& isspace(t_con->line[usr_cmd_pos + i + 1])) {
|
||||
if ((i < usr_cmd_len - 1) && isspace((unsigned char)t_con->line[usr_cmd_pos + i])
|
||||
&& isspace((unsigned char)t_con->line[usr_cmd_pos + i + 1])) {
|
||||
optimized_spaces++;
|
||||
continue;
|
||||
}
|
||||
@@ -967,16 +970,16 @@ int telnet_init(char *banner)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
bool telnet_is_from_telnet_session(struct command_context *cmd_ctx)
|
||||
{
|
||||
return cmd_ctx->output_handler == telnet_output;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_telnet_port_command)
|
||||
{
|
||||
return CALL_COMMAND_HANDLER(server_pipe_command, &telnet_port);
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_exit_command)
|
||||
{
|
||||
return ERROR_COMMAND_CLOSE_CONNECTION;
|
||||
}
|
||||
|
||||
static const struct command_registration telnet_subcommand_handlers[] = {
|
||||
{
|
||||
.name = "port",
|
||||
@@ -991,13 +994,6 @@ static const struct command_registration telnet_subcommand_handlers[] = {
|
||||
};
|
||||
|
||||
static const struct command_registration telnet_command_handlers[] = {
|
||||
{
|
||||
.name = "exit",
|
||||
.handler = handle_exit_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.usage = "",
|
||||
.help = "exit telnet session",
|
||||
},
|
||||
{
|
||||
.name = "telnet",
|
||||
.chain = telnet_subcommand_handlers,
|
||||
|
||||
@@ -54,5 +54,6 @@ struct telnet_service {
|
||||
int telnet_init(char *banner);
|
||||
int telnet_register_commands(struct command_context *command_context);
|
||||
void telnet_service_free(void);
|
||||
bool telnet_is_from_telnet_session(struct command_context *cmd_ctx);
|
||||
|
||||
#endif /* OPENOCD_SERVER_TELNET_SERVER_H */
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "target.h"
|
||||
#include "a64_disassembler.h"
|
||||
|
||||
#if HAVE_CAPSTONE
|
||||
#ifdef HAVE_CAPSTONE
|
||||
|
||||
#include <capstone.h>
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <helper/time_support.h>
|
||||
|
||||
#include <transport/transport.h>
|
||||
#include <jtag/adapter.h>
|
||||
#include <jtag/interface.h>
|
||||
|
||||
#include <jtag/swd.h>
|
||||
@@ -722,8 +723,6 @@ static const struct command_registration swd_handlers[] = {
|
||||
|
||||
static int swd_select(struct command_context *ctx)
|
||||
{
|
||||
/* FIXME: only place where global 'adapter_driver' is still needed */
|
||||
extern struct adapter_driver *adapter_driver;
|
||||
const struct swd_driver *swd = adapter_driver->swd_ops;
|
||||
int retval;
|
||||
|
||||
|
||||
@@ -323,7 +323,8 @@ int armv4_5_run_algorithm_inner(struct target *target,
|
||||
int arm_checksum_memory(struct target *target,
|
||||
target_addr_t address, uint32_t count, uint32_t *checksum);
|
||||
int arm_blank_check_memory(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value);
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked);
|
||||
|
||||
void arm_set_cpsr(struct arm *arm, uint32_t cpsr);
|
||||
struct reg *arm_reg_current(struct arm *arm, unsigned int regnum);
|
||||
|
||||
@@ -1112,7 +1112,9 @@ bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num)
|
||||
* This function checks the ID for each access port to find the requested Access Port type
|
||||
* It also calls dap_get_ap() to increment the AP refcount
|
||||
*/
|
||||
int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out)
|
||||
int dap_find_by_types_get_ap(struct adiv5_dap *dap,
|
||||
const enum ap_type *types_to_find, unsigned int num_types,
|
||||
struct adiv5_ap **ap_out)
|
||||
{
|
||||
if (is_adiv6(dap)) {
|
||||
/* TODO: scan the ROM table and detect the AP available */
|
||||
@@ -1120,6 +1122,8 @@ int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adi
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
assert(num_types > 0);
|
||||
|
||||
/* Maximum AP number is 255 since the SELECT register is 8 bits */
|
||||
for (unsigned int ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) {
|
||||
struct adiv5_ap *ap = dap_get_ap(dap, ap_num);
|
||||
@@ -1140,18 +1144,39 @@ int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adi
|
||||
/* Reading register for a non-existent AP should not cause an error,
|
||||
* but just to be sure, try to continue searching if an error does happen.
|
||||
*/
|
||||
if (retval == ERROR_OK && (id_val & AP_TYPE_MASK) == type_to_find) {
|
||||
LOG_DEBUG("Found %s at AP index: %d (IDR=0x%08" PRIX32 ")",
|
||||
ap_type_to_description(type_to_find),
|
||||
if (retval == ERROR_OK) {
|
||||
for (unsigned int i = 0; i < num_types; i++) {
|
||||
if ((id_val & AP_TYPE_MASK) == types_to_find[i]) {
|
||||
LOG_DEBUG("Found %s at AP index: %d (IDR=0x%08" PRIX32 ")",
|
||||
ap_type_to_description(types_to_find[i]),
|
||||
ap_num, id_val);
|
||||
|
||||
*ap_out = ap;
|
||||
return ERROR_OK;
|
||||
*ap_out = ap;
|
||||
return ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
dap_put_ap(ap);
|
||||
}
|
||||
|
||||
LOG_DEBUG("No %s found", ap_type_to_description(type_to_find));
|
||||
char *types_str = NULL;
|
||||
for (unsigned int i = 0; i < num_types; i++) {
|
||||
if (!types_str) {
|
||||
types_str = strdup(ap_type_to_description(types_to_find[i]));
|
||||
} else {
|
||||
char *next_str = alloc_printf("%s, %s", types_str,
|
||||
ap_type_to_description(types_to_find[i]));
|
||||
free(types_str);
|
||||
types_str = next_str;
|
||||
}
|
||||
if (!types_str) {
|
||||
LOG_ERROR("No memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("No %s found", types_str);
|
||||
free(types_str);
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
|
||||
@@ -738,11 +738,22 @@ int adiv6_dap_read_baseptr(struct command_invocation *cmd, struct adiv5_dap *dap
|
||||
/* test if ap_num is valid, based on current knowledge of dap */
|
||||
bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num);
|
||||
|
||||
/* Probe Access Ports to find a particular type. Increment AP refcount */
|
||||
int dap_find_get_ap(struct adiv5_dap *dap,
|
||||
enum ap_type type_to_find,
|
||||
/* Probe Access Ports to find any type from array.
|
||||
* Increment AP refcount */
|
||||
int dap_find_by_types_get_ap(struct adiv5_dap *dap,
|
||||
const enum ap_type *types_to_find,
|
||||
unsigned int num_types,
|
||||
struct adiv5_ap **ap_out);
|
||||
|
||||
/* Probe Access Ports to find a particular type. Increment AP refcount */
|
||||
static inline int dap_find_get_ap(struct adiv5_dap *dap,
|
||||
enum ap_type type_to_find,
|
||||
struct adiv5_ap **ap_out)
|
||||
{
|
||||
const enum ap_type types[1] = { type_to_find };
|
||||
return dap_find_by_types_get_ap(dap, types, 1, ap_out);
|
||||
}
|
||||
|
||||
/* Return AP with specified ap_num. Increment AP refcount */
|
||||
struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num);
|
||||
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
#include "helper/list.h"
|
||||
#include "helper/command.h"
|
||||
#include "transport/transport.h"
|
||||
#include "jtag/adapter.h"
|
||||
#include "jtag/interface.h"
|
||||
|
||||
static OOCD_LIST_HEAD(all_dap);
|
||||
|
||||
extern struct adapter_driver *adapter_driver;
|
||||
|
||||
/* DAP command support */
|
||||
struct arm_dap_object {
|
||||
struct list_head lh;
|
||||
@@ -412,6 +411,16 @@ err:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct adiv5_dap *target_to_dap(const struct target *target)
|
||||
{
|
||||
struct adiv5_private_config *pc = target->private_config;
|
||||
|
||||
if (!target->has_dap || !target->dap_configured || !pc)
|
||||
return NULL;
|
||||
|
||||
return pc->dap;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_dap_names)
|
||||
{
|
||||
if (CMD_ARGC != 0)
|
||||
@@ -432,12 +441,11 @@ COMMAND_HANDLER(handle_dap_init)
|
||||
COMMAND_HANDLER(handle_dap_info_command)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct arm *arm = target_to_arm(target);
|
||||
struct adiv5_dap *dap = arm->dap;
|
||||
struct adiv5_dap *dap = target_to_dap(target);
|
||||
uint64_t apsel;
|
||||
|
||||
if (!dap) {
|
||||
LOG_ERROR("DAP instance not available. Probably a HLA target...");
|
||||
command_print(CMD, "target %s has no DAP", target_name(target));
|
||||
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "arm_disassembler.h"
|
||||
#include <helper/log.h>
|
||||
|
||||
#if HAVE_CAPSTONE
|
||||
#ifdef HAVE_CAPSTONE
|
||||
#include <capstone.h>
|
||||
#endif
|
||||
|
||||
@@ -3019,7 +3019,7 @@ int arm_access_size(struct arm_instruction *instruction)
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_CAPSTONE
|
||||
#ifdef HAVE_CAPSTONE
|
||||
static void print_opcode(struct command_invocation *cmd, const cs_insn *insn)
|
||||
{
|
||||
uint32_t opcode = 0;
|
||||
|
||||
@@ -187,7 +187,7 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
|
||||
int thumb_evaluate_opcode(uint16_t opcode, uint32_t address,
|
||||
struct arm_instruction *instruction);
|
||||
int arm_access_size(struct arm_instruction *instruction);
|
||||
#if HAVE_CAPSTONE
|
||||
#ifdef HAVE_CAPSTONE
|
||||
int arm_disassemble(struct command_invocation *cmd, struct target *target,
|
||||
target_addr_t address, size_t count, bool thumb_mode);
|
||||
#endif
|
||||
|
||||
@@ -27,25 +27,31 @@ static uint32_t arm_shift(uint8_t shift, uint32_t rm,
|
||||
shift_amount &= 0xff;
|
||||
|
||||
if (shift == 0x0) { /* LSL */
|
||||
if ((shift_amount > 0) && (shift_amount <= 32)) {
|
||||
if (shift_amount > 0 && shift_amount < 32) {
|
||||
return_value = rm << shift_amount;
|
||||
*carry = rm >> (32 - shift_amount);
|
||||
} else if (shift_amount == 32) {
|
||||
return_value = 0x0;
|
||||
*carry = rm & 0x1;
|
||||
} else if (shift_amount > 32) {
|
||||
return_value = 0x0;
|
||||
*carry = 0x0;
|
||||
} else /* (shift_amount == 0) */
|
||||
return_value = rm;
|
||||
} else if (shift == 0x1) { /* LSR */
|
||||
if ((shift_amount > 0) && (shift_amount <= 32)) {
|
||||
if (shift_amount > 0 && shift_amount < 32) {
|
||||
return_value = rm >> shift_amount;
|
||||
*carry = (rm >> (shift_amount - 1)) & 1;
|
||||
} else if (shift_amount == 32) {
|
||||
return_value = 0x0;
|
||||
*carry = (rm >> 31) & 0x1;
|
||||
} else if (shift_amount > 32) {
|
||||
return_value = 0x0;
|
||||
*carry = 0x0;
|
||||
} else /* (shift_amount == 0) */
|
||||
return_value = rm;
|
||||
} else if (shift == 0x2) { /* ASR */
|
||||
if ((shift_amount > 0) && (shift_amount <= 32)) {
|
||||
if (shift_amount > 0 && shift_amount < 32) {
|
||||
/* C right shifts of unsigned values are guaranteed to
|
||||
* be logical (shift in zeroes); simulate an arithmetic
|
||||
* shift (shift in signed-bit) by adding the sign bit
|
||||
@@ -54,7 +60,7 @@ static uint32_t arm_shift(uint8_t shift, uint32_t rm,
|
||||
return_value = rm >> shift_amount;
|
||||
if (rm & 0x80000000)
|
||||
return_value |= 0xffffffff << (32 - shift_amount);
|
||||
} else if (shift_amount > 32) {
|
||||
} else if (shift_amount >= 32) {
|
||||
if (rm & 0x80000000) {
|
||||
return_value = 0xffffffff;
|
||||
*carry = 0x1;
|
||||
|
||||
@@ -739,6 +739,7 @@ COMMAND_HANDLER(handle_arm_tpiu_swo_enable)
|
||||
CONNECTION_LIMIT_UNLIMITED, priv);
|
||||
if (retval != ERROR_OK) {
|
||||
command_print(CMD, "Can't configure trace TCP port %s", &obj->out_filename[1]);
|
||||
free(priv);
|
||||
return retval;
|
||||
}
|
||||
} else if (strcmp(obj->out_filename, "-")) {
|
||||
|
||||
@@ -952,7 +952,7 @@ COMMAND_HANDLER(handle_arm_core_state_command)
|
||||
|
||||
COMMAND_HANDLER(handle_arm_disassemble_command)
|
||||
{
|
||||
#if HAVE_CAPSTONE
|
||||
#ifdef HAVE_CAPSTONE
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
|
||||
if (!target) {
|
||||
@@ -1686,7 +1686,8 @@ int arm_checksum_memory(struct target *target,
|
||||
*
|
||||
*/
|
||||
int arm_blank_check_memory(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked)
|
||||
{
|
||||
struct working_area *check_algorithm;
|
||||
struct reg_param reg_params[3];
|
||||
@@ -1748,8 +1749,10 @@ int arm_blank_check_memory(struct target *target,
|
||||
exit_var,
|
||||
10000, &arm_algo);
|
||||
|
||||
if (retval == ERROR_OK)
|
||||
if (retval == ERROR_OK) {
|
||||
blocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);
|
||||
*checked = 1; /* only one block has been checked */
|
||||
}
|
||||
|
||||
destroy_reg_param(®_params[0]);
|
||||
destroy_reg_param(®_params[1]);
|
||||
@@ -1757,10 +1760,7 @@ int arm_blank_check_memory(struct target *target,
|
||||
|
||||
target_free_working_area(target, check_algorithm);
|
||||
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return 1; /* only one block has been checked */
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int arm_full_context(struct target *target)
|
||||
|
||||
@@ -973,7 +973,8 @@ cleanup:
|
||||
|
||||
/** Checks an array of memory regions whether they are erased. */
|
||||
int armv7m_blank_check_memory(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked)
|
||||
{
|
||||
struct working_area *erase_check_algorithm;
|
||||
struct working_area *erase_check_params;
|
||||
@@ -1009,7 +1010,13 @@ int armv7m_blank_check_memory(struct target *target,
|
||||
};
|
||||
|
||||
uint32_t avail = target_get_working_area_avail(target);
|
||||
int blocks_to_check = avail / sizeof(struct algo_block) - 1;
|
||||
unsigned int avail_blocks = avail / sizeof(struct algo_block);
|
||||
if (avail_blocks < 2) {
|
||||
retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
||||
goto cleanup1;
|
||||
}
|
||||
|
||||
unsigned int blocks_to_check = avail_blocks - 1;
|
||||
if (num_blocks < blocks_to_check)
|
||||
blocks_to_check = num_blocks;
|
||||
|
||||
@@ -1019,7 +1026,7 @@ int armv7m_blank_check_memory(struct target *target,
|
||||
goto cleanup1;
|
||||
}
|
||||
|
||||
int i;
|
||||
unsigned int i;
|
||||
uint32_t total_size = 0;
|
||||
for (i = 0; i < blocks_to_check; i++) {
|
||||
total_size += blocks[i].size;
|
||||
@@ -1089,7 +1096,7 @@ int armv7m_blank_check_memory(struct target *target,
|
||||
LOG_TARGET_INFO(target, "Slow CPU clock: %d blocks checked, %d remain. Continuing...",
|
||||
i, num_blocks - i);
|
||||
|
||||
retval = i; /* return number of blocks really checked */
|
||||
*checked = i; /* return number of blocks really checked */
|
||||
|
||||
cleanup4:
|
||||
destroy_reg_param(®_params[0]);
|
||||
|
||||
@@ -353,7 +353,8 @@ bool armv7m_map_reg_packing(unsigned int arm_reg_id,
|
||||
int armv7m_checksum_memory(struct target *target,
|
||||
target_addr_t address, uint32_t count, uint32_t *checksum);
|
||||
int armv7m_blank_check_memory(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value);
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked);
|
||||
|
||||
int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found);
|
||||
|
||||
|
||||
@@ -192,28 +192,37 @@ static int armv7m_identify_cache_internal(struct target *target)
|
||||
}
|
||||
|
||||
/*
|
||||
* On Cortex-M7 only, when the CPU is kept in reset, several registers of the
|
||||
* System Control Space (SCS) are not accessible and return bus error.
|
||||
* The list of accessible registers is:
|
||||
* On Cortex-M7 and Cortex-M85, when the CPU is kept in reset, several
|
||||
* registers of the System Control Space (SCS) are not accessible and
|
||||
* return bus error.
|
||||
* The list of accessible registers for Cortex-M7 is:
|
||||
* - 0xE000ED00
|
||||
* - 0xE000ED30
|
||||
* - 0xE000EDF0 ... 0xE000EEFC
|
||||
* - 0xE000EF40 ... 0xE000EF48
|
||||
* - 0xE000EFD0 ... 0xE000EFFC
|
||||
* The list of accessible registers for Cortex-M85 is:
|
||||
* - 0xE000ED00
|
||||
* - 0xE000ED30
|
||||
* - 0xE000ED40 ... 0xE000ED80
|
||||
* - 0xE000EDF0 ... 0xE000EEFC
|
||||
* - 0xE000EF40 ... 0xE000EF4C
|
||||
* - 0xE000EFB0 ... 0xE000EFFC
|
||||
* This makes impossible detecting the cache during the reset.
|
||||
* Use a deferred mechanism to detect the cache during polling or when the
|
||||
* Cortex-M7 halts.
|
||||
* CPU halts.
|
||||
*/
|
||||
int armv7m_identify_cache(struct target *target)
|
||||
{
|
||||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||
struct armv7m_common *armv7m = target_to_armv7m(target);
|
||||
struct armv7m_cache_common *cache = &armv7m->armv7m_cache;
|
||||
enum cortex_m_impl_part part = cortex_m->core_info->impl_part;
|
||||
|
||||
if (cache->info_valid)
|
||||
return ERROR_OK;
|
||||
|
||||
if (cortex_m->core_info->impl_part == CORTEX_M7_PARTNO
|
||||
if ((part == CORTEX_M7_PARTNO || part == CORTEX_M85_PARTNO)
|
||||
&& cortex_m->dcb_dhcsr & S_RESET_ST) {
|
||||
cache->defer_identification = true;
|
||||
return ERROR_OK;
|
||||
|
||||
@@ -2775,10 +2775,12 @@ int cortex_m_security_restore(struct target *target, struct cortex_m_saved_secur
|
||||
static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,
|
||||
struct adiv5_ap **debug_ap)
|
||||
{
|
||||
if (dap_find_get_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
|
||||
return ERROR_OK;
|
||||
const enum ap_type types[] = {
|
||||
AP_TYPE_AHB3_AP,
|
||||
AP_TYPE_AHB5_AP
|
||||
};
|
||||
|
||||
return dap_find_get_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
|
||||
return dap_find_by_types_get_ap(swjdp, types, ARRAY_SIZE(types), debug_ap);
|
||||
}
|
||||
|
||||
int cortex_m_examine(struct target *target)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1310,8 +1310,8 @@ int mips32_checksum_memory(struct target *target, target_addr_t address,
|
||||
|
||||
/** Checks whether a memory region is erased. */
|
||||
int mips32_blank_check_memory(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks,
|
||||
uint8_t erased_value)
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked)
|
||||
{
|
||||
struct working_area *erase_check_algorithm;
|
||||
struct reg_param reg_params[3];
|
||||
@@ -1367,8 +1367,10 @@ int mips32_blank_check_memory(struct target *target,
|
||||
retval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address,
|
||||
erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &mips32_info);
|
||||
|
||||
if (retval == ERROR_OK)
|
||||
if (retval == ERROR_OK) {
|
||||
blocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);
|
||||
*checked = 1; /* only one block has been checked */
|
||||
}
|
||||
|
||||
destroy_reg_param(®_params[0]);
|
||||
destroy_reg_param(®_params[1]);
|
||||
@@ -1377,10 +1379,7 @@ int mips32_blank_check_memory(struct target *target,
|
||||
cleanup:
|
||||
target_free_working_area(target, erase_check_algorithm);
|
||||
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return 1; /* only one block has been checked */
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int mips32_verify_pointer(struct command_invocation *cmd,
|
||||
|
||||
@@ -933,7 +933,8 @@ int mips32_get_gdb_reg_list(struct target *target,
|
||||
int mips32_checksum_memory(struct target *target, target_addr_t address,
|
||||
uint32_t count, uint32_t *checksum);
|
||||
int mips32_blank_check_memory(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value);
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked);
|
||||
|
||||
bool mips32_cpu_support_sync(struct mips_ejtag *ejtag_info);
|
||||
bool mips32_cpu_support_hazard_barrier(struct mips_ejtag *ejtag_info);
|
||||
|
||||
@@ -195,10 +195,19 @@ static const struct service_driver jsp_service_driver = {
|
||||
int jsp_init(struct or1k_jtag *jtag_info, char *banner)
|
||||
{
|
||||
struct jsp_service *jsp_service = malloc(sizeof(struct jsp_service));
|
||||
if (!jsp_service) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
jsp_service->banner = banner;
|
||||
jsp_service->jtag_info = jtag_info;
|
||||
|
||||
return add_service(&jsp_service_driver, jsp_port, 1, jsp_service);
|
||||
int retval = add_service(&jsp_service_driver, jsp_port, 1, jsp_service);
|
||||
if (retval != ERROR_OK)
|
||||
free(jsp_service);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_jsp_port_command)
|
||||
|
||||
@@ -4380,7 +4380,7 @@ static bool parse_csr_address(const char *reg_address_str, unsigned int *reg_add
|
||||
{
|
||||
*reg_addr = -1;
|
||||
/* skip initial spaces */
|
||||
while (isspace(reg_address_str[0]))
|
||||
while (isspace((unsigned char)reg_address_str[0]))
|
||||
++reg_address_str;
|
||||
/* try to detect if string starts with 0x or 0X */
|
||||
bool is_hex_address = strncmp(reg_address_str, "0x", 2) == 0 ||
|
||||
|
||||
@@ -1857,7 +1857,7 @@ COMMAND_HANDLER(handle_common_semihosting_command)
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (semihosting && semihosting->setup(target, is_active) != ERROR_OK) {
|
||||
if (semihosting->setup(target, is_active) != ERROR_OK) {
|
||||
LOG_ERROR("Failed to Configure semihosting");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
@@ -54,16 +54,13 @@ int gdb_read_smp_packet(struct connection *connection,
|
||||
LOG_WARNING(DEPRECATED_MSG);
|
||||
|
||||
if (target->smp) {
|
||||
if (strncmp(packet, "jc", 2) == 0) {
|
||||
const uint32_t len = sizeof(target->gdb_service->core[0]);
|
||||
char hex_buffer[len * 2 + 1];
|
||||
uint8_t buffer[len];
|
||||
buf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]);
|
||||
size_t pkt_len = hexify(hex_buffer, buffer, sizeof(buffer),
|
||||
sizeof(hex_buffer));
|
||||
|
||||
retval = gdb_put_packet(connection, hex_buffer, pkt_len);
|
||||
}
|
||||
const uint32_t len = sizeof(target->gdb_service->core[0]);
|
||||
char hex_buffer[len * 2 + 1];
|
||||
uint8_t buffer[len];
|
||||
buf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]);
|
||||
size_t pkt_len = hexify(hex_buffer, buffer, sizeof(buffer),
|
||||
sizeof(hex_buffer));
|
||||
retval = gdb_put_packet(connection, hex_buffer, pkt_len);
|
||||
} else
|
||||
retval = gdb_put_packet(connection, "E01", 3);
|
||||
return retval;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <helper/log.h>
|
||||
#include "target.h"
|
||||
#include "target_type.h"
|
||||
#include "jtag/adapter.h"
|
||||
#include "jtag/interface.h"
|
||||
#include "jtag/jtag.h"
|
||||
#include "jtag/swim.h"
|
||||
@@ -33,7 +34,6 @@ static void stm8_enable_watchpoints(struct target *target);
|
||||
static int stm8_unset_watchpoint(struct target *target,
|
||||
struct watchpoint *watchpoint);
|
||||
static int (*adapter_speed)(int speed);
|
||||
extern struct adapter_driver *adapter_driver;
|
||||
|
||||
static const struct {
|
||||
unsigned int id;
|
||||
@@ -1757,7 +1757,8 @@ static int stm8_examine(struct target *target)
|
||||
|
||||
/** Checks whether a memory region is erased. */
|
||||
static int stm8_blank_check_memory(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked)
|
||||
{
|
||||
struct working_area *erase_check_algorithm;
|
||||
struct reg_param reg_params[2];
|
||||
@@ -1801,8 +1802,10 @@ static int stm8_blank_check_memory(struct target *target,
|
||||
erase_check_algorithm->address + (sizeof(stm8_erase_check_code) - 1),
|
||||
10000, &stm8_info);
|
||||
|
||||
if (retval == ERROR_OK)
|
||||
if (retval == ERROR_OK) {
|
||||
blocks[0].result = (*(reg_params[0].value) == 0xff);
|
||||
*checked = 1; /* only one block has been checked */
|
||||
}
|
||||
|
||||
destroy_mem_param(&mem_params[0]);
|
||||
destroy_mem_param(&mem_params[1]);
|
||||
@@ -1811,10 +1814,7 @@ static int stm8_blank_check_memory(struct target *target,
|
||||
|
||||
target_free_working_area(target, erase_check_algorithm);
|
||||
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return 1; /* only one block has been checked */
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int stm8_checksum_memory(struct target *target, target_addr_t address,
|
||||
|
||||
@@ -2513,8 +2513,8 @@ int target_checksum_memory(struct target *target, target_addr_t address, uint32_
|
||||
}
|
||||
|
||||
int target_blank_check_memory(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks,
|
||||
uint8_t erased_value)
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked)
|
||||
{
|
||||
if (!target_was_examined(target)) {
|
||||
LOG_ERROR("Target not examined yet");
|
||||
@@ -2524,7 +2524,8 @@ int target_blank_check_memory(struct target *target,
|
||||
if (!target->type->blank_check_memory)
|
||||
return ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
return target->type->blank_check_memory(target, blocks, num_blocks, erased_value);
|
||||
return target->type->blank_check_memory(target, blocks, num_blocks,
|
||||
erased_value, checked);
|
||||
}
|
||||
|
||||
int target_read_u64(struct target *target, target_addr_t address, uint64_t *value)
|
||||
|
||||
@@ -662,8 +662,8 @@ int target_read_buffer(struct target *target,
|
||||
int target_checksum_memory(struct target *target,
|
||||
target_addr_t address, uint32_t size, uint32_t *crc);
|
||||
int target_blank_check_memory(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks,
|
||||
uint8_t erased_value);
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked);
|
||||
int target_wait_state(struct target *target, enum target_state state, unsigned int ms);
|
||||
|
||||
/**
|
||||
|
||||
@@ -141,8 +141,8 @@ struct target_type {
|
||||
int (*checksum_memory)(struct target *target, target_addr_t address,
|
||||
uint32_t count, uint32_t *checksum);
|
||||
int (*blank_check_memory)(struct target *target,
|
||||
struct target_memory_check_block *blocks, int num_blocks,
|
||||
uint8_t erased_value);
|
||||
struct target_memory_check_block *blocks, unsigned int num_blocks,
|
||||
uint8_t erased_value, unsigned int *checked);
|
||||
|
||||
/*
|
||||
* target break-/watchpoint control
|
||||
|
||||
@@ -3493,6 +3493,10 @@ static void xtensa_free_reg_cache(struct target *target)
|
||||
free(xtensa->optregs);
|
||||
}
|
||||
xtensa->optregs = NULL;
|
||||
free(xtensa->contiguous_regs_desc);
|
||||
xtensa->contiguous_regs_desc = NULL;
|
||||
free(xtensa->contiguous_regs_list);
|
||||
xtensa->contiguous_regs_list = NULL;
|
||||
}
|
||||
|
||||
void xtensa_target_deinit(struct target *target)
|
||||
@@ -3896,6 +3900,10 @@ COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa)
|
||||
xtensa->total_regs_num = numregs;
|
||||
xtensa->core_regs_num = 0;
|
||||
xtensa->num_optregs = 0;
|
||||
/* Prevent memory leak in case xtregs is called twice */
|
||||
free(xtensa->optregs);
|
||||
free(xtensa->contiguous_regs_desc);
|
||||
xtensa->contiguous_regs_desc = NULL;
|
||||
/* A little more memory than required, but saves a second initialization pass */
|
||||
xtensa->optregs = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc));
|
||||
if (!xtensa->optregs) {
|
||||
|
||||
@@ -352,7 +352,7 @@ COMMAND_HANDLER(handle_transport_select)
|
||||
transport_single_is_autoselected = false;
|
||||
return ERROR_OK;
|
||||
}
|
||||
LOG_WARNING("Transport \"%s\" was already selected", CMD_ARGV[0]);
|
||||
LOG_DEBUG("Transport \"%s\" was already selected", CMD_ARGV[0]);
|
||||
return ERROR_OK;
|
||||
}
|
||||
command_print(CMD, "Can't change session's transport after the initial selection was made");
|
||||
|
||||
@@ -5,7 +5,4 @@
|
||||
#
|
||||
|
||||
source [find interface/jlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
source [find target/nordic/nrf51.cfg]
|
||||
|
||||
@@ -5,7 +5,4 @@
|
||||
#
|
||||
|
||||
source [find interface/jlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
source [find target/nordic/nrf52.cfg]
|
||||
|
||||
@@ -6,7 +6,4 @@
|
||||
#
|
||||
|
||||
source [find interface/jlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
source [find target/nordic/nrf53.cfg]
|
||||
|
||||
@@ -6,7 +6,4 @@
|
||||
#
|
||||
|
||||
source [find interface/jlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
source [find target/nordic/nrf91.cfg]
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
source [find target/stm32u0x.cfg]
|
||||
|
||||
reset_config srst_only
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
source [find target/stm32c0x.cfg]
|
||||
|
||||
reset_config srst_only
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
source [find target/stm32f0x.cfg]
|
||||
|
||||
reset_config srst_only
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
source [find target/stm32g0x.cfg]
|
||||
|
||||
reset_config srst_only
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
# increase working area to 8KB
|
||||
set WORKAREASIZE 0x2000
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
set WORKAREASIZE 0x2000
|
||||
source [find target/stm32f0x.cfg]
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
transport select swd
|
||||
|
||||
set WORKAREASIZE 0x2000
|
||||
source [find target/stm32l0.cfg]
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
# samdXX devices only support SWD transports.
|
||||
#
|
||||
source [find target/swj-dp.tcl]
|
||||
transport select swd
|
||||
|
||||
if { [info exists CHIPNAME] } {
|
||||
set _CHIPNAME $CHIPNAME
|
||||
@@ -15,12 +15,6 @@ if { [info exists CHIPNAME] } {
|
||||
set _CHIPNAME at91samd
|
||||
}
|
||||
|
||||
if { [info exists ENDIAN] } {
|
||||
set _ENDIAN $ENDIAN
|
||||
} else {
|
||||
set _ENDIAN little
|
||||
}
|
||||
|
||||
# Work-area is a space in RAM used for flash programming
|
||||
# By default use 2kB
|
||||
if { [info exists WORKAREASIZE] } {
|
||||
@@ -35,11 +29,11 @@ if { [info exists CPUTAPID] } {
|
||||
set _CPUTAPID 0x4ba00477
|
||||
}
|
||||
|
||||
swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
|
||||
swd newdap $_CHIPNAME cpu -expected-id $_CPUTAPID
|
||||
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap
|
||||
target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap
|
||||
|
||||
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Devices only support SWD transports.
|
||||
#
|
||||
source [find target/swj-dp.tcl]
|
||||
transport select swd
|
||||
|
||||
if { [info exists CHIPNAME] } {
|
||||
set _CHIPNAME $CHIPNAME
|
||||
@@ -16,12 +16,6 @@ if { [info exists CHIPNAME] } {
|
||||
set _CHIPNAME atsame5
|
||||
}
|
||||
|
||||
if { [info exists ENDIAN] } {
|
||||
set _ENDIAN $ENDIAN
|
||||
} else {
|
||||
set _ENDIAN little
|
||||
}
|
||||
|
||||
# Work-area is a space in RAM used for flash programming
|
||||
# By default use 32kB (the smallest RAM size is 128kB)
|
||||
if { [info exists WORKAREASIZE] } {
|
||||
@@ -36,11 +30,11 @@ if { [info exists CPUTAPID] } {
|
||||
set _CPUTAPID 0x4ba00477
|
||||
}
|
||||
|
||||
swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
|
||||
swd newdap $_CHIPNAME cpu -expected-id $_CPUTAPID
|
||||
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap
|
||||
target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap
|
||||
|
||||
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#
|
||||
# Freescale Kinetis KE0x and KEAx series devices
|
||||
#
|
||||
|
||||
source [find target/swj-dp.tcl]
|
||||
# Devices support SWD transport only
|
||||
transport select swd
|
||||
|
||||
if { [info exists CHIPNAME] } {
|
||||
set _CHIPNAME $CHIPNAME
|
||||
@@ -26,7 +26,7 @@ if { [info exists CPUTAPID] } {
|
||||
set _CPUTAPID 0x0bc11477
|
||||
}
|
||||
|
||||
swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
|
||||
swd newdap $_CHIPNAME cpu -expected-id $_CPUTAPID
|
||||
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
# NXP (former Freescale) Kinetis KL series devices
|
||||
# Also used for Cortex-M0+ equipped members of KVx and KE1xZ series
|
||||
#
|
||||
|
||||
source [find target/swj-dp.tcl]
|
||||
# Devices support SWD transport only
|
||||
transport select swd
|
||||
|
||||
if { [info exists CHIPNAME] } {
|
||||
set _CHIPNAME $CHIPNAME
|
||||
@@ -27,7 +27,7 @@ if { [info exists CPUTAPID] } {
|
||||
set _CPUTAPID 0x0bc11477
|
||||
}
|
||||
|
||||
swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
|
||||
swd newdap $_CHIPNAME cpu -expected-id $_CPUTAPID
|
||||
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
# Based on NXP proposal https://community.nxp.com/message/1011149
|
||||
# Many thanks to Dries Moors from NXP support.
|
||||
# SWD only transport
|
||||
transport select swd
|
||||
|
||||
source [find target/swj-dp.tcl]
|
||||
source [find mem_helper.tcl]
|
||||
|
||||
if { [info exists CHIPNAME] } {
|
||||
@@ -15,7 +15,7 @@ if { [info exists CHIPNAME] } {
|
||||
set _CHIPNAME lpc8nxx
|
||||
}
|
||||
|
||||
swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id 0
|
||||
swd newdap $_CHIPNAME cpu -expected-id 0
|
||||
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Maxim Integrated MAX32620 OpenOCD target configuration file
|
||||
# Maxim Integrated MAX32620 - Arm Cortex-M4F @ 96MHz
|
||||
|
||||
# Set the reset pin configuration
|
||||
reset_config srst_only
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Maxim Integrated MAX32625 OpenOCD target configuration file
|
||||
# Maxim Integrated MAX32625 - Arm Cortex-M4F @ 96MHz
|
||||
|
||||
# Set the reset pin configuration
|
||||
reset_config srst_only
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Maxim Integrated MAX3263X OpenOCD target configuration file
|
||||
# Maxim Integrated MAX3263x - Arm Cortex-M4F @ 96MHz
|
||||
|
||||
# Set the reset pin configuration
|
||||
reset_config none
|
||||
|
||||
18
tcl/target/max32660.cfg
Normal file
18
tcl/target/max32660.cfg
Normal file
@@ -0,0 +1,18 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Maxim Integrated MAX32660 - Arm Cortex-M4F @ 96MHz
|
||||
|
||||
# Set the reset pin configuration
|
||||
reset_config srst_only
|
||||
|
||||
# Set flash parameters
|
||||
set FLASH_BASE 0x0
|
||||
set FLASH_SIZE 0x40000
|
||||
set FLC_BASE 0x40029000
|
||||
set FLASH_SECTOR 0x2000
|
||||
set FLASH_CLK 96
|
||||
set FLASH_OPTIONS 0x00
|
||||
|
||||
# Use Serial Wire Debug
|
||||
transport select swd
|
||||
|
||||
source [find target/max32xxx_common.cfg]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user