aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2023-05-01 10:17:24 -0700
committerTim Newsome <tim@sifive.com>2023-05-04 14:38:10 -0700
commitda44fb5407a3aed24b1be04dd3c12d6a8b013fc8 (patch)
tree7a0b5c63a914ba290a2cbbea4331bc5e499b20d5
parentfc52bfefc8e794d037bfb23a3a7358daba5c9475 (diff)
parent228fe7300c7df7aa05ba2c0bc19edde6d0156401 (diff)
downloadriscv-openocd-da44fb5407a3aed24b1be04dd3c12d6a8b013fc8.zip
riscv-openocd-da44fb5407a3aed24b1be04dd3c12d6a8b013fc8.tar.gz
riscv-openocd-da44fb5407a3aed24b1be04dd3c12d6a8b013fc8.tar.bz2
Merge commit '228fe7300c7df7aa05ba2c0bc19edde6d0156401' into from_upstream
Conflicts: doc/openocd.texi src/jtag/aice/aice_pipe.c src/jtag/aice/aice_usb.c src/rtos/FreeRTOS.c src/rtos/hwthread.c src/rtos/rtos_standard_stackings.c src/target/riscv/riscv.c Change-Id: I0c6228c499d60274325be895fbcd8007ed1699bc
-rw-r--r--NEWS99
-rw-r--r--NEWS-0.12.0132
-rw-r--r--README29
-rw-r--r--configure.ac30
-rw-r--r--contrib/buildroot/openocd_be_defconfig1
-rw-r--r--doc/openocd.texi67
-rw-r--r--src/flash/nor/at91samd.c29
-rw-r--r--src/flash/nor/avrf.c1
-rw-r--r--src/flash/nor/lpc2900.c4
-rw-r--r--src/flash/nor/rp2040.c241
-rw-r--r--src/flash/nor/spi.c1
-rw-r--r--src/flash/nor/stm32f1x.c2
-rw-r--r--src/flash/nor/stm32lx.c2
-rw-r--r--src/flash/nor/stmqspi.c31
-rw-r--r--src/helper/command.c14
-rw-r--r--src/helper/jep106.inc87
-rw-r--r--src/helper/types.h16
-rw-r--r--src/jtag/Makefile.am5
-rw-r--r--src/jtag/aice/Makefile.am16
-rw-r--r--src/jtag/aice/aice_interface.c507
-rw-r--r--src/jtag/aice/aice_interface.h14
-rw-r--r--src/jtag/aice/aice_pipe.c885
-rw-r--r--src/jtag/aice/aice_pipe.h20
-rw-r--r--src/jtag/aice/aice_port.c34
-rw-r--r--src/jtag/aice/aice_port.h224
-rw-r--r--src/jtag/aice/aice_transport.c432
-rw-r--r--src/jtag/aice/aice_transport.h13
-rw-r--r--src/jtag/aice/aice_usb.c4100
-rw-r--r--src/jtag/aice/aice_usb.h122
-rw-r--r--src/jtag/drivers/arm-jtag-ew.c15
-rw-r--r--src/jtag/drivers/bcm2835gpio.c15
-rw-r--r--src/jtag/drivers/bitbang.c15
-rw-r--r--src/jtag/drivers/cmsis_dap.c8
-rw-r--r--src/jtag/drivers/cmsis_dap_usb_bulk.c4
-rw-r--r--src/jtag/drivers/esp_usb_jtag.c8
-rw-r--r--src/jtag/drivers/opendous.c15
-rw-r--r--src/jtag/drivers/vdebug.c2
-rw-r--r--src/jtag/drivers/xds110.c2
-rw-r--r--src/jtag/interfaces.c6
-rw-r--r--src/jtag/startup.tcl6
-rw-r--r--src/openocd.c60
-rw-r--r--src/pld/virtex2.c6
-rw-r--r--src/pld/xilinx_bit.c41
-rw-r--r--src/pld/xilinx_bit.h2
-rw-r--r--src/rtos/FreeRTOS.c11
-rw-r--r--src/rtos/ThreadX.c29
-rw-r--r--src/rtos/eCos.c1033
-rw-r--r--src/rtos/hwthread.c30
-rw-r--r--src/rtos/rtos_ecos_stackings.c7
-rw-r--r--src/rtos/rtos_standard_stackings.c47
-rw-r--r--src/rtos/rtos_standard_stackings.h1
-rw-r--r--src/target/Makefile.am27
-rw-r--r--src/target/aarch64.c31
-rw-r--r--src/target/adi_v5_swd.c18
-rw-r--r--src/target/arm_adi_v5.c2
-rw-r--r--src/target/armv7m.c73
-rw-r--r--src/target/armv8.c335
-rw-r--r--src/target/armv8.h7
-rw-r--r--src/target/cortex_a.c49
-rw-r--r--src/target/cortex_m.c339
-rw-r--r--src/target/cortex_m.h3
-rw-r--r--src/target/dsp5680xx.c4
-rw-r--r--src/target/esirisc_jtag.c4
-rw-r--r--src/target/espressif/esp32s2.c2
-rw-r--r--src/target/hla_target.c7
-rw-r--r--src/target/mem_ap.c13
-rw-r--r--src/target/mips_m4k.c2
-rw-r--r--src/target/nds32.c2613
-rw-r--r--src/target/nds32.h447
-rw-r--r--src/target/nds32_aice.c147
-rw-r--r--src/target/nds32_aice.h150
-rw-r--r--src/target/nds32_cmd.c1123
-rw-r--r--src/target/nds32_cmd.h15
-rw-r--r--src/target/nds32_disassembler.c3847
-rw-r--r--src/target/nds32_disassembler.h45
-rw-r--r--src/target/nds32_edm.h106
-rw-r--r--src/target/nds32_insn.h67
-rw-r--r--src/target/nds32_reg.c369
-rw-r--r--src/target/nds32_reg.h314
-rw-r--r--src/target/nds32_tlb.c67
-rw-r--r--src/target/nds32_tlb.h36
-rw-r--r--src/target/nds32_v2.c774
-rw-r--r--src/target/nds32_v2.h31
-rw-r--r--src/target/nds32_v3.c510
-rw-r--r--src/target/nds32_v3.h34
-rw-r--r--src/target/nds32_v3_common.c664
-rw-r--r--src/target/nds32_v3_common.h50
-rw-r--r--src/target/nds32_v3m.c495
-rw-r--r--src/target/nds32_v3m.h40
-rw-r--r--src/target/openrisc/or1k_du_adv.c5
-rw-r--r--src/target/rtt.c34
-rw-r--r--src/target/startup.tcl19
-rw-r--r--src/target/target.c113
-rw-r--r--src/target/target.h4
-rw-r--r--src/target/xtensa/xtensa.c38
-rw-r--r--tcl/board/nds32_xc5.cfg7
-rw-r--r--tcl/cpld/xilinx-xcu.cfg2
-rw-r--r--tcl/interface/nds32-aice.cfg17
-rw-r--r--tcl/interface/raspberrypi2-native.cfg4
-rw-r--r--tcl/target/atmega32u4.cfg30
-rw-r--r--tcl/target/max32620.cfg4
-rw-r--r--tcl/target/max32625.cfg4
-rw-r--r--tcl/target/max3263x.cfg4
-rw-r--r--tcl/target/nds32v2.cfg12
-rw-r--r--tcl/target/nds32v3.cfg12
-rw-r--r--tcl/target/nds32v3m.cfg12
-rw-r--r--tcl/target/rp2040-core0.cfg37
-rw-r--r--tcl/target/rp2040.cfg80
-rw-r--r--tcl/target/stm32x5x_common.cfg24
-rw-r--r--tcl/target/ti_k3.cfg5
-rw-r--r--tcl/target/xtensa-core-esp32.cfg42
-rw-r--r--tcl/target/xtensa-core-esp32s2.cfg74
-rw-r--r--tcl/target/xtensa-core-esp32s3.cfg147
-rw-r--r--tools/scripts/camelcase.txt16
114 files changed, 2567 insertions, 19560 deletions
diff --git a/NEWS b/NEWS
index 50cb984..9db6c5f 100644
--- a/NEWS
+++ b/NEWS
@@ -2,126 +2,29 @@ This file includes highlights of the changes made in the OpenOCD
source archive release.
JTAG Layer:
- * add default to adapter speed when unspecified (100 kHz)
- * AM335X gpio (BeagleBones) adapter driver
- * BCM2835 support for SWD
- * Cadence Virtual Debug (vdebug) adapter driver
- * CMSIS-DAP support for SWO and SWD multidrop
- * Espressif USB JTAG Programmer adapter driver
- * Remote bitbang support for Windows host
- * ST-LINK add TCP server support to adapter driver
- * SWD multidrop support
Boundary Scan:
Target Layer:
- * aarch64: support watchpoints
- * arm: support independent TPIU and SWO for trace
- * arm adi v5: support Large Physical Address Extension
- * arm adi v6: support added, for jtag and swd transport
- * cortex_a: support watchpoints
- * elf 64bit load support
- * Espressif: support ESP32, ESP32-S2 and ESP32-S3 cores
- * semihosting: support user defined operations
- * Xtensa: support Xtensa LX architecture via JTAG and ADIv5 DAP
Flash Layer:
- * Atmel/Microchip SAM E51G18A, E51G19A, R35J18B, LAN9255 support
- * GigaDevice GD32E23x, GD32F1x0/3x0, GD32VF103 support
- * Nuvoton NPCX series support
- * onsemi RSL10 support
- * Raspberry Pi Pico RP2040 support
- * ST BlueNRG-LPS support
- * ST STM32 G05x, G06x, G0Bx, G0Cx, U57x, U58x, WB1x, WL5x support
- * ST STM32 G0, G4, L4, L4+, L5, WB, WL OTP support
Board, Target, and Interface Configuration Scripts:
- * Ampere Computing eMAG8180, Altra ("Quicksilver") and Altra Max ("Mystique") board config
- * Cadence KC705 FPGA (Xtensa Development Platform) via JTAG and ADIv5 DAP board config
- * Digilent Nexys Video board config
- * Espressif ESP32 ETHERNET-KIT and WROVER-KIT board config
- * Espressif ESP32 via ESP USB Bridge generic board config
- * Espressif ESP32-S2 Kaluga 1 board config
- * Espressif ESP32-S2 with ESP USB Bridge board config
- * Espressif ESP32-S3 example board config
- * Kontron SMARC-sAL28 board config
- * LambdaConcept ECPIX-5 board config
- * Microchip ATSAMA5D27-SOM1-EK1 board config
- * Microchip EVB-LAN9255 board config
- * Microchip SAME51 Curiosity Nano board config
- * NXP FRDM-K64F, LS1046ARDB and LS1088ARDB board config
- * NXP RT6XX board config
- * Olimex H405 board config
- * Radiona ULX3S board config
- * Raspberry Pi 3 and Raspberry Pi 4 model B board config
- * Raspberry Pi Pico-Debug board config
- * Renesas R-Car V3U Falcon board config
- * ST BlueNRG-LPS steval-idb012v1 board config
- * ST NUCLEO-8S208RB board config
- * ST NUCLEO-G031K8, NUCLEO-G070RB, NUCLEO-G071RB board config
- * ST NUCLEO-G431KB, NUCLEO-G431RB, NUCLEO-G474RE board config
- * ST STM32MP13x-DK board config
- * TI AM625 EVM, AM642 EVM and AM654 EVM board config
- * TI J721E EVM, J721S2 EVM and J7200 EVM board config
- * Ampere Computing eMAG, Altra ("Quicksilver") and Altra Max ("Mystique") target config
- * Cadence Xtensa generic and Xtensa VDebug target config
- * Broadcom BCM2711, BCM2835, BCM2836 and BCM2837 target config
- * Espressif ESP32, ESP32-S2 and ESP32-S3 target config
- * Microchip ATSAMA5D2 series target config
- * NanoXplore NG-Ultra SoC target config
- * NXP IMX8QM target config
- * NXP LS1028A, LS1046A and LS1088A target config
- * NXP RT600 (Xtensa HiFi DSP) target config
- * onsemi RSL10 target config
- * Raspberry Pi Pico RP2040 target config
- * Renesas R8A779A0 V3U target config
- * Renesas RZ/Five target config
- * Renesas RZ/G2 MPU family target config
- * Rockchip RK3399 target config
- * ST BlueNRG-LPS target config
- * ST STM32MP13x target config
- * TI AM625, AM654, J721E and J721S2 target config
- * Ashling Opella-LD interface config
- * Aspeed AST2600 linuxgpiod based interface config
- * Blinkinlabs JTAG_Hat interface config
- * Cadence Virtual Debug (vdebug) interface config
- * Espressif ESP32-S2 Kaluga 1 board's interface config
- * Espressif USB Bridge jtag interface config
- * Infineon DAP miniWiggler V3 interface config
- * PLS SPC5 interface config
- * Tigard interface config
- * Lattice MachXO3 family FPGA config
Server Layer:
- * GDB: add per-target remote protocol extensions
- * GDB: more 'Z' packets support
- * IPDBG JtagHost server functionality
- * semihosting: I/O redirection to TCP server
- * telnet: support for command's autocomplete
RTOS:
- * 'none' rtos support
- * Zephyr rtos support
Documentation:
Build and Release:
- * Add json extension to jimtcl build
- * Drop dependency from libusb0
- * Drop repository repo.or.cz for submodules
- * Move gerrit to https://review.openocd.org/
- * Require autoconf 2.69 or newer
- * Update jep106 to revision JEP106BE
- * Update jimtcl to version 0.81
- * Update libjaylink to version 0.3.1
- * New configure flag '--enable-jimtcl-maintainer' for jimtcl build
This release also contains a number of other important functional and
cosmetic bugfixes. For more details about what has changed since the
last release, see the git repository history:
-http://sourceforge.net/p/openocd/code/ci/v0.12.0-rc1/log/?path=
+http://sourceforge.net/p/openocd/code/ci/v0.x.0/log/?path=
For older NEWS, see the NEWS files associated with each release
diff --git a/NEWS-0.12.0 b/NEWS-0.12.0
new file mode 100644
index 0000000..208146a
--- /dev/null
+++ b/NEWS-0.12.0
@@ -0,0 +1,132 @@
+This file includes highlights of the changes made in the OpenOCD
+source archive release.
+
+JTAG Layer:
+ * add default to adapter speed when unspecified (100 kHz)
+ * AM335X gpio (BeagleBones) adapter driver
+ * BCM2835 support for SWD
+ * Cadence Virtual Debug (vdebug) adapter driver
+ * CMSIS-DAP support for SWO and SWD multidrop
+ * Espressif USB JTAG Programmer adapter driver
+ * Remote bitbang support for Windows host
+ * ST-LINK add TCP server support to adapter driver
+ * SWD multidrop support
+
+Boundary Scan:
+
+Target Layer:
+ * aarch64: support watchpoints
+ * arm: support independent TPIU and SWO for trace
+ * arm adi v5: support Large Physical Address Extension
+ * arm adi v6: support added, for jtag and swd transport
+ * cortex_a: support watchpoints
+ * elf 64bit load support
+ * Espressif: support ESP32, ESP32-S2 and ESP32-S3 cores
+ * semihosting: support user defined operations
+ * Xtensa: support Xtensa LX architecture via JTAG and ADIv5 DAP
+
+Flash Layer:
+ * Atmel/Microchip SAM E51G18A, E51G19A, R35J18B, LAN9255 support
+ * GigaDevice GD32E23x, GD32F1x0/3x0, GD32VF103 support
+ * Nuvoton NPCX series support
+ * onsemi RSL10 support
+ * Raspberry Pi Pico RP2040 support
+ * ST BlueNRG-LPS support
+ * ST STM32 G05x, G06x, G0Bx, G0Cx, U57x, U58x, WB1x, WL5x support
+ * ST STM32 G0, G4, L4, L4+, L5, WB, WL OTP support
+
+Board, Target, and Interface Configuration Scripts:
+ * Ampere Computing eMAG8180, Altra ("Quicksilver") and Altra Max ("Mystique") board config
+ * Cadence KC705 FPGA (Xtensa Development Platform) via JTAG and ADIv5 DAP board config
+ * Digilent Nexys Video board config
+ * Espressif ESP32 ETHERNET-KIT and WROVER-KIT board config
+ * Espressif ESP32 via ESP USB Bridge generic board config
+ * Espressif ESP32-S2 Kaluga 1 board config
+ * Espressif ESP32-S2 with ESP USB Bridge board config
+ * Espressif ESP32-S3 example board config
+ * Kontron SMARC-sAL28 board config
+ * LambdaConcept ECPIX-5 board config
+ * Microchip ATSAMA5D27-SOM1-EK1 board config
+ * Microchip EVB-LAN9255 board config
+ * Microchip SAME51 Curiosity Nano board config
+ * NXP FRDM-K64F, LS1046ARDB and LS1088ARDB board config
+ * NXP RT6XX board config
+ * Olimex H405 board config
+ * Radiona ULX3S board config
+ * Raspberry Pi 3 and Raspberry Pi 4 model B board config
+ * Raspberry Pi Pico-Debug board config
+ * Renesas R-Car V3U Falcon board config
+ * ST BlueNRG-LPS steval-idb012v1 board config
+ * ST NUCLEO-8S208RB board config
+ * ST NUCLEO-G031K8, NUCLEO-G070RB, NUCLEO-G071RB board config
+ * ST NUCLEO-G431KB, NUCLEO-G431RB, NUCLEO-G474RE board config
+ * ST STM32MP13x-DK board config
+ * TI AM625 EVM, AM642 EVM and AM654 EVM board config
+ * TI J721E EVM, J721S2 EVM and J7200 EVM board config
+ * Ampere Computing eMAG, Altra ("Quicksilver") and Altra Max ("Mystique") target config
+ * Cadence Xtensa generic and Xtensa VDebug target config
+ * Broadcom BCM2711, BCM2835, BCM2836 and BCM2837 target config
+ * Espressif ESP32, ESP32-S2 and ESP32-S3 target config
+ * Microchip ATSAMA5D2 series target config
+ * NanoXplore NG-Ultra SoC target config
+ * NXP IMX8QM target config
+ * NXP LS1028A, LS1046A and LS1088A target config
+ * NXP RT600 (Xtensa HiFi DSP) target config
+ * onsemi RSL10 target config
+ * Raspberry Pi Pico RP2040 target config
+ * Renesas R8A779A0 V3U target config
+ * Renesas RZ/Five target config
+ * Renesas RZ/G2 MPU family target config
+ * Rockchip RK3399 target config
+ * ST BlueNRG-LPS target config
+ * ST STM32MP13x target config
+ * TI AM625, AM654, J721E and J721S2 target config
+ * Ashling Opella-LD interface config
+ * Aspeed AST2600 linuxgpiod based interface config
+ * Blinkinlabs JTAG_Hat interface config
+ * Cadence Virtual Debug (vdebug) interface config
+ * Espressif ESP32-S2 Kaluga 1 board's interface config
+ * Espressif USB Bridge jtag interface config
+ * Infineon DAP miniWiggler V3 interface config
+ * PLS SPC5 interface config
+ * Tigard interface config
+ * Lattice MachXO3 family FPGA config
+
+Server Layer:
+ * GDB: add per-target remote protocol extensions
+ * GDB: more 'Z' packets support
+ * IPDBG JtagHost server functionality
+ * semihosting: I/O redirection to TCP server
+ * telnet: support for command's autocomplete
+
+RTOS:
+ * 'none' rtos support
+ * Zephyr rtos support
+
+Documentation:
+
+Build and Release:
+ * Add json extension to jimtcl build
+ * Drop dependency from libusb0
+ * Drop repository repo.or.cz for submodules
+ * Move gerrit to https://review.openocd.org/
+ * Require autoconf 2.69 or newer
+ * Update jep106 to revision JEP106BF.01
+ * Update jimtcl to version 0.81
+ * Update libjaylink to version 0.3.1
+ * New configure flag '--enable-jimtcl-maintainer' for jimtcl build
+
+
+This release also contains a number of other important functional and
+cosmetic bugfixes. For more details about what has changed since the
+last release, see the git repository history:
+
+http://sourceforge.net/p/openocd/code/ci/v0.12.0/log/?path=
+
+
+For older NEWS, see the NEWS files associated with each release
+(i.e. NEWS-<version>).
+
+For more information about contributing test reports, bug fixes, or new
+features and device support, please read the new Developer Manual (or
+the BUGS and PATCHES.txt files in the source archive).
diff --git a/README b/README
index 3c07d7c..2f71cfc 100644
--- a/README
+++ b/README
@@ -101,7 +101,7 @@ Supported hardware
JTAG adapters
-------------
-AICE, AM335x, ARM-JTAG-EW, ARM-USB-OCD, ARM-USB-TINY, AT91RM9200, axm0432, BCM2835,
+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,
@@ -122,7 +122,7 @@ 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, NDS32, RISC-V, ST STM8,
+ESP32, ESP32-S2, ESP32-S3, Intel Quark, LS102x-SAP, RISC-V, ST STM8,
Xtensa.
Flash drivers
@@ -219,7 +219,10 @@ You'll also need:
- make
- libtool
-- pkg-config >= 0.23 (or compatible)
+- pkg-config >= 0.23 or pkgconf
+
+OpenOCD uses jimtcl library; build from git can retrieve jimtcl as git
+submodule.
Additionally, for building from git:
@@ -227,14 +230,26 @@ Additionally, for building from git:
- automake >= 1.14
- texinfo >= 5.0
-USB-based adapters depend on libusb-1.0. A compatible implementation, such as
-FreeBSD's, additionally needs the corresponding .pc files.
+Optional USB-based adapter drivers need libusb-1.0.
-USB-Blaster, ASIX Presto and OpenJTAG interface adapter
+Optional USB-Blaster, ASIX Presto and OpenJTAG interface adapter
drivers need:
- libftdi: http://www.intra2net.com/en/developer/libftdi/index.php
-CMSIS-DAP support needs HIDAPI library.
+Optional CMSIS-DAP adapter driver needs HIDAPI library.
+
+Optional linuxgpiod adapter driver needs libgpiod library.
+
+Optional JLink adapter driver needs libjaylink; build from git can
+retrieve libjaylink as git submodule.
+
+Optional ARM disassembly needs capstone library.
+
+Optional development script checkpatch needs:
+
+- perl
+- python
+- python-ply
Permissions delegation
----------------------
diff --git a/configure.ac b/configure.ac
index dacf277..a32fe89 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
AC_PREREQ([2.69])
-AC_INIT([openocd], [0.12.0-rc1+dev],
+AC_INIT([openocd], [0.12.0+dev],
[OpenOCD Mailing List <openocd-devel@lists.sourceforge.net>])
AC_CONFIG_SRCDIR([src/openocd.c])
AC_CONFIG_AUX_DIR([build-aux])
@@ -131,9 +131,6 @@ m4_define([USB1_ADAPTERS],
[[usbprog], [USBProg JTAG Programmer], [USBPROG]],
[[esp_usb_jtag], [Espressif JTAG Programmer], [ESP_USB_JTAG]]])
-m4_define([DEPRECATED_USB1_ADAPTERS],
- [[[aice], [Andes JTAG Programmer (deprecated)], [AICE]]])
-
m4_define([HIDAPI_ADAPTERS],
[[[cmsis_dap], [CMSIS-DAP Compliant Debugger], [CMSIS_DAP_HID]],
[[nulink], [Nu-Link Programmer], [HLADAPTER_NULINK]]])
@@ -265,8 +262,6 @@ AC_ARG_ADAPTERS([
LIBJAYLINK_ADAPTERS
],[auto])
-AC_ARG_ADAPTERS([DEPRECATED_USB1_ADAPTERS],[no])
-
AC_ARG_ENABLE([parport],
AS_HELP_STRING([--enable-parport], [Enable building the pc parallel port driver]),
[build_parport=$enableval], [build_parport=no])
@@ -374,9 +369,9 @@ AC_ARG_ENABLE([jimtcl-maintainer],
[use_internal_jimtcl_maintainer=$enableval], [use_internal_jimtcl_maintainer=no])
AC_ARG_ENABLE([internal-libjaylink],
- AS_HELP_STRING([--disable-internal-libjaylink],
- [Disable building internal libjaylink]),
- [use_internal_libjaylink=$enableval], [use_internal_libjaylink=yes])
+ AS_HELP_STRING([--enable-internal-libjaylink],
+ [Enable building internal libjaylink]),
+ [use_internal_libjaylink=$enableval], [use_internal_libjaylink=no])
AC_ARG_ENABLE([remote-bitbang],
AS_HELP_STRING([--enable-remote-bitbang], [Enable building support for the Remote Bitbang jtag driver]),
@@ -575,7 +570,7 @@ AS_IF([test "x$enable_buspirate" != "xno"], [
])
AS_IF([test "x$use_internal_jimtcl" = "xyes"], [
- AS_IF([test -f "$srcdir/jimtcl/configure.ac"], [
+ AS_IF([test -f "$srcdir/jimtcl/configure"], [
AS_IF([test "x$use_internal_jimtcl_maintainer" = "xyes"], [
jimtcl_config_options="--disable-install-jim --with-ext=json --maintainer"
], [
@@ -632,7 +627,6 @@ AS_IF([test "x$enable_capstone" != xno], [
PKG_CHECK_MODULES([CAPSTONE], [capstone], [
AC_DEFINE([HAVE_CAPSTONE], [1], [1 if you have Capstone disassembly framework.])
], [
- AC_DEFINE([HAVE_CAPSTONE], [0], [0 if you don't have Capstone disassembly framework.])
if test "x$enable_capstone" != xauto; then
AC_MSG_ERROR([--with-capstone was given, but test for Capstone failed])
fi
@@ -640,6 +634,10 @@ 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
@@ -682,7 +680,6 @@ m4_define([PROCESS_ADAPTERS], [
])
PROCESS_ADAPTERS([USB1_ADAPTERS], ["x$use_libusb1" = "xyes"], [libusb-1.x])
-PROCESS_ADAPTERS([DEPRECATED_USB1_ADAPTERS], ["x$use_libusb1" = "xyes"], [libusb-1.x])
PROCESS_ADAPTERS([HIDAPI_ADAPTERS], ["x$use_hidapi" = "xyes"], [hidapi])
PROCESS_ADAPTERS([HIDAPI_USB1_ADAPTERS], ["x$use_hidapi" = "xyes" -a "x$use_libusb1" = "xyes"], [hidapi and libusb-1.x])
PROCESS_ADAPTERS([LIBFTDI_ADAPTERS], ["x$use_libftdi" = "xyes"], [libftdi])
@@ -711,7 +708,7 @@ AS_IF([test "x$enable_jlink" != "xno"], [
AX_CONFIG_SUBDIR_OPTION([src/jtag/drivers/libjaylink],
[--enable-subproject-build])
], [
- AC_MSG_ERROR([Internal libjaylink not found, run either 'git submodule init' and 'git submodule update' or disable internal libjaylink with --disable-internal-libjaylink.])
+ AC_MSG_ERROR([Internal libjaylink not found, run 'git submodule init' and 'git submodule update'.])
])
])
])
@@ -821,12 +818,17 @@ AC_CONFIG_FILES([
])
AC_OUTPUT
+AS_IF([test "x$enable_jlink" != "xno"], [
+ AS_IF([test "x$use_internal_libjaylink" = "xyes"], [
+ AC_MSG_WARN([Using the internal libjaylink is deprecated and will not be possible in the future.])
+ ]])
+)
+
echo
echo
echo OpenOCD configuration summary
echo --------------------------------------------------
m4_foreach([adapter], [USB1_ADAPTERS,
- DEPRECATED_USB1_ADAPTERS,
HIDAPI_ADAPTERS, HIDAPI_USB1_ADAPTERS, LIBFTDI_ADAPTERS,
LIBFTDI_USB1_ADAPTERS,
LIBGPIOD_ADAPTERS,
diff --git a/contrib/buildroot/openocd_be_defconfig b/contrib/buildroot/openocd_be_defconfig
index 2fe28f6..49a6ec2 100644
--- a/contrib/buildroot/openocd_be_defconfig
+++ b/contrib/buildroot/openocd_be_defconfig
@@ -12,7 +12,6 @@ BR2_PACKAGE_OPENOCD_UBLASTER2=y
BR2_PACKAGE_OPENOCD_JLINK=y
BR2_PACKAGE_OPENOCD_OSDBM=y
BR2_PACKAGE_OPENOCD_OPENDOUS=y
-BR2_PACKAGE_OPENOCD_AICE=y
BR2_PACKAGE_OPENOCD_VSLLINK=y
BR2_PACKAGE_OPENOCD_USBPROG=y
BR2_PACKAGE_OPENOCD_RLINK=y
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 115b538..bae0c91 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -1785,7 +1785,6 @@ $_TARGETNAME configure -work-area-phys 0x00200000 \
-work-area-size 0x4000 -work-area-backup 0
@end example
-@anchor{definecputargetsworkinginsmp}
@subsection Define CPU targets working in SMP
@cindex SMP
After setting targets, you can define a list of targets working in SMP.
@@ -1939,7 +1938,6 @@ For an example of this scheme see LPC2000 target config files.
The @code{init_boards} procedure is a similar concept concerning board config files
(@xref{theinitboardprocedure,,The init_board procedure}.)
-@anchor{theinittargeteventsprocedure}
@subsection The init_target_events procedure
@cindex init_target_events procedure
@@ -2468,7 +2466,6 @@ the generic mapping may not support all of the listed options.
Returns the name of the debug adapter driver being used.
@end deffn
-@anchor{adapter_usb_location}
@deffn {Config Command} {adapter usb location} [<bus>-<port>[.<port>]...]
Displays or specifies the physical USB port of the adapter to use. The path
roots at @var{bus} and walks down the physical ports, with each
@@ -2483,7 +2480,7 @@ This command is only available if your libusb1 is at least version 1.0.16.
Specifies the @var{serial_string} of the adapter to use.
If this command is not specified, serial strings are not checked.
Only the following adapter drivers use the serial string from this command:
-aice (aice_usb), arm-jtag-ew, cmsis_dap, ft232r, ftdi, hla (stlink, ti-icdi), jlink, kitprog, opendus,
+arm-jtag-ew, cmsis_dap, ft232r, ftdi, hla (stlink, ti-icdi), jlink, kitprog, opendus,
openjtag, osbdm, presto, rlink, st-link, usb_blaster (ublast2), usbprog, vsllink, xds110.
@end deffn
@@ -3533,11 +3530,11 @@ Espressif JTAG driver to communicate with ESP32-C3, ESP32-S3 chips and ESP USB B
These chips have built-in JTAG circuitry and can be debugged without any additional hardware.
Only an USB cable connected to the D+/D- pins is necessary.
-@deffn {Config Command} {espusbjtag tdo}
+@deffn {Command} {espusbjtag tdo}
Returns the current state of the TDO line
@end deffn
-@deffn {Config Command} {espusbjtag setio} setio
+@deffn {Command} {espusbjtag setio} setio
Manually set the status of the output lines with the order of (tdi tms tck trst srst)
@example
espusbjtag setio 0 1 0 1 0
@@ -4859,9 +4856,6 @@ specified, @xref{gdbportoverride,,option -gdb-port}.), and a fake ARM core will
be emulated to comply to GDB remote protocol.
@item @code{mips_m4k} -- a MIPS core.
@item @code{mips_mips64} -- a MIPS64 core.
-@item @code{nds32_v2} -- this is an Andes NDS32 v2 core (deprecated; would be removed in v0.13.0).
-@item @code{nds32_v3} -- this is an Andes NDS32 v3 core (deprecated; would be removed in v0.13.0).
-@item @code{nds32_v3m} -- this is an Andes NDS32 v3m core (deprecated; would be removed in v0.13.0).
@item @code{or1k} -- this is an OpenRISC 1000 core.
The current implementation supports three JTAG TAP cores:
@itemize @minus
@@ -6236,7 +6230,6 @@ the flash.
@end deffn
@end deffn
-@anchor{at91samd}
@deffn {Flash Driver} {at91samd}
@cindex at91samd
All members of the ATSAM D2x, D1x, D0x, ATSAMR, ATSAML and ATSAMC microcontroller
@@ -8513,12 +8506,20 @@ that particular type of PLD.
@deffn {FPGA Driver} {virtex2} [no_jstart]
Virtex-II is a family of FPGAs sold by Xilinx.
+This driver can also be used to load Series3, Series6, Series7 and Zynq 7000 devices.
It supports the IEEE 1532 standard for In-System Configuration (ISC).
If @var{no_jstart} is non-zero, the JSTART instruction is not used after
loading the bitstream. While required for Series2, Series3, and Series6, it
breaks bitstream loading on Series7.
+@example
+openocd -f board/digilent_zedboard.cfg -c "init" \
+ -c "pld load 0 zedboard_bitstream.bit"
+@end example
+
+
+
@deffn {Command} {virtex2 read_stat} num
Reads and displays the Virtex-II status register (STAT)
for FPGA @var{num}.
@@ -8550,7 +8551,7 @@ command. All output is relayed through the GDB session.
@item @b{Machine Interface}
The Tcl interface's intent is to be a machine interface. The default Tcl
-port is 5555.
+port is 6666.
@end itemize
@@ -9533,14 +9534,14 @@ requests by using a special SVC instruction that is trapped at the
Supervisor Call vector by OpenOCD.
@end deffn
-@deffn {Command} {arm semihosting_redirect} (@option{disable} | @option{tcp} <port>
-[@option{debug}|@option{stdio}|@option{all})
+@deffn {Command} {arm semihosting_redirect} (@option{disable} | @option{tcp} <port> [@option{debug}|@option{stdio}|@option{all}])
@cindex ARM semihosting
Redirect semihosting messages to a specified TCP port.
This command redirects debug (READC, WRITEC and WRITE0) and stdio (READ, WRITE)
semihosting operations to the specified TCP port.
The command allows to select which type of operations to redirect (debug, stdio, all (default)).
+
Note: for stdio operations, only I/O from/to ':tt' file descriptors are redirected.
@end deffn
@@ -10327,6 +10328,16 @@ the target, the exception catch must be disabled again with @command{$target_nam
Issuing the command without options prints the current configuration.
@end deffn
+@deffn {Command} {$target_name pauth} [@option{off}|@option{on}]
+Enable or disable pointer authentication features.
+When pointer authentication is used on ARM cores, GDB asks GDB servers for an 8-bytes mask to remove signature bits added by pointer authentication.
+If this feature is enabled, OpenOCD provides GDB with an 8-bytes mask.
+Pointer authentication feature is broken until gdb 12.1, going to be fixed.
+Consider using a newer version of gdb if you want to enable pauth feature.
+The default configuration is @option{off}.
+@end deffn
+
+
@section EnSilica eSi-RISC Architecture
eSi-RISC is a highly configurable microprocessor architecture for embedded systems
@@ -10724,6 +10735,16 @@ to read out a buffer that's memory-mapped to be accessed through a single
address, or to sample a changing value in a memory-mapped device.
@end deffn
+@deffn {Command} {riscv info}
+Displays some information OpenOCD detected about the target.
+@end deffn
+
+@deffn {Command} {riscv reset_delays} [wait]
+OpenOCD learns how many Run-Test/Idle cycles are required between scans to avoid
+encountering the target being busy. This command resets those learned values
+after `wait` scans. It's only useful for testing OpenOCD itself.
+@end deffn
+
@deffn {Command} {riscv set_command_timeout_sec} [seconds]
Set the wall-clock timeout (in seconds) for individual commands. The default
should work fine for all but the slowest targets (eg. simulators).
@@ -10739,7 +10760,7 @@ Set the address of 16 bytes of scratch RAM the debugger can use, or 'none'.
This is used to access 64-bit floating point registers on 32-bit targets.
@end deffn
-@deffn Command {riscv set_mem_access} method1 [method2] [method3]
+@deffn {Command} {riscv set_mem_access} method1 [method2] [method3]
Specify which RISC-V memory access method(s) shall be used, and in which order
of priority. At least one method must be specified.
@@ -11164,12 +11185,12 @@ NXP}.
@subsection Xtensa Configuration Commands
-@deffn {Command} {xtensa xtdef} (@option{LX}|@option{NX})
+@deffn {Config Command} {xtensa xtdef} (@option{LX}|@option{NX})
Configure the Xtensa target architecture. Currently, Xtensa support is limited
to LX6, LX7, and NX cores.
@end deffn
-@deffn {Command} {xtensa xtopt} option value
+@deffn {Config Command} {xtensa xtopt} option value
Configure Xtensa target options that are relevant to the debug subsystem.
@var{option} is one of: @option{arnum}, @option{windowed},
@option{cpenable}, @option{exceptions}, @option{intnum}, @option{hipriints},
@@ -11181,35 +11202,35 @@ NOTE: Some options are specific to Xtensa LX or Xtensa NX architecture, while
others may be common to both but have different valid ranges.
@end deffn
-@deffn {Command} {xtensa xtmem} (@option{iram}|@option{dram}|@option{sram}|@option{irom}|@option{drom}|@option{srom}) baseaddr bytes
+@deffn {Config Command} {xtensa xtmem} (@option{iram}|@option{dram}|@option{sram}|@option{irom}|@option{drom}|@option{srom}) baseaddr bytes
Configure Xtensa target memory. Memory type determines access rights,
where RAMs are read/write while ROMs are read-only. @var{baseaddr} and
@var{bytes} are both integers, typically hexadecimal and decimal, respectively.
@end deffn
-@deffn {Command} {xtensa xtmem} (@option{icache}|@option{dcache}) linebytes cachebytes ways [writeback]
+@deffn {Config Command} {xtensa xtmem} (@option{icache}|@option{dcache}) linebytes cachebytes ways [writeback]
Configure Xtensa processor cache. All parameters are required except for
the optional @option{writeback} parameter; all are integers.
@end deffn
-@deffn {Command} {xtensa xtmpu} numfgseg minsegsz lockable execonly
+@deffn {Config Command} {xtensa xtmpu} numfgseg minsegsz lockable execonly
Configure an Xtensa Memory Protection Unit (MPU). MPUs can restrict access
and/or control cacheability of specific address ranges, but are lighter-weight
than a full traditional MMU. All parameters are required; all are integers.
@end deffn
-@deffn {Command} {xtensa xtmmu} numirefillentries numdrefillentries
+@deffn {Config Command} {xtensa xtmmu} numirefillentries numdrefillentries
(Xtensa-LX only) Configure an Xtensa Memory Management Unit (MMU). Both
parameters are required; both are integers.
@end deffn
-@deffn {Command} {xtensa xtregs} numregs
+@deffn {Config Command} {xtensa xtregs} numregs
Configure the total number of registers for the Xtensa core. Configuration
logic expects to subsequently process this number of @code{xtensa xtreg}
definitions. @var{numregs} is an integer.
@end deffn
-@deffn {Command} {xtensa xtregfmt} (@option{sparse}|@option{contiguous}) [general]
+@deffn {Config Command} {xtensa xtregfmt} (@option{sparse}|@option{contiguous}) [general]
Configure the type of register map used by GDB to access the Xtensa core.
Generic Xtensa tools (e.g. xt-gdb) require @option{sparse} mapping (default) while
Espressif tools expect @option{contiguous} mapping. Contiguous mapping takes an
@@ -11217,7 +11238,7 @@ additional, optional integer parameter @option{numgregs}, which specifies the nu
of general registers used in handling g/G packets.
@end deffn
-@deffn {Command} {xtensa xtreg} name offset
+@deffn {Config Command} {xtensa xtreg} name offset
Configure an Xtensa core register. All core registers are 32 bits wide,
while TIE and user registers may have variable widths. @var{name} is a
character string identifier while @var{offset} is a hexadecimal integer.
diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c
index a0252a2..33e86c7 100644
--- a/src/flash/nor/at91samd.c
+++ b/src/flash/nor/at91samd.c
@@ -12,6 +12,7 @@
#include "imp.h"
#include "helper/binarybuffer.h"
+#include <helper/time_support.h>
#include <jtag/jtag.h>
#include <target/cortex_m.h>
@@ -31,7 +32,7 @@
#define SAMD_NVMCTRL_CTRLA 0x00 /* NVM control A register */
#define SAMD_NVMCTRL_CTRLB 0x04 /* NVM control B register */
#define SAMD_NVMCTRL_PARAM 0x08 /* NVM parameters register */
-#define SAMD_NVMCTRL_INTFLAG 0x18 /* NVM Interrupt Flag Status & Clear */
+#define SAMD_NVMCTRL_INTFLAG 0x14 /* NVM Interrupt Flag Status & Clear */
#define SAMD_NVMCTRL_STATUS 0x18 /* NVM status register */
#define SAMD_NVMCTRL_ADDR 0x1C /* NVM address register */
#define SAMD_NVMCTRL_LOCK 0x20 /* NVM Lock section register */
@@ -55,6 +56,9 @@
/* NVMCTRL bits */
#define SAMD_NVM_CTRLB_MANW 0x80
+/* NVMCTRL_INTFLAG bits */
+#define SAMD_NVM_INTFLAG_READY 0x01
+
/* Known identifiers */
#define SAMD_PROCESSOR_M0 0x01
#define SAMD_FAMILY_D 0x00
@@ -497,7 +501,27 @@ static int samd_probe(struct flash_bank *bank)
static int samd_check_error(struct target *target)
{
int ret, ret2;
+ uint8_t intflag;
uint16_t status;
+ int timeout_ms = 1000;
+ int64_t ts_start = timeval_ms();
+
+ do {
+ ret = target_read_u8(target,
+ SAMD_NVMCTRL + SAMD_NVMCTRL_INTFLAG, &intflag);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Can't read NVM intflag");
+ return ret;
+ }
+ if (intflag & SAMD_NVM_INTFLAG_READY)
+ break;
+ keep_alive();
+ } while (timeval_ms() - ts_start < timeout_ms);
+
+ if (!(intflag & SAMD_NVM_INTFLAG_READY)) {
+ LOG_ERROR("SAMD: NVM programming timed out");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
ret = target_read_u16(target,
SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, &status);
@@ -543,7 +567,8 @@ static int samd_issue_nvmctrl_command(struct target *target, uint16_t cmd)
}
/* Issue the NVM command */
- res = target_write_u16(target,
+ /* 32-bit write is used to ensure atomic operation on ST-Link */
+ res = target_write_u32(target,
SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLA, SAMD_NVM_CMD(cmd));
if (res != ERROR_OK)
return res;
diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c
index 0e2e263..1d317a1 100644
--- a/src/flash/nor/avrf.c
+++ b/src/flash/nor/avrf.c
@@ -64,6 +64,7 @@ static const struct avrf_type avft_chips_info[] = {
{"atmega324pa", 0x9511, 128, 256, 4, 256},
{"atmega644p", 0x960a, 256, 256, 8, 256},
{"atmega1284p", 0x9705, 256, 512, 8, 512},
+ {"atmega32u4", 0x9587, 128, 256, 4, 256},
};
/* avr program functions */
diff --git a/src/flash/nor/lpc2900.c b/src/flash/nor/lpc2900.c
index c30fa76..948def9 100644
--- a/src/flash/nor/lpc2900.c
+++ b/src/flash/nor/lpc2900.c
@@ -1132,9 +1132,9 @@ static int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer,
* reduced size if that fails. */
struct working_area *warea;
uint32_t buffer_size = lpc2900_info->max_ram_block - 1 * KiB;
- while ((retval = target_alloc_working_area_try(target,
+ while (target_alloc_working_area_try(target,
buffer_size + target_code_size,
- &warea)) != ERROR_OK) {
+ &warea) != ERROR_OK) {
/* Try a smaller buffer now, and stop if it's too small. */
buffer_size -= 1 * KiB;
if (buffer_size < 2 * KiB) {
diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c
index 667498c..b0d118b 100644
--- a/src/flash/nor/rp2040.c
+++ b/src/flash/nor/rp2040.c
@@ -50,6 +50,10 @@ struct rp2040_flash_bank {
const struct flash_device *dev;
};
+/* guessed SPI flash description if autodetection disabled (same as win w25q16jv) */
+static const struct flash_device rp2040_default_spi_device =
+ FLASH_ID("autodetect disabled", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0, 0x100, 0x10000, 0);
+
static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16_t *symbol)
{
uint32_t magic;
@@ -87,7 +91,7 @@ static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16
}
static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank *priv,
- uint16_t func_offset, uint32_t argdata[], unsigned int n_args)
+ uint16_t func_offset, uint32_t argdata[], unsigned int n_args, int timeout_ms)
{
char *regnames[4] = { "r0", "r1", "r2", "r3" };
@@ -99,8 +103,7 @@ static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank
}
target_addr_t stacktop = priv->stack->address + priv->stack->size;
- LOG_DEBUG("Calling ROM func @0x%" PRIx16 " with %d arguments", func_offset, n_args);
- LOG_DEBUG("Calling on core \"%s\"", target->cmd_name);
+ LOG_TARGET_DEBUG(target, "Calling ROM func @0x%" PRIx16 " with %u arguments", func_offset, n_args);
struct reg_param args[ARRAY_SIZE(regnames) + 2];
struct armv7m_algorithm alg_info;
@@ -112,11 +115,12 @@ static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank
/* Pass function pointer in r7 */
init_reg_param(&args[n_args], "r7", 32, PARAM_OUT);
buf_set_u32(args[n_args].value, 0, 32, func_offset);
+ /* Setup stack */
init_reg_param(&args[n_args + 1], "sp", 32, PARAM_OUT);
buf_set_u32(args[n_args + 1].value, 0, 32, stacktop);
+ unsigned int n_reg_params = n_args + 2; /* User arguments + r7 + sp */
-
- for (unsigned int i = 0; i < n_args + 2; ++i)
+ for (unsigned int i = 0; i < n_reg_params; ++i)
LOG_DEBUG("Set %s = 0x%" PRIx32, args[i].reg_name, buf_get_u32(args[i].value, 0, 32));
/* Actually call the function */
@@ -125,42 +129,82 @@ static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank
int err = target_run_algorithm(
target,
0, NULL, /* No memory arguments */
- n_args + 1, args, /* User arguments + r7 */
+ n_reg_params, args, /* User arguments + r7 + sp */
priv->jump_debug_trampoline, priv->jump_debug_trampoline_end,
- 3000, /* 3s timeout */
+ timeout_ms,
&alg_info
);
- for (unsigned int i = 0; i < n_args + 2; ++i)
+
+ for (unsigned int i = 0; i < n_reg_params; ++i)
destroy_reg_param(&args[i]);
+
if (err != ERROR_OK)
- LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16 "\n", func_offset);
+ LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16, func_offset);
+
return err;
+}
+
+/* Finalize flash write/erase/read ID
+ * - flush cache
+ * - enters memory-mapped (XIP) mode to make flash data visible
+ * - deallocates target ROM func stack if previously allocated
+ */
+static int rp2040_finalize_stack_free(struct flash_bank *bank)
+{
+ struct rp2040_flash_bank *priv = bank->driver_priv;
+ struct target *target = bank->target;
+
+ /* Always flush before returning to execute-in-place, to invalidate stale
+ * cache contents. The flush call also restores regular hardware-controlled
+ * chip select following a rp2040_flash_exit_xip().
+ */
+ LOG_DEBUG("Flushing flash cache after write behind");
+ int err = rp2040_call_rom_func(target, priv, priv->jump_flush_cache, NULL, 0, 1000);
+ if (err != ERROR_OK) {
+ LOG_ERROR("Failed to flush flash cache");
+ /* Intentionally continue after error and try to setup xip anyway */
+ }
+
+ LOG_DEBUG("Configuring SSI for execute-in-place");
+ err = rp2040_call_rom_func(target, priv, priv->jump_enter_cmd_xip, NULL, 0, 1000);
+ if (err != ERROR_OK)
+ LOG_ERROR("Failed to set SSI to XIP mode");
+ target_free_working_area(target, priv->stack);
+ priv->stack = NULL;
+ return err;
}
-static int stack_grab_and_prep(struct flash_bank *bank)
+/* Prepare flash write/erase/read ID
+ * - allocates a stack for target ROM func
+ * - switches the SPI interface from memory-mapped mode to direct command mode
+ * Always pair with a call of rp2040_finalize_stack_free()
+ * after flash operation finishes or fails.
+ */
+static int rp2040_stack_grab_and_prep(struct flash_bank *bank)
{
struct rp2040_flash_bank *priv = bank->driver_priv;
+ struct target *target = bank->target;
/* target_alloc_working_area always allocates multiples of 4 bytes, so no worry about alignment */
const int STACK_SIZE = 256;
- int err = target_alloc_working_area(bank->target, STACK_SIZE, &priv->stack);
+ int err = target_alloc_working_area(target, STACK_SIZE, &priv->stack);
if (err != ERROR_OK) {
LOG_ERROR("Could not allocate stack for flash programming code");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
LOG_DEBUG("Connecting internal flash");
- err = rp2040_call_rom_func(bank->target, priv, priv->jump_connect_internal_flash, NULL, 0);
+ err = rp2040_call_rom_func(target, priv, priv->jump_connect_internal_flash, NULL, 0, 1000);
if (err != ERROR_OK) {
- LOG_ERROR("RP2040 erase: failed to connect internal flash");
+ LOG_ERROR("Failed to connect internal flash");
return err;
}
LOG_DEBUG("Kicking flash out of XIP mode");
- err = rp2040_call_rom_func(bank->target, priv, priv->jump_flash_exit_xip, NULL, 0);
+ err = rp2040_call_rom_func(target, priv, priv->jump_flash_exit_xip, NULL, 0, 1000);
if (err != ERROR_OK) {
- LOG_ERROR("RP2040 erase: failed to exit flash XIP mode");
+ LOG_ERROR("Failed to exit flash XIP mode");
return err;
}
@@ -173,16 +217,27 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui
struct rp2040_flash_bank *priv = bank->driver_priv;
struct target *target = bank->target;
- struct working_area *bounce;
- int err = stack_grab_and_prep(bank);
- if (err != ERROR_OK)
- return err;
+ if (target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ struct working_area *bounce = NULL;
- const unsigned int chunk_size = target_get_working_area_avail(target);
- if (target_alloc_working_area(target, chunk_size, &bounce) != ERROR_OK) {
+ int err = rp2040_stack_grab_and_prep(bank);
+ if (err != ERROR_OK)
+ goto cleanup;
+
+ unsigned int avail_pages = target_get_working_area_avail(target) / priv->dev->pagesize;
+ /* We try to allocate working area rounded down to device page size,
+ * al least 1 page, at most the write data size
+ */
+ unsigned int chunk_size = MIN(MAX(avail_pages, 1) * priv->dev->pagesize, count);
+ err = target_alloc_working_area(target, chunk_size, &bounce);
+ if (err != ERROR_OK) {
LOG_ERROR("Could not allocate bounce buffer for flash programming. Can't continue");
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ goto cleanup;
}
LOG_DEBUG("Allocated flash bounce buffer @" TARGET_ADDR_FMT, bounce->address);
@@ -200,7 +255,8 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui
bounce->address, /* data */
write_size /* count */
};
- err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_program, args, ARRAY_SIZE(args));
+ err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_program,
+ args, ARRAY_SIZE(args), 3000);
if (err != ERROR_OK) {
LOG_ERROR("Failed to invoke flash programming code on target");
break;
@@ -210,36 +266,32 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui
offset += write_size;
count -= write_size;
}
+
+cleanup:
target_free_working_area(target, bounce);
- if (err != ERROR_OK)
- return err;
+ rp2040_finalize_stack_free(bank);
- /* Flash is successfully programmed. We can now do a bit of poking to make the flash
- contents visible to us via memory-mapped (XIP) interface in the 0x1... memory region */
- LOG_DEBUG("Flushing flash cache after write behind");
- err = rp2040_call_rom_func(bank->target, priv, priv->jump_flush_cache, NULL, 0);
- if (err != ERROR_OK) {
- LOG_ERROR("RP2040 write: failed to flush flash cache");
- return err;
- }
- LOG_DEBUG("Configuring SSI for execute-in-place");
- err = rp2040_call_rom_func(bank->target, priv, priv->jump_enter_cmd_xip, NULL, 0);
- if (err != ERROR_OK)
- LOG_ERROR("RP2040 write: failed to flush flash cache");
return err;
}
static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
{
struct rp2040_flash_bank *priv = bank->driver_priv;
+ struct target *target = bank->target;
+
+ if (target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
uint32_t start_addr = bank->sectors[first].offset;
uint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr;
LOG_DEBUG("RP2040 erase %d bytes starting at 0x%" PRIx32, length, start_addr);
- int err = stack_grab_and_prep(bank);
+ int err = rp2040_stack_grab_and_prep(bank);
if (err != ERROR_OK)
- return err;
+ goto cleanup;
LOG_DEBUG("Remote call flash_range_erase");
@@ -257,10 +309,15 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig
https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c
In theory, the function algorithm provides for erasing both a smaller "sector" (4096 bytes) and
- an optional larger "block" (size and command provided in args). OpenOCD's spi.c only uses "block" sizes.
+ an optional larger "block" (size and command provided in args).
*/
- err = rp2040_call_rom_func(bank->target, priv, priv->jump_flash_range_erase, args, ARRAY_SIZE(args));
+ int timeout_ms = 2000 * (last - first) + 1000;
+ err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_erase,
+ args, ARRAY_SIZE(args), timeout_ms);
+
+cleanup:
+ rp2040_finalize_stack_free(bank);
return err;
}
@@ -289,11 +346,46 @@ static int rp2040_ssel_active(struct target *target, bool active)
return ERROR_OK;
}
+static int rp2040_spi_read_flash_id(struct target *target, uint32_t *devid)
+{
+ uint32_t device_id = 0;
+ const target_addr_t ssi_dr0 = 0x18000060;
+
+ int err = rp2040_ssel_active(target, true);
+
+ /* write RDID request into SPI peripheral's FIFO */
+ for (int count = 0; (count < 4) && (err == ERROR_OK); count++)
+ err = target_write_u32(target, ssi_dr0, SPIFLASH_READ_ID);
+
+ /* by this time, there is a receive FIFO entry for every write */
+ for (int count = 0; (count < 4) && (err == ERROR_OK); count++) {
+ uint32_t status;
+ err = target_read_u32(target, ssi_dr0, &status);
+
+ device_id >>= 8;
+ device_id |= (status & 0xFF) << 24;
+ }
+
+ if (err == ERROR_OK)
+ *devid = device_id >> 8;
+
+ int err2 = rp2040_ssel_active(target, false);
+ if (err2 != ERROR_OK)
+ LOG_ERROR("SSEL inactive failed");
+
+ return err;
+}
+
static int rp2040_flash_probe(struct flash_bank *bank)
{
struct rp2040_flash_bank *priv = bank->driver_priv;
struct target *target = bank->target;
+ if (target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
int err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE, &priv->jump_debug_trampoline);
if (err != ERROR_OK) {
LOG_ERROR("Debug trampoline not found in RP2040 ROM.");
@@ -344,59 +436,48 @@ static int rp2040_flash_probe(struct flash_bank *bank)
return err;
}
- err = stack_grab_and_prep(bank);
- if (err != ERROR_OK)
- return err;
+ if (bank->size) {
+ /* size overridden, suppress reading SPI flash ID */
+ priv->dev = &rp2040_default_spi_device;
+ LOG_DEBUG("SPI flash autodetection disabled, using configured size");
- uint32_t device_id = 0;
- const target_addr_t ssi_dr0 = 0x18000060;
-
- err = rp2040_ssel_active(target, true);
+ } else {
+ /* zero bank size in cfg, read SPI flash ID and autodetect */
+ err = rp2040_stack_grab_and_prep(bank);
- /* write RDID request into SPI peripheral's FIFO */
- for (int count = 0; (count < 4) && (err == ERROR_OK); count++)
- err = target_write_u32(target, ssi_dr0, SPIFLASH_READ_ID);
+ uint32_t device_id = 0;
+ if (err == ERROR_OK)
+ err = rp2040_spi_read_flash_id(target, &device_id);
- /* by this time, there is a receive FIFO entry for every write */
- for (int count = 0; (count < 4) && (err == ERROR_OK); count++) {
- uint32_t status;
- err = target_read_u32(target, ssi_dr0, &status);
+ rp2040_finalize_stack_free(bank);
- device_id >>= 8;
- device_id |= (status & 0xFF) << 24;
- }
- device_id >>= 8;
-
- err = rp2040_ssel_active(target, false);
- if (err != ERROR_OK) {
- LOG_ERROR("SSEL inactive failed");
- return err;
- }
+ if (err != ERROR_OK)
+ return err;
- /* search for a SPI flash Device ID match */
- priv->dev = NULL;
- for (const struct flash_device *p = flash_devices; p->name ; p++)
- if (p->device_id == device_id) {
- priv->dev = p;
- break;
+ /* search for a SPI flash Device ID match */
+ priv->dev = NULL;
+ for (const struct flash_device *p = flash_devices; p->name ; p++)
+ if (p->device_id == device_id) {
+ priv->dev = p;
+ break;
+ }
+
+ if (!priv->dev) {
+ LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", device_id);
+ return ERROR_FAIL;
}
+ LOG_INFO("Found flash device '%s' (ID 0x%08" PRIx32 ")",
+ priv->dev->name, priv->dev->device_id);
- if (!priv->dev) {
- LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", device_id);
- return ERROR_FAIL;
+ bank->size = priv->dev->size_in_bytes;
}
- LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
- priv->dev->name, priv->dev->device_id);
-
/* the Boot ROM flash_range_program() routine requires page alignment */
bank->write_start_alignment = priv->dev->pagesize;
bank->write_end_alignment = priv->dev->pagesize;
- bank->size = priv->dev->size_in_bytes;
-
bank->num_sectors = bank->size / priv->dev->sectorsize;
- LOG_INFO("RP2040 B0 Flash Probe: %d bytes @" TARGET_ADDR_FMT ", in %d sectors\n",
+ LOG_INFO("RP2040 B0 Flash Probe: %" PRIu32 " bytes @" TARGET_ADDR_FMT ", in %u sectors\n",
bank->size, bank->base, bank->num_sectors);
bank->sectors = alloc_block_array(0, priv->dev->sectorsize, bank->num_sectors);
if (!bank->sectors)
diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c
index eed747b..373a9a1 100644
--- a/src/flash/nor/spi.c
+++ b/src/flash/nor/spi.c
@@ -112,6 +112,7 @@ const struct flash_device flash_devices[] = {
FLASH_ID("gd gd25q128c", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001840c8, 0x100, 0x10000, 0x1000000),
FLASH_ID("gd gd25q256c", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x001940c8, 0x100, 0x10000, 0x2000000),
FLASH_ID("gd gd25q512mc", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x002040c8, 0x100, 0x10000, 0x4000000),
+ FLASH_ID("issi is25lq040b", 0x03, 0xeb, 0x02, 0x20, 0xc7, 0x0013409d, 0x100, 0x1000, 0x80000),
FLASH_ID("issi is25lp032", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0016609d, 0x100, 0x10000, 0x400000),
FLASH_ID("issi is25lp064", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0017609d, 0x100, 0x10000, 0x800000),
FLASH_ID("issi is25lp128d", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0018609d, 0x100, 0x10000, 0x1000000),
diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c
index 292b66d..04f4da0 100644
--- a/src/flash/nor/stm32f1x.c
+++ b/src/flash/nor/stm32f1x.c
@@ -473,7 +473,7 @@ static int stm32x_write_block_async(struct flash_bank *bank, const uint8_t *buff
/* memory buffer */
buffer_size = target_get_working_area_avail(target);
- buffer_size = MIN(hwords_count * 2, MAX(buffer_size, 256));
+ buffer_size = MIN(hwords_count * 2 + 8, MAX(buffer_size, 256));
/* Normally we allocate all available working area.
* MIN shrinks buffer_size if the size of the written block is smaller.
* MAX prevents using async algo if the available working area is smaller
diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c
index 860bab3..0c76ed7 100644
--- a/src/flash/nor/stm32lx.c
+++ b/src/flash/nor/stm32lx.c
@@ -132,7 +132,7 @@ static const struct stm32lx_rev stm32_417_revs[] = {
{ 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" }, { 0x1038, "X" }
};
static const struct stm32lx_rev stm32_425_revs[] = {
- { 0x1000, "A" }, { 0x2000, "B" }, { 0x2008, "Y" },
+ { 0x1000, "A" }, { 0x2000, "B" }, { 0x2008, "Y" }, { 0x2018, "1, X" },
};
static const struct stm32lx_rev stm32_427_revs[] = {
{ 0x1000, "A" }, { 0x1018, "Y" }, { 0x1038, "X" }, { 0x10f8, "V" },
diff --git a/src/flash/nor/stmqspi.c b/src/flash/nor/stmqspi.c
index 9c266e9..77ea4c4 100644
--- a/src/flash/nor/stmqspi.c
+++ b/src/flash/nor/stmqspi.c
@@ -616,8 +616,6 @@ COMMAND_HANDLER(stmqspi_handle_set)
LOG_DEBUG("%s", __func__);
- dual = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 1 : 0;
-
/* chip_erase_cmd, sectorsize and erase_cmd are optional */
if ((CMD_ARGC < 7) || (CMD_ARGC > 10))
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -628,8 +626,9 @@ COMMAND_HANDLER(stmqspi_handle_set)
target = bank->target;
stmqspi_info = bank->driver_priv;
+ dual = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 1 : 0;
- /* invalidate all old info */
+ /* invalidate all flash device info */
if (stmqspi_info->probed)
free(bank->sectors);
bank->size = 0;
@@ -721,10 +720,8 @@ COMMAND_HANDLER(stmqspi_handle_set)
uint32_t dcr;
retval = target_read_u32(target, io_base + SPI_DCR, &dcr);
-
if (retval != ERROR_OK)
return retval;
-
fsize = (dcr >> SPI_FSIZE_POS) & (BIT(SPI_FSIZE_LEN) - 1);
LOG_DEBUG("FSIZE = 0x%04x", fsize);
@@ -1799,7 +1796,6 @@ static int find_sfdp_dummy(struct flash_bank *bank, int len)
}
}
- retval = ERROR_FAIL;
LOG_DEBUG("no start of SFDP header even after %u dummy bytes", count);
err:
@@ -2081,16 +2077,17 @@ static int stmqspi_probe(struct flash_bank *bank)
bool octal_dtr;
int retval;
- if (stmqspi_info->probed) {
- bank->size = 0;
- bank->num_sectors = 0;
+ /* invalidate all flash device info */
+ if (stmqspi_info->probed)
free(bank->sectors);
- bank->sectors = NULL;
- memset(&stmqspi_info->dev, 0, sizeof(stmqspi_info->dev));
- stmqspi_info->sfdp_dummy1 = 0;
- stmqspi_info->sfdp_dummy2 = 0;
- stmqspi_info->probed = false;
- }
+ bank->size = 0;
+ bank->num_sectors = 0;
+ bank->sectors = NULL;
+ stmqspi_info->sfdp_dummy1 = 0;
+ stmqspi_info->sfdp_dummy2 = 0;
+ stmqspi_info->probed = false;
+ memset(&stmqspi_info->dev, 0, sizeof(stmqspi_info->dev));
+ stmqspi_info->dev.name = "unknown";
/* Abort any previous operation */
retval = stmqspi_abort(bank);
@@ -2105,8 +2102,8 @@ static int stmqspi_probe(struct flash_bank *bank)
/* check whether QSPI_ABR is writeable and readback returns the value written */
retval = target_write_u32(target, io_base + QSPI_ABR, magic);
if (retval == ERROR_OK) {
- retval = target_read_u32(target, io_base + QSPI_ABR, &data);
- retval = target_write_u32(target, io_base + QSPI_ABR, 0);
+ (void)target_read_u32(target, io_base + QSPI_ABR, &data);
+ (void)target_write_u32(target, io_base + QSPI_ABR, 0);
}
if (data == magic) {
diff --git a/src/helper/command.c b/src/helper/command.c
index 6898e2d..ca66cf7 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -936,19 +936,7 @@ static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *a
if (!command_can_run(cmd_ctx, c, Jim_GetString(argv[0], NULL)))
return JIM_ERR;
- /*
- * TODO: to be removed after v0.12.0
- * workaround for https://sourceforge.net/p/openocd/tickets/362/
- * After syntax change of "expr" in jimtcl 0.81
- * the replacement of jimtcl "expr" with openocd version in
- * https://review.openocd.org/6510/
- * introduces too many target polling during math expressions with
- * "expr" commands.
- * After v0.12.0 replace the following two lines with
- * target_call_timer_callbacks();
- */
- if (strcmp(c->name, "expr"))
- target_call_timer_callbacks_now();
+ target_call_timer_callbacks();
/*
* Black magic of overridden current target:
diff --git a/src/helper/jep106.inc b/src/helper/jep106.inc
index 01c3aac..cb67b92 100644
--- a/src/helper/jep106.inc
+++ b/src/helper/jep106.inc
@@ -8,7 +8,7 @@
* identification code list, please visit the JEDEC website at www.jedec.org .
*/
-/* This file is aligned to revision JEP106BE January 2022. */
+/* This file is aligned to revision JEP106BF.01 October 2022. */
[0][0x01 - 1] = "AMD",
[0][0x02 - 1] = "AMI",
@@ -149,7 +149,7 @@
[1][0x0b - 1] = "Bestlink Systems",
[1][0x0c - 1] = "Graychip",
[1][0x0d - 1] = "GENNUM",
-[1][0x0e - 1] = "VideoLogic",
+[1][0x0e - 1] = "Imagination Technologies Limited",
[1][0x0f - 1] = "Robert Bosch",
[1][0x10 - 1] = "Chip Express",
[1][0x11 - 1] = "DATARAM",
@@ -1501,7 +1501,7 @@
[11][0x67 - 1] = "Guangzhou Shuvrwine Technology Co",
[11][0x68 - 1] = "Shenzhen Hangshun Chip Technology",
[11][0x69 - 1] = "Chengboliwei Electronic Business",
-[11][0x6a - 1] = "Kowin Memory Technology Co Ltd",
+[11][0x6a - 1] = "Kowin Technology HK Limited",
[11][0x6b - 1] = "Euronet Technology Inc",
[11][0x6c - 1] = "SCY",
[11][0x6d - 1] = "Shenzhen Xinhongyusheng Electrical",
@@ -1705,4 +1705,85 @@
[13][0x37 - 1] = "ORICO Technologies Co. Ltd.",
[13][0x38 - 1] = "Space Exploration Technologies Corp",
[13][0x39 - 1] = "AONDEVICES Inc",
+[13][0x3a - 1] = "Shenzhen Netforward Micro Electronic",
+[13][0x3b - 1] = "Syntacore Ltd",
+[13][0x3c - 1] = "Shenzhen Secmem Microelectronics Co",
+[13][0x3d - 1] = "ONiO As",
+[13][0x3e - 1] = "Shenzhen Peladn Technology Co Ltd",
+[13][0x3f - 1] = "O-Cubes Shanghai Microelectronics",
+[13][0x40 - 1] = "ASTC",
+[13][0x41 - 1] = "UMIS",
+[13][0x42 - 1] = "Paradromics",
+[13][0x43 - 1] = "Sinh Micro Co Ltd",
+[13][0x44 - 1] = "Metorage Semiconductor Technology Co",
+[13][0x45 - 1] = "Aeva Inc",
+[13][0x46 - 1] = "HongKong Hyunion Electronics Co Ltd",
+[13][0x47 - 1] = "China Flash Co Ltd",
+[13][0x48 - 1] = "Sunplus Technology Co Ltd",
+[13][0x49 - 1] = "Idaho Scientific",
+[13][0x4a - 1] = "Suzhou SF Micro Electronics Co Ltd",
+[13][0x4b - 1] = "IMEX Cap AG",
+[13][0x4c - 1] = "Fitipower Integrated Technology Co Ltd",
+[13][0x4d - 1] = "ShenzhenWooacme Technology Co Ltd",
+[13][0x4e - 1] = "KeepData Original Chips",
+[13][0x4f - 1] = "Rivos Inc",
+[13][0x50 - 1] = "Big Innovation Company Limited",
+[13][0x51 - 1] = "Wuhan YuXin Semiconductor Co Ltd",
+[13][0x52 - 1] = "United Memory Technology (Jiangsu)",
+[13][0x53 - 1] = "PQShield Ltd",
+[13][0x54 - 1] = "ArchiTek Corporation",
+[13][0x55 - 1] = "ShenZhen AZW Technology Co Ltd",
+[13][0x56 - 1] = "Hengchi Zhixin (Dongguan) Technology",
+[13][0x57 - 1] = "Eggtronic Engineering Spa",
+[13][0x58 - 1] = "Fusontai Technology",
+[13][0x59 - 1] = "PULP Platform",
+[13][0x5a - 1] = "Koitek Electronic Technology (Shenzhen) Co",
+[13][0x5b - 1] = "Shenzhen Jiteng Network Technology Co",
+[13][0x5c - 1] = "Aviva Links Inc",
+[13][0x5d - 1] = "Trilinear Technologies Inc",
+[13][0x5e - 1] = "Shenzhen Developer Microelectronics Co",
+[13][0x5f - 1] = "Guangdong OPPO Mobile Telecommunication",
+[13][0x60 - 1] = "Akeana",
+[13][0x61 - 1] = "Lyczar",
+[13][0x62 - 1] = "Shenzhen Qiji Technology Co Ltd",
+[13][0x63 - 1] = "Shenzhen Shangzhaoyuan Technology",
+[13][0x64 - 1] = "Han Stor",
+[13][0x65 - 1] = "China Micro Semicon Co., Ltd.",
+[13][0x66 - 1] = "Shenzhen Zhuqin Technology Co Ltd",
+[13][0x67 - 1] = "Shanghai Ningyuan Electronic Technology",
+[13][0x68 - 1] = "Auradine",
+[13][0x69 - 1] = "Suzhou Yishuo Electronics Co Ltd",
+[13][0x6a - 1] = "Faurecia Clarion Electronics",
+[13][0x6b - 1] = "SiMa Technologies",
+[13][0x6c - 1] = "CFD Sales Inc",
+[13][0x6d - 1] = "Suzhou Comay Information Co Ltd",
+[13][0x6e - 1] = "Yentek",
+[13][0x6f - 1] = "Qorvo Inc",
+[13][0x70 - 1] = "Shenzhen Youzhi Computer Technology",
+[13][0x71 - 1] = "Sychw Technology (Shenzhen) Co Ltd",
+[13][0x72 - 1] = "MK Founder Technology Co Ltd",
+[13][0x73 - 1] = "Siliconwaves Technologies Co Ltd",
+[13][0x74 - 1] = "Hongkong Hyunion Electronics Co Ltd",
+[13][0x75 - 1] = "Shenzhen Xinxinzhitao Electronics Business",
+[13][0x76 - 1] = "Shenzhen HenQi Electronic Commerce Co",
+[13][0x77 - 1] = "Shenzhen Jingyi Technology Co Ltd",
+[13][0x78 - 1] = "Xiaohua Semiconductor Co. Ltd.",
+[13][0x79 - 1] = "Shenzhen Dalu Semiconductor Technology",
+[13][0x7a - 1] = "Shenzhen Ninespeed Electronics Co Ltd",
+[13][0x7b - 1] = "ICYC Semiconductor Co Ltd",
+[13][0x7c - 1] = "Shenzhen Jaguar Microsystems Co Ltd",
+[13][0x7d - 1] = "Beijing EC-Founder Co Ltd",
+[13][0x7e - 1] = "Shenzhen Taike Industrial Automation Co",
+[14][0x01 - 1] = "Kalray SA",
+[14][0x02 - 1] = "Shanghai Iluvatar CoreX Semiconductor Co",
+[14][0x03 - 1] = "Fungible Inc",
+[14][0x04 - 1] = "Song Industria E Comercio de Eletronicos",
+[14][0x05 - 1] = "DreamBig Semiconductor Inc",
+[14][0x06 - 1] = "ChampTek Electronics Corp",
+[14][0x07 - 1] = "Fusontai Technology",
+[14][0x08 - 1] = "Endress Hauser AG",
+[14][0x09 - 1] = "altec ComputerSysteme GmbH",
+[14][0x0a - 1] = "UltraRISC Technology (Shanghai) Co Ltd",
+[14][0x0b - 1] = "Shenzhen Jing Da Kang Technology Co Ltd",
+[14][0x0c - 1] = "Hangzhou Hongjun Microelectronics Co Ltd",
/* EOF */
diff --git a/src/helper/types.h b/src/helper/types.h
index b99ece1..587ed22 100644
--- a/src/helper/types.h
+++ b/src/helper/types.h
@@ -151,7 +151,7 @@ static inline uint16_t be_to_h_u16(const uint8_t *buf)
return (uint16_t)((uint16_t)buf[1] | (uint16_t)buf[0] << 8);
}
-static inline void h_u64_to_le(uint8_t *buf, int64_t val)
+static inline void h_u64_to_le(uint8_t *buf, uint64_t val)
{
buf[7] = (uint8_t) (val >> 56);
buf[6] = (uint8_t) (val >> 48);
@@ -163,7 +163,7 @@ static inline void h_u64_to_le(uint8_t *buf, int64_t val)
buf[0] = (uint8_t) (val >> 0);
}
-static inline void h_u64_to_be(uint8_t *buf, int64_t val)
+static inline void h_u64_to_be(uint8_t *buf, uint64_t val)
{
buf[0] = (uint8_t) (val >> 56);
buf[1] = (uint8_t) (val >> 48);
@@ -175,7 +175,7 @@ static inline void h_u64_to_be(uint8_t *buf, int64_t val)
buf[7] = (uint8_t) (val >> 0);
}
-static inline void h_u32_to_le(uint8_t *buf, int val)
+static inline void h_u32_to_le(uint8_t *buf, uint32_t val)
{
buf[3] = (uint8_t) (val >> 24);
buf[2] = (uint8_t) (val >> 16);
@@ -183,7 +183,7 @@ static inline void h_u32_to_le(uint8_t *buf, int val)
buf[0] = (uint8_t) (val >> 0);
}
-static inline void h_u32_to_be(uint8_t *buf, int val)
+static inline void h_u32_to_be(uint8_t *buf, uint32_t val)
{
buf[0] = (uint8_t) (val >> 24);
buf[1] = (uint8_t) (val >> 16);
@@ -191,27 +191,27 @@ static inline void h_u32_to_be(uint8_t *buf, int val)
buf[3] = (uint8_t) (val >> 0);
}
-static inline void h_u24_to_le(uint8_t *buf, int val)
+static inline void h_u24_to_le(uint8_t *buf, unsigned int val)
{
buf[2] = (uint8_t) (val >> 16);
buf[1] = (uint8_t) (val >> 8);
buf[0] = (uint8_t) (val >> 0);
}
-static inline void h_u24_to_be(uint8_t *buf, int val)
+static inline void h_u24_to_be(uint8_t *buf, unsigned int val)
{
buf[0] = (uint8_t) (val >> 16);
buf[1] = (uint8_t) (val >> 8);
buf[2] = (uint8_t) (val >> 0);
}
-static inline void h_u16_to_le(uint8_t *buf, int val)
+static inline void h_u16_to_le(uint8_t *buf, uint16_t val)
{
buf[1] = (uint8_t) (val >> 8);
buf[0] = (uint8_t) (val >> 0);
}
-static inline void h_u16_to_be(uint8_t *buf, int val)
+static inline void h_u16_to_be(uint8_t *buf, uint16_t val)
{
buf[0] = (uint8_t) (val >> 8);
buf[1] = (uint8_t) (val >> 0);
diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am
index 43c6f8b..7ce4adc 100644
--- a/src/jtag/Makefile.am
+++ b/src/jtag/Makefile.am
@@ -9,11 +9,6 @@ include %D%/hla/Makefile.am
%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/hla/libocdhla.la
endif
-if AICE
-include %D%/aice/Makefile.am
-%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/aice/libocdaice.la
-endif
-
include %D%/drivers/Makefile.am
%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/drivers/libocdjtagdrivers.la
diff --git a/src/jtag/aice/Makefile.am b/src/jtag/aice/Makefile.am
deleted file mode 100644
index bc5dac1..0000000
--- a/src/jtag/aice/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-noinst_LTLIBRARIES += %D%/libocdaice.la
-
-%C%_libocdaice_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS)
-%C%_libocdaice_la_SOURCES = \
- %D%/aice_transport.c \
- %D%/aice_interface.c \
- %D%/aice_port.c \
- %D%/aice_usb.c \
- %D%/aice_pipe.c \
- %D%/aice_transport.h \
- %D%/aice_interface.h \
- %D%/aice_port.h \
- %D%/aice_usb.h \
- %D%/aice_pipe.h
diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c
deleted file mode 100644
index 89f82a0..0000000
--- a/src/jtag/aice/aice_interface.c
+++ /dev/null
@@ -1,507 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <jtag/adapter.h>
-#include <jtag/interface.h>
-#include <jtag/commands.h>
-#include <transport/transport.h>
-#include <target/target.h>
-#include <jtag/aice/aice_transport.h>
-#include "aice_usb.h"
-
-#define AICE_KHZ_TO_SPEED_MAP_SIZE 16
-static const int aice_khz_to_speed_map[AICE_KHZ_TO_SPEED_MAP_SIZE] = {
- 30000,
- 15000,
- 7500,
- 3750,
- 1875,
- 937,
- 468,
- 234,
- 48000,
- 24000,
- 12000,
- 6000,
- 3000,
- 1500,
- 750,
- 375,
-};
-
-static const struct aice_port *aice_port;
-static struct aice_port_param_s param;
-static uint32_t retry_times;
-static uint32_t count_to_check_dbger;
-
-/***************************************************************************/
-/* External interface implementation */
-static uint32_t aice_target_id_codes[AICE_MAX_NUM_CORE];
-static uint8_t aice_num_of_target_id_codes;
-
-/***************************************************************************/
-/* AICE operations */
-int aice_init_targets(void)
-{
- int res;
- struct target *target;
- struct aice_port_s *aice;
-
- LOG_DEBUG("aice_init_targets");
-
- if (aice_num_of_target_id_codes == 0) {
- res = aice_port->api->idcode(aice_target_id_codes, &aice_num_of_target_id_codes);
- if (res != ERROR_OK) {
- LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore "
- "JTAG Manufacture ID in the JTAG scan chain. "
- "Failed to access EDM registers. -->");
- return res;
- }
- }
-
- for (target = all_targets; target; target = target->next) {
- target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position];
-
- unsigned ii, limit = target->tap->expected_ids_cnt;
- int found = 0;
-
- for (ii = 0; ii < limit; ii++) {
- uint32_t expected = target->tap->expected_ids[ii];
-
- /* treat "-expected-id 0" as a "don't-warn" wildcard */
- if (!expected || (target->tap->idcode == expected)) {
- found = 1;
- break;
- }
- }
-
- if (found == 0) {
- LOG_ERROR
- ("aice_init_targets: target not found: idcode: %" PRIx32,
- target->tap->idcode);
- return ERROR_FAIL;
- }
-
- aice = calloc(1, sizeof(struct aice_port_s));
- aice->port = aice_port;
- aice->coreid = target->tap->abs_chain_position;
-
- target->tap->priv = aice;
- target->tap->hasidcode = 1;
- }
-
- return ERROR_OK;
-}
-
-/***************************************************************************/
-/* End of External interface implementation */
-
-/* initial aice
- * 1. open usb
- * 2. get/show version number
- * 3. reset
- */
-static int aice_init(void)
-{
- if (aice_port->api->open(&param) != ERROR_OK) {
- LOG_ERROR("Cannot find AICE Interface! Please check "
- "connection and permissions.");
- return ERROR_JTAG_INIT_FAILED;
- }
-
- aice_port->api->set_retry_times(retry_times);
- aice_port->api->set_count_to_check_dbger(count_to_check_dbger);
-
- LOG_INFO("AICE JTAG Interface ready");
-
- return ERROR_OK;
-}
-
-/* cleanup aice resource
- * close usb
- */
-static int aice_quit(void)
-{
- aice_port->api->close();
- return ERROR_OK;
-}
-
-static int aice_execute_reset(struct jtag_command *cmd)
-{
- static int last_trst;
- int retval = ERROR_OK;
-
- LOG_DEBUG_IO("reset trst: %d", cmd->cmd.reset->trst);
-
- if (cmd->cmd.reset->trst != last_trst) {
- if (cmd->cmd.reset->trst)
- retval = aice_port->api->reset();
-
- last_trst = cmd->cmd.reset->trst;
- }
-
- return retval;
-}
-
-static int aice_execute_command(struct jtag_command *cmd)
-{
- int retval;
-
- switch (cmd->type) {
- case JTAG_RESET:
- retval = aice_execute_reset(cmd);
- break;
- default:
- retval = ERROR_OK;
- break;
- }
- return retval;
-}
-
-/* aice has no need to implement jtag execution model
-*/
-static int aice_execute_queue(void)
-{
- struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
- int retval;
-
- retval = ERROR_OK;
-
- while (cmd) {
- if (aice_execute_command(cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
-
- cmd = cmd->next;
- }
-
- return retval;
-}
-
-/* set jtag frequency(base frequency/frequency divider) to your jtag adapter */
-static int aice_speed(int speed)
-{
- return aice_port->api->set_jtag_clock(speed);
-}
-
-/* convert jtag adapter frequency(base frequency/frequency divider) to
- * human readable KHz value */
-static int aice_speed_div(int speed, int *khz)
-{
- *khz = aice_khz_to_speed_map[speed];
-
- return ERROR_OK;
-}
-
-/* convert human readable KHz value to jtag adapter frequency
- * (base frequency/frequency divider) */
-static int aice_khz(int khz, int *jtag_speed)
-{
- int i;
- for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) {
- if (khz == aice_khz_to_speed_map[i]) {
- if (i >= 8)
- *jtag_speed = i | AICE_TCK_CONTROL_TCK3048;
- else
- *jtag_speed = i;
- break;
- }
- }
-
- if (i == AICE_KHZ_TO_SPEED_MAP_SIZE) {
- LOG_INFO("No support the jtag clock: %d", khz);
- LOG_INFO("Supported jtag clocks are:");
-
- for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++)
- LOG_INFO("* %d", aice_khz_to_speed_map[i]);
-
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-int aice_scan_jtag_chain(void)
-{
- LOG_DEBUG("=== %s ===", __func__);
- uint8_t num_of_idcode = 0;
- struct target *target;
-
- int res = aice_port->api->idcode(aice_target_id_codes, &num_of_idcode);
- if (res != ERROR_OK) {
- LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore "
- "JTAG Manufacture ID in the JTAG scan chain. "
- "Failed to access EDM registers. -->");
- return res;
- }
-
- for (unsigned int i = 0; i < num_of_idcode; i++)
- LOG_DEBUG("id_codes[%u] = 0x%" PRIx32, i, aice_target_id_codes[i]);
-
- /* Update tap idcode */
- for (target = all_targets; target; target = target->next)
- target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position];
-
- return ERROR_OK;
-}
-
-/***************************************************************************/
-/* Command handlers */
-COMMAND_HANDLER(aice_handle_aice_info_command)
-{
- LOG_DEBUG("aice_handle_aice_info_command");
-
- command_print(CMD, "Description: %s", param.device_desc);
- command_print(CMD, "Serial number: %s", adapter_get_required_serial());
- if (strncmp(aice_port->name, "aice_pipe", 9) == 0)
- command_print(CMD, "Adapter: %s", param.adapter_name);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(aice_handle_aice_port_command)
-{
- LOG_DEBUG("aice_handle_aice_port_command");
-
- if (CMD_ARGC != 1) {
- LOG_ERROR("Need exactly one argument to 'aice port'");
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- for (const struct aice_port *l = aice_port_get_list(); l->name; l++) {
- if (strcmp(l->name, CMD_ARGV[0]) == 0) {
- aice_port = l;
- return ERROR_OK;
- }
- }
-
- LOG_ERROR("No AICE port '%s' found", CMD_ARGV[0]);
- return ERROR_FAIL;
-}
-
-COMMAND_HANDLER(aice_handle_aice_desc_command)
-{
- LOG_DEBUG("aice_handle_aice_desc_command");
-
- if (CMD_ARGC == 1)
- param.device_desc = strdup(CMD_ARGV[0]);
- else
- LOG_ERROR("expected exactly one argument to aice desc <description>");
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(aice_handle_aice_vid_pid_command)
-{
- LOG_DEBUG("aice_handle_aice_vid_pid_command");
-
- if (CMD_ARGC != 2) {
- LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)");
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], param.vid);
- COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], param.pid);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(aice_handle_aice_adapter_command)
-{
- LOG_DEBUG("aice_handle_aice_adapter_command");
-
- if (CMD_ARGC == 1)
- param.adapter_name = strdup(CMD_ARGV[0]);
- else
- LOG_ERROR("expected exactly one argument to aice adapter <adapter-name>");
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(aice_handle_aice_retry_times_command)
-{
- LOG_DEBUG("aice_handle_aice_retry_times_command");
-
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], retry_times);
- else
- LOG_ERROR("expected exactly one argument to aice retry_times <num_of_retry>");
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command)
-{
- LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command");
-
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], count_to_check_dbger);
- else
- LOG_ERROR("expected exactly one argument to aice count_to_check_dbger "
- "<count_of_checking>");
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command)
-{
- LOG_DEBUG("aice_handle_aice_custom_srst_script_command");
-
- if (CMD_ARGC > 0) {
- aice_port->api->set_custom_srst_script(CMD_ARGV[0]);
- return ERROR_OK;
- }
-
- return ERROR_FAIL;
-}
-
-COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command)
-{
- LOG_DEBUG("aice_handle_aice_custom_trst_script_command");
-
- if (CMD_ARGC > 0) {
- aice_port->api->set_custom_trst_script(CMD_ARGV[0]);
- return ERROR_OK;
- }
-
- return ERROR_FAIL;
-}
-
-COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command)
-{
- LOG_DEBUG("aice_handle_aice_custom_restart_script_command");
-
- if (CMD_ARGC > 0) {
- aice_port->api->set_custom_restart_script(CMD_ARGV[0]);
- return ERROR_OK;
- }
-
- return ERROR_FAIL;
-}
-
-COMMAND_HANDLER(aice_handle_aice_reset_command)
-{
- LOG_DEBUG("aice_handle_aice_reset_command");
-
- return aice_port->api->reset();
-}
-
-
-static const struct command_registration aice_subcommand_handlers[] = {
- {
- .name = "info",
- .handler = &aice_handle_aice_info_command,
- .mode = COMMAND_EXEC,
- .help = "show aice info",
- .usage = "",
- },
- {
- .name = "port",
- .handler = &aice_handle_aice_port_command,
- .mode = COMMAND_CONFIG,
- .help = "set the port of the AICE",
- .usage = "['aice_pipe'|'aice_usb']",
- },
- {
- .name = "desc",
- .handler = &aice_handle_aice_desc_command,
- .mode = COMMAND_CONFIG,
- .help = "set the aice device description",
- .usage = "[description string]",
- },
- {
- .name = "vid_pid",
- .handler = &aice_handle_aice_vid_pid_command,
- .mode = COMMAND_CONFIG,
- .help = "the vendor and product ID of the AICE device",
- .usage = "(vid pid)*",
- },
- {
- .name = "adapter",
- .handler = &aice_handle_aice_adapter_command,
- .mode = COMMAND_CONFIG,
- .help = "set the file name of adapter",
- .usage = "[adapter name]",
- },
- {
- .name = "retry_times",
- .handler = &aice_handle_aice_retry_times_command,
- .mode = COMMAND_CONFIG,
- .help = "set retry times as AICE timeout",
- .usage = "num_of_retry",
- },
- {
- .name = "count_to_check_dbger",
- .handler = &aice_handle_aice_count_to_check_dbger_command,
- .mode = COMMAND_CONFIG,
- .help = "set retry times as checking $DBGER status",
- .usage = "count_of_checking",
- },
- {
- .name = "custom_srst_script",
- .handler = &aice_handle_aice_custom_srst_script_command,
- .mode = COMMAND_CONFIG,
- .usage = "script_file_name",
- .help = "set custom srst script",
- },
- {
- .name = "custom_trst_script",
- .handler = &aice_handle_aice_custom_trst_script_command,
- .mode = COMMAND_CONFIG,
- .usage = "script_file_name",
- .help = "set custom trst script",
- },
- {
- .name = "custom_restart_script",
- .handler = &aice_handle_aice_custom_restart_script_command,
- .mode = COMMAND_CONFIG,
- .usage = "script_file_name",
- .help = "set custom restart script",
- },
- {
- .name = "reset",
- .handler = &aice_handle_aice_reset_command,
- .mode = COMMAND_EXEC,
- .usage = "",
- .help = "reset AICE",
- },
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration aice_command_handlers[] = {
- {
- .name = "aice",
- .mode = COMMAND_ANY,
- .help = "perform aice management",
- .usage = "[subcommand]",
- .chain = aice_subcommand_handlers,
- },
- COMMAND_REGISTRATION_DONE
-};
-/***************************************************************************/
-/* End of Command handlers */
-
-static struct jtag_interface aice_interface = {
- .execute_queue = aice_execute_queue,
-};
-
-struct adapter_driver aice_adapter_driver = {
- .name = "aice",
- .transports = aice_transports,
- .commands = aice_command_handlers,
-
- .init = aice_init,
- .quit = aice_quit,
- .speed = aice_speed, /* set interface speed */
- .khz = aice_khz, /* convert khz to interface speed value */
- .speed_div = aice_speed_div, /* return readable value */
-
- .jtag_ops = &aice_interface,
-};
diff --git a/src/jtag/aice/aice_interface.h b/src/jtag/aice/aice_interface.h
deleted file mode 100644
index 615e90f..0000000
--- a/src/jtag/aice/aice_interface.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_JTAG_AICE_AICE_INTERFACE_H
-#define OPENOCD_JTAG_AICE_AICE_INTERFACE_H
-
-int aice_init_targets(void);
-int aice_scan_jtag_chain(void);
-
-#endif /* OPENOCD_JTAG_AICE_AICE_INTERFACE_H */
diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c
deleted file mode 100644
index d2befde..0000000
--- a/src/jtag/aice/aice_pipe.c
+++ /dev/null
@@ -1,885 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <helper/system.h>
-
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <signal.h>
-#endif
-
-#include <helper/log.h>
-#include <helper/time_support.h>
-#include <helper/system.h>
-#include "aice_port.h"
-#include "aice_pipe.h"
-
-#define AICE_PIPE_MAXLINE 8192
-
-#ifdef _WIN32
-PROCESS_INFORMATION proc_info;
-
-static HANDLE aice_pipe_output[2];
-static HANDLE aice_pipe_input[2];
-
-static int aice_pipe_write(const void *buffer, int count)
-{
- BOOL success;
- DWORD written;
-
- success = WriteFile(aice_pipe_output[1], buffer, count, &written, NULL);
- if (!success) {
- LOG_ERROR("(WIN32) write to pipe failed, error code: 0x%08l" PRIx32, GetLastError());
- return -1;
- }
-
- return written;
-}
-
-static int aice_pipe_read(void *buffer, int count)
-{
- BOOL success;
- DWORD has_read;
-
- success = ReadFile(aice_pipe_input[0], buffer, count, &has_read, NULL);
- if (!success || (has_read == 0)) {
- LOG_ERROR("(WIN32) read from pipe failed, error code: 0x%08l" PRIx32, GetLastError());
- return -1;
- }
-
- return has_read;
-}
-
-static int aice_pipe_child_init(struct aice_port_param_s *param)
-{
- STARTUPINFO start_info;
- BOOL success;
-
- ZeroMemory(&proc_info, sizeof(PROCESS_INFORMATION));
- ZeroMemory(&start_info, sizeof(STARTUPINFO));
- start_info.cb = sizeof(STARTUPINFO);
- start_info.hStdError = aice_pipe_input[1];
- start_info.hStdOutput = aice_pipe_input[1];
- start_info.hStdInput = aice_pipe_output[0];
- start_info.dwFlags |= STARTF_USESTDHANDLES;
-
- success = CreateProcess(NULL,
- param->adapter_name,
- NULL,
- NULL,
- TRUE,
- 0,
- NULL,
- NULL,
- &start_info,
- &proc_info);
-
- if (!success) {
- LOG_ERROR("Create new process failed");
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int aice_pipe_parent_init(struct aice_port_param_s *param)
-{
- /* send open to adapter */
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_OPEN;
- set_u16(command + 1, param->vid);
- set_u16(command + 3, param->pid);
-
- if (aice_pipe_write(command, 5) != 5) {
- LOG_ERROR("write failed\n");
- return ERROR_FAIL;
- }
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) {
- LOG_ERROR("read failed\n");
- return ERROR_FAIL;
- }
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_open(struct aice_port_param_s *param)
-{
- SECURITY_ATTRIBUTES attribute;
-
- attribute.nLength = sizeof(SECURITY_ATTRIBUTES);
- attribute.bInheritHandle = TRUE;
- attribute.lpSecurityDescriptor = NULL;
-
- if (!CreatePipe(&aice_pipe_output[0], &aice_pipe_output[1],
- &attribute, AICE_PIPE_MAXLINE)) {
- LOG_ERROR("Create pipes failed");
- return ERROR_FAIL;
- }
- if (!CreatePipe(&aice_pipe_input[0], &aice_pipe_input[1],
- &attribute, AICE_PIPE_MAXLINE)) {
- LOG_ERROR("Create pipes failed");
- return ERROR_FAIL;
- }
-
- /* do not inherit aice_pipe_output[1] & aice_pipe_input[0] to child process */
- if (!SetHandleInformation(aice_pipe_output[1], HANDLE_FLAG_INHERIT, 0))
- return ERROR_FAIL;
- if (!SetHandleInformation(aice_pipe_input[0], HANDLE_FLAG_INHERIT, 0))
- return ERROR_FAIL;
-
- aice_pipe_child_init(param);
-
- aice_pipe_parent_init(param);
-
- return ERROR_OK;
-}
-
-#else
-
-static int aice_pipe_output[2];
-static int aice_pipe_input[2];
-
-static int aice_pipe_write(const void *buffer, int count)
-{
- if (write(aice_pipe_output[1], buffer, count) != count) {
- LOG_ERROR("write to pipe failed");
- return -1;
- }
-
- return count;
-}
-
-static int aice_pipe_read(void *buffer, int count)
-{
- int n;
- int64_t then, cur;
-
- then = timeval_ms();
-
- while (1) {
- n = read(aice_pipe_input[0], buffer, count);
-
- if ((n == -1) && (errno == EAGAIN)) {
- cur = timeval_ms();
- if (cur - then > 500)
- keep_alive();
- continue;
- } else if (n > 0)
- break;
- else {
- LOG_ERROR("read from pipe failed");
- break;
- }
- }
-
- return n;
-}
-
-static int aice_pipe_child_init(struct aice_port_param_s *param)
-{
- close(aice_pipe_output[1]);
- close(aice_pipe_input[0]);
-
- if (aice_pipe_output[0] != STDIN_FILENO) {
- if (dup2(aice_pipe_output[0], STDIN_FILENO) != STDIN_FILENO) {
- LOG_ERROR("Map aice_pipe to STDIN failed");
- return ERROR_FAIL;
- }
- close(aice_pipe_output[0]);
- }
-
- if (aice_pipe_input[1] != STDOUT_FILENO) {
- if (dup2(aice_pipe_input[1], STDOUT_FILENO) != STDOUT_FILENO) {
- LOG_ERROR("Map aice_pipe to STDOUT failed");
- return ERROR_FAIL;
- }
- close(aice_pipe_input[1]);
- }
-
- if (execl(param->adapter_name, param->adapter_name, (char *)0) < 0) {
- LOG_ERROR("Execute aice_pipe failed");
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int aice_pipe_parent_init(struct aice_port_param_s *param)
-{
- close(aice_pipe_output[0]);
- close(aice_pipe_input[1]);
-
- /* set read end of pipe as non-blocking */
- if (fcntl(aice_pipe_input[0], F_SETFL, O_NONBLOCK))
- return ERROR_FAIL;
-
- /* send open to adapter */
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_OPEN;
- set_u16(command + 1, param->vid);
- set_u16(command + 3, param->pid);
-
- if (aice_pipe_write(command, 5) != 5) {
- LOG_ERROR("write failed\n");
- return ERROR_FAIL;
- }
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) {
- LOG_ERROR("read failed\n");
- return ERROR_FAIL;
- }
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static void sig_pipe(int signo)
-{
- exit(1);
-}
-
-static int aice_pipe_open(struct aice_port_param_s *param)
-{
- pid_t pid;
-
- if (signal(SIGPIPE, sig_pipe) == SIG_ERR) {
- LOG_ERROR("Register SIGPIPE handler failed");
- return ERROR_FAIL;
- }
-
- if (pipe(aice_pipe_output) < 0 || pipe(aice_pipe_input) < 0) {
- LOG_ERROR("Create pipes failed");
- return ERROR_FAIL;
- }
-
- pid = fork();
- if (pid < 0) {
- LOG_ERROR("Fork new process failed");
- return ERROR_FAIL;
- } else if (pid == 0) {
- if (aice_pipe_child_init(param) != ERROR_OK) {
- LOG_ERROR("AICE_PIPE child process initial error");
- return ERROR_FAIL;
- } else {
- if (aice_pipe_parent_init(param) != ERROR_OK) {
- LOG_ERROR("AICE_PIPE parent process initial error");
- return ERROR_FAIL;
- }
- }
- }
-
- return ERROR_OK;
-}
-#endif
-
-static int aice_pipe_close(void)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_CLOSE;
-
- if (aice_pipe_write(command, 1) != 1)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK) {
-#ifdef _WIN32
- WaitForSingleObject(proc_info.hProcess, INFINITE);
- CloseHandle(proc_info.hProcess);
- CloseHandle(proc_info.hThread);
-#endif
- return ERROR_OK;
- } else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_idcode(uint32_t *idcode, uint8_t *num_of_idcode)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_IDCODE;
-
- if (aice_pipe_write(command, 1) != 1)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- *num_of_idcode = line[0];
-
- if ((*num_of_idcode == 0) || (*num_of_idcode >= 16))
- return ERROR_FAIL;
-
- for (int i = 0 ; i < *num_of_idcode ; i++)
- idcode[i] = get_u32(line + i * 4 + 1);
-
- return ERROR_OK;
-}
-
-static int aice_pipe_state(uint32_t coreid, enum aice_target_state_s *state)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_STATE;
-
- if (aice_pipe_write(command, 1) != 1)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- *state = (enum aice_target_state_s)line[0];
-
- return ERROR_OK;
-}
-
-static int aice_pipe_reset(void)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_RESET;
-
- if (aice_pipe_write(command, 1) != 1)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_assert_srst(uint32_t coreid, enum aice_srst_type_s srst)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_ASSERT_SRST;
- command[1] = srst;
-
- if (aice_pipe_write(command, 2) != 2)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_run(uint32_t coreid)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_RUN;
-
- if (aice_pipe_write(command, 1) != 1)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_halt(uint32_t coreid)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_HALT;
-
- if (aice_pipe_write(command, 1) != 1)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_read_reg(uint32_t coreid, uint32_t num, uint32_t *val)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_READ_REG;
- set_u32(command + 1, num);
-
- if (aice_pipe_write(command, 5) != 5)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- *val = get_u32(line);
-
- return ERROR_OK;
-}
-
-static int aice_pipe_write_reg(uint32_t coreid, uint32_t num, uint32_t val)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_WRITE_REG;
- set_u32(command + 1, num);
- set_u32(command + 5, val);
-
- if (aice_pipe_write(command, 9) != 9)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_read_reg_64(uint32_t coreid, uint32_t num, uint64_t *val)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_READ_REG_64;
- set_u32(command + 1, num);
-
- if (aice_pipe_write(command, 5) != 5)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- *val = (((uint64_t)get_u32(line + 4)) << 32) | get_u32(line);
-
- return ERROR_OK;
-}
-
-static int aice_pipe_write_reg_64(uint32_t coreid, uint32_t num, uint64_t val)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_WRITE_REG_64;
- set_u32(command + 1, num);
- set_u32(command + 5, val & 0xFFFFFFFF);
- set_u32(command + 9, (val >> 32) & 0xFFFFFFFF);
-
- if (aice_pipe_write(command, 13) != 9)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_step(uint32_t coreid)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_STEP;
-
- if (aice_pipe_write(command, 1) != 1)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_read_mem_unit(uint32_t coreid, uint32_t addr, uint32_t size,
- uint32_t count, uint8_t *buffer)
-{
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_READ_MEM_UNIT;
- set_u32(command + 1, addr);
- set_u32(command + 5, size);
- set_u32(command + 9, count);
-
- if (aice_pipe_write(command, 13) != 13)
- return ERROR_FAIL;
-
- if (aice_pipe_read(buffer, size * count) < 0)
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int aice_pipe_write_mem_unit(uint32_t coreid, uint32_t addr, uint32_t size,
- uint32_t count, const uint8_t *buffer)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_WRITE_MEM_UNIT;
- set_u32(command + 1, addr);
- set_u32(command + 5, size);
- set_u32(command + 9, count);
-
- /* WRITE_MEM_UNIT|addr|size|count|data */
- memcpy(command + 13, buffer, size * count);
-
- if (aice_pipe_write(command, 13 + size * count) < 0)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int aice_pipe_read_mem_bulk(uint32_t coreid, uint32_t addr,
- uint32_t length, uint8_t *buffer)
-{
- char line[AICE_PIPE_MAXLINE + 1];
- char command[AICE_PIPE_MAXLINE];
- uint32_t remain_len = length;
- uint32_t prepare_len;
- char *received_line;
- uint32_t received_len;
- int read_len;
-
- command[0] = AICE_READ_MEM_BULK;
- set_u32(command + 1, addr);
- set_u32(command + 5, length);
-
- if (aice_pipe_write(command, 9) < 0)
- return ERROR_FAIL;
-
- while (remain_len > 0) {
- if (remain_len > AICE_PIPE_MAXLINE)
- prepare_len = AICE_PIPE_MAXLINE;
- else
- prepare_len = remain_len;
-
- prepare_len++;
- received_len = 0;
- received_line = line;
- do {
- read_len = aice_pipe_read(received_line, prepare_len - received_len);
- if (read_len < 0)
- return ERROR_FAIL;
- received_line += read_len;
- received_len += read_len;
- } while (received_len < prepare_len);
-
- if (line[0] != AICE_OK)
- return ERROR_FAIL;
-
- prepare_len--;
- memcpy(buffer, line + 1, prepare_len);
- remain_len -= prepare_len;
- buffer += prepare_len;
- }
-
- return ERROR_OK;
-}
-
-static int aice_pipe_write_mem_bulk(uint32_t coreid, uint32_t addr,
- uint32_t length, const uint8_t *buffer)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE + 4];
- uint32_t remain_len = length;
- uint32_t written_len = 0;
- uint32_t write_len;
-
- command[0] = AICE_WRITE_MEM_BULK;
- set_u32(command + 1, addr);
- set_u32(command + 5, length);
-
- /* Send command first */
- if (aice_pipe_write(command, 9) < 0)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_ERROR)
- return ERROR_FAIL;
-
- while (remain_len > 0) {
- if (remain_len > AICE_PIPE_MAXLINE)
- write_len = AICE_PIPE_MAXLINE;
- else
- write_len = remain_len;
-
- set_u32(command, write_len);
- memcpy(command + 4, buffer + written_len, write_len); /* data only */
-
- if (aice_pipe_write(command, write_len + 4) < 0)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_ERROR)
- return ERROR_FAIL;
-
- remain_len -= write_len;
- written_len += write_len;
- }
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_read_debug_reg(uint32_t coreid, uint32_t addr, uint32_t *val)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_READ_DEBUG_REG;
- set_u32(command + 1, addr);
-
- if (aice_pipe_write(command, 5) != 5)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- *val = get_u32(line);
-
- return ERROR_OK;
-}
-
-static int aice_pipe_write_debug_reg(uint32_t coreid, uint32_t addr, const uint32_t val)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_WRITE_DEBUG_REG;
- set_u32(command + 1, addr);
- set_u32(command + 5, val);
-
- if (aice_pipe_write(command, 9) != 9)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_set_jtag_clock(uint32_t a_clock)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_SET_JTAG_CLOCK;
- set_u32(command + 1, a_clock);
-
- if (aice_pipe_write(command, 5) != 5)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_memory_access(uint32_t coreid, enum nds_memory_access access_channel)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_MEMORY_ACCESS;
- set_u32(command + 1, access_channel);
-
- if (aice_pipe_write(command, 5) != 5)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_memory_mode(uint32_t coreid, enum nds_memory_select mem_select)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_MEMORY_MODE;
- set_u32(command + 1, mem_select);
-
- if (aice_pipe_write(command, 5) != 5)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_read_tlb(uint32_t coreid, target_addr_t virtual_address,
- target_addr_t *physical_address)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_READ_TLB;
- set_u32(command + 1, virtual_address);
-
- if (aice_pipe_write(command, 5) != 5)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK) {
- *physical_address = get_u32(line + 1);
- return ERROR_OK;
- } else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_cache_ctl(uint32_t coreid, uint32_t subtype, uint32_t address)
-{
- char line[AICE_PIPE_MAXLINE];
- char command[AICE_PIPE_MAXLINE];
-
- command[0] = AICE_CACHE_CTL;
- set_u32(command + 1, subtype);
- set_u32(command + 5, address);
-
- if (aice_pipe_write(command, 9) != 9)
- return ERROR_FAIL;
-
- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
- return ERROR_FAIL;
-
- if (line[0] == AICE_OK)
- return ERROR_OK;
- else
- return ERROR_FAIL;
-}
-
-static int aice_pipe_set_retry_times(uint32_t a_retry_times)
-{
- return ERROR_OK;
-}
-
-/** */
-struct aice_port_api_s aice_pipe = {
- /** */
- .open = aice_pipe_open,
- /** */
- .close = aice_pipe_close,
- /** */
- .idcode = aice_pipe_idcode,
- /** */
- .set_jtag_clock = aice_pipe_set_jtag_clock,
- /** */
- .state = aice_pipe_state,
- /** */
- .reset = aice_pipe_reset,
- /** */
- .assert_srst = aice_pipe_assert_srst,
- /** */
- .run = aice_pipe_run,
- /** */
- .halt = aice_pipe_halt,
- /** */
- .step = aice_pipe_step,
- /** */
- .read_reg = aice_pipe_read_reg,
- /** */
- .write_reg = aice_pipe_write_reg,
- /** */
- .read_reg_64 = aice_pipe_read_reg_64,
- /** */
- .write_reg_64 = aice_pipe_write_reg_64,
- /** */
- .read_mem_unit = aice_pipe_read_mem_unit,
- /** */
- .write_mem_unit = aice_pipe_write_mem_unit,
- /** */
- .read_mem_bulk = aice_pipe_read_mem_bulk,
- /** */
- .write_mem_bulk = aice_pipe_write_mem_bulk,
- /** */
- .read_debug_reg = aice_pipe_read_debug_reg,
- /** */
- .write_debug_reg = aice_pipe_write_debug_reg,
-
- /** */
- .memory_access = aice_pipe_memory_access,
- /** */
- .memory_mode = aice_pipe_memory_mode,
-
- /** */
- .read_tlb = aice_pipe_read_tlb,
-
- /** */
- .cache_ctl = aice_pipe_cache_ctl,
-
- /** */
- .set_retry_times = aice_pipe_set_retry_times,
-};
diff --git a/src/jtag/aice/aice_pipe.h b/src/jtag/aice/aice_pipe.h
deleted file mode 100644
index 5a1f410..0000000
--- a/src/jtag/aice/aice_pipe.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_JTAG_AICE_AICE_PIPE_H
-#define OPENOCD_JTAG_AICE_AICE_PIPE_H
-
-#include <helper/types.h>
-
-#define set_u32(buffer, value) h_u32_to_le((uint8_t *)buffer, value)
-#define set_u16(buffer, value) h_u16_to_le((uint8_t *)buffer, value)
-#define get_u32(buffer) le_to_h_u32((const uint8_t *)buffer)
-#define get_u16(buffer) le_to_h_u16((const uint8_t *)buffer)
-
-extern struct aice_port_api_s aice_pipe;
-
-#endif /* OPENOCD_JTAG_AICE_AICE_PIPE_H */
diff --git a/src/jtag/aice/aice_port.c b/src/jtag/aice/aice_port.c
deleted file mode 100644
index ac38cec..0000000
--- a/src/jtag/aice/aice_port.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <helper/log.h>
-#include "aice_usb.h"
-#include "aice_pipe.h"
-#include "aice_port.h"
-
-static const struct aice_port aice_ports[] = {
- {
- .name = "aice_usb",
- .type = AICE_PORT_AICE_USB,
- .api = &aice_usb_api,
- },
- {
- .name = "aice_pipe",
- .type = AICE_PORT_AICE_PIPE,
- .api = &aice_pipe,
- },
- {.name = NULL, /* END OF TABLE */ },
-};
-
-/** */
-const struct aice_port *aice_port_get_list(void)
-{
- return aice_ports;
-}
diff --git a/src/jtag/aice/aice_port.h b/src/jtag/aice/aice_port.h
deleted file mode 100644
index fb914d8..0000000
--- a/src/jtag/aice/aice_port.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_JTAG_AICE_AICE_PORT_H
-#define OPENOCD_JTAG_AICE_AICE_PORT_H
-
-#include <target/nds32_edm.h>
-
-#define AICE_MAX_NUM_CORE (0x10)
-
-#define ERROR_AICE_DISCONNECT (-200)
-#define ERROR_AICE_TIMEOUT (-201)
-
-enum aice_target_state_s {
- AICE_DISCONNECT = 0,
- AICE_TARGET_DETACH,
- AICE_TARGET_UNKNOWN,
- AICE_TARGET_RUNNING,
- AICE_TARGET_HALTED,
- AICE_TARGET_RESET,
- AICE_TARGET_DEBUG_RUNNING,
-};
-
-enum aice_srst_type_s {
- AICE_SRST = 0x1,
- AICE_RESET_HOLD = 0x8,
-};
-
-enum aice_target_endian {
- AICE_LITTLE_ENDIAN = 0,
- AICE_BIG_ENDIAN,
-};
-
-enum aice_api_s {
- AICE_OPEN = 0x0,
- AICE_CLOSE,
- AICE_RESET,
- AICE_IDCODE,
- AICE_SET_JTAG_CLOCK,
- AICE_ASSERT_SRST,
- AICE_RUN,
- AICE_HALT,
- AICE_STEP,
- AICE_READ_REG,
- AICE_WRITE_REG,
- AICE_READ_REG_64,
- AICE_WRITE_REG_64,
- AICE_READ_MEM_UNIT,
- AICE_WRITE_MEM_UNIT,
- AICE_READ_MEM_BULK,
- AICE_WRITE_MEM_BULK,
- AICE_READ_DEBUG_REG,
- AICE_WRITE_DEBUG_REG,
- AICE_STATE,
- AICE_MEMORY_ACCESS,
- AICE_MEMORY_MODE,
- AICE_READ_TLB,
- AICE_CACHE_CTL,
- AICE_SET_RETRY_TIMES,
- AICE_PROGRAM_EDM,
- AICE_SET_COMMAND_MODE,
- AICE_EXECUTE,
- AICE_SET_CUSTOM_SRST_SCRIPT,
- AICE_SET_CUSTOM_TRST_SCRIPT,
- AICE_SET_CUSTOM_RESTART_SCRIPT,
- AICE_SET_COUNT_TO_CHECK_DBGER,
- AICE_SET_DATA_ENDIAN,
-};
-
-enum aice_error_s {
- AICE_OK,
- AICE_ACK,
- AICE_ERROR,
-};
-
-enum aice_cache_ctl_type {
- AICE_CACHE_CTL_L1D_INVALALL = 0,
- AICE_CACHE_CTL_L1D_VA_INVAL,
- AICE_CACHE_CTL_L1D_WBALL,
- AICE_CACHE_CTL_L1D_VA_WB,
- AICE_CACHE_CTL_L1I_INVALALL,
- AICE_CACHE_CTL_L1I_VA_INVAL,
-};
-
-enum aice_command_mode {
- AICE_COMMAND_MODE_NORMAL,
- AICE_COMMAND_MODE_PACK,
- AICE_COMMAND_MODE_BATCH,
-};
-
-struct aice_port_param_s {
- /** */
- const char *device_desc;
- /** */
- uint16_t vid;
- /** */
- uint16_t pid;
- /** */
- char *adapter_name;
-};
-
-struct aice_port_s {
- /** */
- uint32_t coreid;
- /** */
- const struct aice_port *port;
-};
-
-/** */
-extern struct aice_port_api_s aice_usb_layout_api;
-
-/** */
-struct aice_port_api_s {
- /** */
- int (*open)(struct aice_port_param_s *param);
- /** */
- int (*close)(void);
- /** */
- int (*reset)(void);
- /** */
- int (*idcode)(uint32_t *idcode, uint8_t *num_of_idcode);
- /** */
- int (*set_jtag_clock)(uint32_t a_clock);
- /** */
- int (*assert_srst)(uint32_t coreid, enum aice_srst_type_s srst);
- /** */
- int (*run)(uint32_t coreid);
- /** */
- int (*halt)(uint32_t coreid);
- /** */
- int (*step)(uint32_t coreid);
- /** */
- int (*read_reg)(uint32_t coreid, uint32_t num, uint32_t *val);
- /** */
- int (*write_reg)(uint32_t coreid, uint32_t num, uint32_t val);
- /** */
- int (*read_reg_64)(uint32_t coreid, uint32_t num, uint64_t *val);
- /** */
- int (*write_reg_64)(uint32_t coreid, uint32_t num, uint64_t val);
- /** */
- int (*read_mem_unit)(uint32_t coreid, uint32_t addr, uint32_t size,
- uint32_t count, uint8_t *buffer);
- /** */
- int (*write_mem_unit)(uint32_t coreid, uint32_t addr, uint32_t size,
- uint32_t count, const uint8_t *buffer);
- /** */
- int (*read_mem_bulk)(uint32_t coreid, uint32_t addr, uint32_t length,
- uint8_t *buffer);
- /** */
- int (*write_mem_bulk)(uint32_t coreid, uint32_t addr, uint32_t length,
- const uint8_t *buffer);
- /** */
- int (*read_debug_reg)(uint32_t coreid, uint32_t addr, uint32_t *val);
- /** */
- int (*write_debug_reg)(uint32_t coreid, uint32_t addr, const uint32_t val);
-
- /** */
- int (*state)(uint32_t coreid, enum aice_target_state_s *state);
-
- /** */
- int (*memory_access)(uint32_t coreid, enum nds_memory_access a_access);
- /** */
- int (*memory_mode)(uint32_t coreid, enum nds_memory_select mem_select);
-
- /** */
- int (*read_tlb)(uint32_t coreid, target_addr_t virtual_address, target_addr_t *physical_address);
-
- /** */
- int (*cache_ctl)(uint32_t coreid, uint32_t subtype, uint32_t address);
-
- /** */
- int (*set_retry_times)(uint32_t a_retry_times);
-
- /** */
- int (*program_edm)(uint32_t coreid, char *command_sequence);
-
- /** */
- int (*set_command_mode)(enum aice_command_mode command_mode);
-
- /** */
- int (*execute)(uint32_t coreid, uint32_t *instructions, uint32_t instruction_num);
-
- /** */
- int (*set_custom_srst_script)(const char *script);
-
- /** */
- int (*set_custom_trst_script)(const char *script);
-
- /** */
- int (*set_custom_restart_script)(const char *script);
-
- /** */
- int (*set_count_to_check_dbger)(uint32_t count_to_check);
-
- /** */
- int (*set_data_endian)(uint32_t coreid, enum aice_target_endian target_data_endian);
-
- /** */
- int (*profiling)(uint32_t coreid, uint32_t interval, uint32_t iteration,
- uint32_t reg_no, uint32_t *samples, uint32_t *num_samples);
-};
-
-#define AICE_PORT_UNKNOWN 0
-#define AICE_PORT_AICE_USB 1
-#define AICE_PORT_AICE_PIPE 2
-
-/** */
-struct aice_port {
- /** */
- const char *name;
- /** */
- int type;
- /** */
- struct aice_port_api_s *const api;
-};
-
-/** */
-const struct aice_port *aice_port_get_list(void);
-
-#endif /* OPENOCD_JTAG_AICE_AICE_PORT_H */
diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c
deleted file mode 100644
index 49f899d..0000000
--- a/src/jtag/aice/aice_transport.c
+++ /dev/null
@@ -1,432 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* project specific includes */
-#include <jtag/interface.h>
-#include <jtag/tcl.h>
-#include <transport/transport.h>
-#include <target/target.h>
-#include <jtag/aice/aice_interface.h>
-#include <jtag/aice/aice_transport.h>
-#include <string.h>
-
-/* */
-static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi,
- struct jtag_tap *tap)
-{
- jim_wide w;
- int e = jim_getopt_wide(goi, &w);
- if (e != JIM_OK) {
- Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
- n->name);
- return e;
- }
-
- unsigned expected_len = sizeof(uint32_t) * tap->expected_ids_cnt;
- uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
- if (!new_expected_ids) {
- Jim_SetResultFormatted(goi->interp, "no memory");
- return JIM_ERR;
- }
-
- assert(tap->expected_ids);
- memcpy(new_expected_ids, tap->expected_ids, expected_len);
-
- new_expected_ids[tap->expected_ids_cnt] = w;
-
- free(tap->expected_ids);
- tap->expected_ids = new_expected_ids;
- tap->expected_ids_cnt++;
-
- return JIM_OK;
-}
-
-#define NTAP_OPT_EXPECTED_ID 0
-
-/* */
-static int jim_aice_newtap_cmd(struct jim_getopt_info *goi)
-{
- struct jtag_tap *tap;
- int x;
- int e;
- struct jim_nvp *n;
- char *cp;
- const struct jim_nvp opts[] = {
- {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID},
- {.name = NULL, .value = -1},
- };
-
- tap = calloc(1, sizeof(struct jtag_tap));
- if (!tap) {
- Jim_SetResultFormatted(goi->interp, "no memory");
- return JIM_ERR;
- }
-
- /*
- * we expect CHIP + TAP + OPTIONS
- * */
- if (goi->argc < 3) {
- Jim_SetResultFormatted(goi->interp,
- "Missing CHIP TAP OPTIONS ....");
- free(tap);
- return JIM_ERR;
- }
-
- const char *tmp;
- jim_getopt_string(goi, &tmp, NULL);
- tap->chip = strdup(tmp);
-
- jim_getopt_string(goi, &tmp, NULL);
- tap->tapname = strdup(tmp);
-
- /* name + dot + name + null */
- x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1;
- cp = malloc(x);
- sprintf(cp, "%s.%s", tap->chip, tap->tapname);
- tap->dotted_name = cp;
-
- LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
- tap->chip, tap->tapname, tap->dotted_name, goi->argc);
-
- while (goi->argc) {
- e = jim_getopt_nvp(goi, opts, &n);
- if (e != JIM_OK) {
- jim_getopt_nvp_unknown(goi, opts, 0);
- free(cp);
- free(tap);
- return e;
- }
- LOG_DEBUG("Processing option: %s", n->name);
- switch (n->value) {
- case NTAP_OPT_EXPECTED_ID:
- e = jim_newtap_expected_id(n, goi, tap);
- if (e != JIM_OK) {
- free(cp);
- free(tap);
- return e;
- }
- break;
- } /* switch (n->value) */
- } /* while (goi->argc) */
-
- /* default is enabled-after-reset */
- tap->enabled = !tap->disabled_after_reset;
-
- jtag_tap_init(tap);
- return JIM_OK;
-}
-
-/* */
-static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- struct jim_getopt_info goi;
- jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
- return jim_aice_newtap_cmd(&goi);
-}
-
-/* */
-COMMAND_HANDLER(handle_aice_init_command)
-{
- if (CMD_ARGC != 0)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- static bool jtag_initialized;
- if (jtag_initialized) {
- LOG_INFO("'jtag init' has already been called");
- return ERROR_OK;
- }
- jtag_initialized = true;
-
- LOG_DEBUG("Initializing jtag devices...");
- return jtag_init(CMD_CTX);
-}
-
-COMMAND_HANDLER(handle_scan_chain_command)
-{
- struct jtag_tap *tap;
- char expected_id[12];
-
- aice_scan_jtag_chain();
- tap = jtag_all_taps();
- command_print(CMD,
- " TapName Enabled IdCode Expected IrLen IrCap IrMask");
- command_print(CMD,
- "-- ------------------- -------- ---------- ---------- ----- ----- ------");
-
- while (tap) {
- uint32_t expected, expected_mask, ii;
-
- snprintf(expected_id, sizeof(expected_id), "0x%08x",
- (unsigned)((tap->expected_ids_cnt > 0)
- ? tap->expected_ids[0]
- : 0));
- if (tap->ignore_version)
- expected_id[2] = '*';
-
- expected = buf_get_u32(tap->expected, 0, tap->ir_length);
- expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
-
- command_print(CMD,
- "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
- tap->abs_chain_position,
- tap->dotted_name,
- tap->enabled ? 'Y' : 'n',
- (unsigned int)(tap->idcode),
- expected_id,
- (unsigned int)(tap->ir_length),
- (unsigned int)(expected),
- (unsigned int)(expected_mask));
-
- for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
- snprintf(expected_id, sizeof(expected_id), "0x%08x",
- (unsigned) tap->expected_ids[ii]);
- if (tap->ignore_version)
- expected_id[2] = '*';
-
- command_print(CMD,
- " %s",
- expected_id);
- }
-
- tap = tap->next_tap;
- }
-
- return ERROR_OK;
-}
-
-static int jim_aice_arp_init(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- LOG_DEBUG("No implement: jim_aice_arp_init");
-
- return JIM_OK;
-}
-
-/* */
-static int aice_init_reset(struct command_context *cmd_ctx)
-{
- LOG_DEBUG("Initializing with hard TRST+SRST reset");
-
- int retval;
- enum reset_types jtag_reset_config = jtag_get_reset_config();
-
- jtag_add_reset(1, 0); /* TAP_RESET */
- if (jtag_reset_config & RESET_HAS_SRST) {
- jtag_add_reset(1, 1);
- if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)
- jtag_add_reset(0, 1);
- }
- jtag_add_reset(0, 0);
- retval = jtag_execute_queue();
- if (retval != ERROR_OK)
- return retval;
-
- return ERROR_OK;
-}
-
-/* */
-static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- int e = ERROR_OK;
- struct jim_getopt_info goi;
- jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
- if (goi.argc != 0) {
- Jim_WrongNumArgs(goi.interp, 1, goi.argv - 1, "(no params)");
- return JIM_ERR;
- }
- struct command_context *context = current_command_context(interp);
- e = aice_init_reset(context);
-
- if (e != ERROR_OK) {
- Jim_Obj *obj = Jim_NewIntObj(goi.interp, e);
- Jim_SetResultFormatted(goi.interp, "error: %#s", obj);
- return JIM_ERR;
- }
- return JIM_OK;
-}
-
-static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- struct jim_getopt_info goi;
- jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
- if (goi.argc != 0) {
- Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
- return JIM_ERR;
- }
- Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
- struct jtag_tap *tap;
-
- for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
- Jim_ListAppendElement(goi.interp,
- Jim_GetResult(goi.interp),
- Jim_NewStringObj(goi.interp,
- tap->dotted_name, -1));
-
- return JIM_OK;
-}
-
-/* */
-static const struct command_registration aice_transport_jtag_subcommand_handlers[] = {
- {
- .name = "init",
- .mode = COMMAND_ANY,
- .handler = handle_aice_init_command,
- .help = "initialize jtag scan chain",
- .usage = ""
- },
- {
- .name = "arp_init",
- .mode = COMMAND_ANY,
- .jim_handler = jim_aice_arp_init,
- .help = "Validates JTAG scan chain against the list of "
- "declared TAPs.",
- },
- {
- .name = "arp_init-reset",
- .mode = COMMAND_ANY,
- .jim_handler = jim_aice_arp_init_reset,
- .help = "Uses TRST and SRST to try resetting everything on "
- "the JTAG scan chain, then performs 'jtag arp_init'."
- },
- {
- .name = "newtap",
- .mode = COMMAND_CONFIG,
- .jim_handler = jim_aice_newtap,
- .help = "Create a new TAP instance named basename.tap_type, "
- "and appends it to the scan chain.",
- .usage = "basename tap_type ['-expected_id' number]"
- },
- {
- .name = "tapisenabled",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_tap_enabler,
- .help = "Returns a Tcl boolean (0/1) indicating whether "
- "the TAP is enabled (1) or not (0).",
- .usage = "tap_name",
- },
- {
- .name = "tapenable",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_tap_enabler,
- .help = "Try to enable the specified TAP using the "
- "'tap-enable' TAP event.",
- .usage = "tap_name",
- },
- {
- .name = "tapdisable",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_tap_enabler,
- .help = "Try to disable the specified TAP using the "
- "'tap-disable' TAP event.",
- .usage = "tap_name",
- },
- {
- .name = "configure",
- .mode = COMMAND_ANY,
- .jim_handler = jim_jtag_configure,
- .help = "Provide a Tcl handler for the specified "
- "TAP event.",
- .usage = "tap_name '-event' event_name handler",
- },
- {
- .name = "cget",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_configure,
- .help = "Return any Tcl handler for the specified "
- "TAP event.",
- .usage = "tap_name '-event' event_name",
- },
- {
- .name = "names",
- .mode = COMMAND_ANY,
- .jim_handler = jim_aice_names,
- .help = "Returns list of all JTAG tap names.",
- },
- {
- .name = "scan_chain",
- .handler = handle_scan_chain_command,
- .mode = COMMAND_ANY,
- .help = "print current scan chain configuration",
- .usage = ""
- },
-
- COMMAND_REGISTRATION_DONE
-};
-
-/* */
-static const struct command_registration aice_transport_command_handlers[] = {
- {
- .name = "jtag",
- .mode = COMMAND_ANY,
- .usage = "",
- .chain = aice_transport_jtag_subcommand_handlers,
- },
- COMMAND_REGISTRATION_DONE
-
-};
-
-/* */
-static int aice_transport_register_commands(struct command_context *cmd_ctx)
-{
- return register_commands(cmd_ctx, NULL, aice_transport_command_handlers);
-}
-
-/* */
-static int aice_transport_init(struct command_context *cmd_ctx)
-{
- LOG_DEBUG("aice_transport_init");
- struct target *t = get_current_target(cmd_ctx);
- struct transport *transport;
-
- if (!t) {
- LOG_ERROR("no current target");
- return ERROR_FAIL;
- }
-
- transport = get_current_transport();
-
- if (!transport) {
- LOG_ERROR("no transport selected");
- return ERROR_FAIL;
- }
-
- LOG_DEBUG("current transport %s", transport->name);
-
- return aice_init_targets();
-}
-
-/* */
-static int aice_transport_select(struct command_context *ctx)
-{
- LOG_DEBUG("aice_transport_select");
-
- int retval;
-
- retval = aice_transport_register_commands(ctx);
-
- if (retval != ERROR_OK)
- return retval;
-
- return ERROR_OK;
-}
-
-static struct transport aice_jtag_transport = {
- .name = "aice_jtag",
- .select = aice_transport_select,
- .init = aice_transport_init,
-};
-
-const char *aice_transports[] = { "aice_jtag", NULL };
-
-static void aice_constructor(void) __attribute__((constructor));
-static void aice_constructor(void)
-{
- transport_register(&aice_jtag_transport);
-}
diff --git a/src/jtag/aice/aice_transport.h b/src/jtag/aice/aice_transport.h
deleted file mode 100644
index b000031..0000000
--- a/src/jtag/aice/aice_transport.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_JTAG_AICE_AICE_TRANSPORT_H
-#define OPENOCD_JTAG_AICE_AICE_TRANSPORT_H
-
-extern const char *aice_transports[];
-
-#endif /* OPENOCD_JTAG_AICE_AICE_TRANSPORT_H */
diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c
deleted file mode 100644
index ef0ac63..0000000
--- a/src/jtag/aice/aice_usb.c
+++ /dev/null
@@ -1,4100 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <helper/system.h>
-#include <jtag/drivers/libusb_helper.h>
-#include <helper/log.h>
-#include <helper/time_support.h>
-#include <helper/system.h>
-#include <target/target.h>
-#include <jtag/jtag.h>
-#include <target/nds32_insn.h>
-#include <target/nds32_reg.h>
-#include "aice_usb.h"
-
-
-/* Global USB buffers */
-static uint8_t usb_in_buffer[AICE_IN_BUFFER_SIZE];
-static uint8_t usb_out_buffer[AICE_OUT_BUFFER_SIZE];
-static uint32_t jtag_clock;
-static struct aice_usb_handler_s aice_handler;
-/* AICE max retry times. If AICE command timeout, retry it. */
-static int aice_max_retry_times = 50;
-/* Default endian is little endian. */
-static enum aice_target_endian data_endian;
-
-/* Constants for AICE command format length */
-#define AICE_FORMAT_HTDA (3)
-#define AICE_FORMAT_HTDC (7)
-#define AICE_FORMAT_HTDMA (4)
-#define AICE_FORMAT_HTDMB (8)
-#define AICE_FORMAT_HTDMC (8)
-#define AICE_FORMAT_HTDMD (12)
-#define AICE_FORMAT_DTHA (6)
-#define AICE_FORMAT_DTHB (2)
-#define AICE_FORMAT_DTHMA (8)
-#define AICE_FORMAT_DTHMB (4)
-
-/* Constants for AICE command */
-#define AICE_CMD_SCAN_CHAIN 0x00
-#define AICE_CMD_T_READ_MISC 0x20
-#define AICE_CMD_T_READ_EDMSR 0x21
-#define AICE_CMD_T_READ_DTR 0x22
-#define AICE_CMD_T_READ_MEM_B 0x24
-#define AICE_CMD_T_READ_MEM_H 0x25
-#define AICE_CMD_T_READ_MEM 0x26
-#define AICE_CMD_T_FASTREAD_MEM 0x27
-#define AICE_CMD_T_WRITE_MISC 0x28
-#define AICE_CMD_T_WRITE_EDMSR 0x29
-#define AICE_CMD_T_WRITE_DTR 0x2A
-#define AICE_CMD_T_WRITE_DIM 0x2B
-#define AICE_CMD_T_WRITE_MEM_B 0x2C
-#define AICE_CMD_T_WRITE_MEM_H 0x2D
-#define AICE_CMD_T_WRITE_MEM 0x2E
-#define AICE_CMD_T_FASTWRITE_MEM 0x2F
-#define AICE_CMD_T_EXECUTE 0x3E
-#define AICE_CMD_READ_CTRL 0x50
-#define AICE_CMD_WRITE_CTRL 0x51
-#define AICE_CMD_BATCH_BUFFER_READ 0x60
-#define AICE_CMD_READ_DTR_TO_BUFFER 0x61
-#define AICE_CMD_BATCH_BUFFER_WRITE 0x68
-#define AICE_CMD_WRITE_DTR_FROM_BUFFER 0x69
-
-/***************************************************************************/
-/* AICE commands' pack/unpack functions */
-static void aice_pack_htda(uint8_t cmd_code, uint8_t extra_word_length,
- uint32_t address)
-{
- usb_out_buffer[0] = cmd_code;
- usb_out_buffer[1] = extra_word_length;
- usb_out_buffer[2] = (uint8_t)(address & 0xFF);
-}
-
-static void aice_pack_htdc(uint8_t cmd_code, uint8_t extra_word_length,
- uint32_t address, uint32_t word, enum aice_target_endian access_endian)
-{
- usb_out_buffer[0] = cmd_code;
- usb_out_buffer[1] = extra_word_length;
- usb_out_buffer[2] = (uint8_t)(address & 0xFF);
- if (access_endian == AICE_BIG_ENDIAN) {
- usb_out_buffer[6] = (uint8_t)((word >> 24) & 0xFF);
- usb_out_buffer[5] = (uint8_t)((word >> 16) & 0xFF);
- usb_out_buffer[4] = (uint8_t)((word >> 8) & 0xFF);
- usb_out_buffer[3] = (uint8_t)(word & 0xFF);
- } else {
- usb_out_buffer[3] = (uint8_t)((word >> 24) & 0xFF);
- usb_out_buffer[4] = (uint8_t)((word >> 16) & 0xFF);
- usb_out_buffer[5] = (uint8_t)((word >> 8) & 0xFF);
- usb_out_buffer[6] = (uint8_t)(word & 0xFF);
- }
-}
-
-static void aice_pack_htdma(uint8_t cmd_code, uint8_t target_id,
- uint8_t extra_word_length, uint32_t address)
-{
- usb_out_buffer[0] = cmd_code;
- usb_out_buffer[1] = target_id;
- usb_out_buffer[2] = extra_word_length;
- usb_out_buffer[3] = (uint8_t)(address & 0xFF);
-}
-
-static void aice_pack_htdmb(uint8_t cmd_code, uint8_t target_id,
- uint8_t extra_word_length, uint32_t address)
-{
- usb_out_buffer[0] = cmd_code;
- usb_out_buffer[1] = target_id;
- usb_out_buffer[2] = extra_word_length;
- usb_out_buffer[3] = 0;
- usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF);
- usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF);
- usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF);
- usb_out_buffer[7] = (uint8_t)(address & 0xFF);
-}
-
-static void aice_pack_htdmc(uint8_t cmd_code, uint8_t target_id,
- uint8_t extra_word_length, uint32_t address, uint32_t word,
- enum aice_target_endian access_endian)
-{
- usb_out_buffer[0] = cmd_code;
- usb_out_buffer[1] = target_id;
- usb_out_buffer[2] = extra_word_length;
- usb_out_buffer[3] = (uint8_t)(address & 0xFF);
- if (access_endian == AICE_BIG_ENDIAN) {
- usb_out_buffer[7] = (uint8_t)((word >> 24) & 0xFF);
- usb_out_buffer[6] = (uint8_t)((word >> 16) & 0xFF);
- usb_out_buffer[5] = (uint8_t)((word >> 8) & 0xFF);
- usb_out_buffer[4] = (uint8_t)(word & 0xFF);
- } else {
- usb_out_buffer[4] = (uint8_t)((word >> 24) & 0xFF);
- usb_out_buffer[5] = (uint8_t)((word >> 16) & 0xFF);
- usb_out_buffer[6] = (uint8_t)((word >> 8) & 0xFF);
- usb_out_buffer[7] = (uint8_t)(word & 0xFF);
- }
-}
-
-static void aice_pack_htdmc_multiple_data(uint8_t cmd_code, uint8_t target_id,
- uint8_t extra_word_length, uint32_t address, uint32_t *word,
- uint8_t num_of_words, enum aice_target_endian access_endian)
-{
- usb_out_buffer[0] = cmd_code;
- usb_out_buffer[1] = target_id;
- usb_out_buffer[2] = extra_word_length;
- usb_out_buffer[3] = (uint8_t)(address & 0xFF);
-
- uint8_t i;
- for (i = 0 ; i < num_of_words ; i++, word++) {
- if (access_endian == AICE_BIG_ENDIAN) {
- usb_out_buffer[7 + i * 4] = (uint8_t)((*word >> 24) & 0xFF);
- usb_out_buffer[6 + i * 4] = (uint8_t)((*word >> 16) & 0xFF);
- usb_out_buffer[5 + i * 4] = (uint8_t)((*word >> 8) & 0xFF);
- usb_out_buffer[4 + i * 4] = (uint8_t)(*word & 0xFF);
- } else {
- usb_out_buffer[4 + i * 4] = (uint8_t)((*word >> 24) & 0xFF);
- usb_out_buffer[5 + i * 4] = (uint8_t)((*word >> 16) & 0xFF);
- usb_out_buffer[6 + i * 4] = (uint8_t)((*word >> 8) & 0xFF);
- usb_out_buffer[7 + i * 4] = (uint8_t)(*word & 0xFF);
- }
- }
-}
-
-static void aice_pack_htdmd(uint8_t cmd_code, uint8_t target_id,
- uint8_t extra_word_length, uint32_t address, uint32_t word,
- enum aice_target_endian access_endian)
-{
- usb_out_buffer[0] = cmd_code;
- usb_out_buffer[1] = target_id;
- usb_out_buffer[2] = extra_word_length;
- usb_out_buffer[3] = 0;
- usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF);
- usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF);
- usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF);
- usb_out_buffer[7] = (uint8_t)(address & 0xFF);
- if (access_endian == AICE_BIG_ENDIAN) {
- usb_out_buffer[11] = (uint8_t)((word >> 24) & 0xFF);
- usb_out_buffer[10] = (uint8_t)((word >> 16) & 0xFF);
- usb_out_buffer[9] = (uint8_t)((word >> 8) & 0xFF);
- usb_out_buffer[8] = (uint8_t)(word & 0xFF);
- } else {
- usb_out_buffer[8] = (uint8_t)((word >> 24) & 0xFF);
- usb_out_buffer[9] = (uint8_t)((word >> 16) & 0xFF);
- usb_out_buffer[10] = (uint8_t)((word >> 8) & 0xFF);
- usb_out_buffer[11] = (uint8_t)(word & 0xFF);
- }
-}
-
-static void aice_pack_htdmd_multiple_data(uint8_t cmd_code, uint8_t target_id,
- uint8_t extra_word_length, uint32_t address, const uint8_t *word,
- enum aice_target_endian access_endian)
-{
- usb_out_buffer[0] = cmd_code;
- usb_out_buffer[1] = target_id;
- usb_out_buffer[2] = extra_word_length;
- usb_out_buffer[3] = 0;
- usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF);
- usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF);
- usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF);
- usb_out_buffer[7] = (uint8_t)(address & 0xFF);
-
- uint32_t i;
- /* num_of_words may be over 0xFF, so use uint32_t */
- uint32_t num_of_words = extra_word_length + 1;
-
- for (i = 0 ; i < num_of_words ; i++, word += 4) {
- if (access_endian == AICE_BIG_ENDIAN) {
- usb_out_buffer[11 + i * 4] = word[3];
- usb_out_buffer[10 + i * 4] = word[2];
- usb_out_buffer[9 + i * 4] = word[1];
- usb_out_buffer[8 + i * 4] = word[0];
- } else {
- usb_out_buffer[8 + i * 4] = word[3];
- usb_out_buffer[9 + i * 4] = word[2];
- usb_out_buffer[10 + i * 4] = word[1];
- usb_out_buffer[11 + i * 4] = word[0];
- }
- }
-}
-
-static void aice_unpack_dtha(uint8_t *cmd_ack_code, uint8_t *extra_word_length,
- uint32_t *word, enum aice_target_endian access_endian)
-{
- *cmd_ack_code = usb_in_buffer[0];
- *extra_word_length = usb_in_buffer[1];
-
- if (access_endian == AICE_BIG_ENDIAN) {
- *word = (usb_in_buffer[5] << 24) |
- (usb_in_buffer[4] << 16) |
- (usb_in_buffer[3] << 8) |
- (usb_in_buffer[2]);
- } else {
- *word = (usb_in_buffer[2] << 24) |
- (usb_in_buffer[3] << 16) |
- (usb_in_buffer[4] << 8) |
- (usb_in_buffer[5]);
- }
-}
-
-static void aice_unpack_dtha_multiple_data(uint8_t *cmd_ack_code,
- uint8_t *extra_word_length, uint32_t *word, uint8_t num_of_words,
- enum aice_target_endian access_endian)
-{
- *cmd_ack_code = usb_in_buffer[0];
- *extra_word_length = usb_in_buffer[1];
-
- uint8_t i;
- for (i = 0 ; i < num_of_words ; i++, word++) {
- if (access_endian == AICE_BIG_ENDIAN) {
- *word = (usb_in_buffer[5 + i * 4] << 24) |
- (usb_in_buffer[4 + i * 4] << 16) |
- (usb_in_buffer[3 + i * 4] << 8) |
- (usb_in_buffer[2 + i * 4]);
- } else {
- *word = (usb_in_buffer[2 + i * 4] << 24) |
- (usb_in_buffer[3 + i * 4] << 16) |
- (usb_in_buffer[4 + i * 4] << 8) |
- (usb_in_buffer[5 + i * 4]);
- }
- }
-}
-
-static void aice_unpack_dthb(uint8_t *cmd_ack_code, uint8_t *extra_word_length)
-{
- *cmd_ack_code = usb_in_buffer[0];
- *extra_word_length = usb_in_buffer[1];
-}
-
-static void aice_unpack_dthma(uint8_t *cmd_ack_code, uint8_t *target_id,
- uint8_t *extra_word_length, uint32_t *word,
- enum aice_target_endian access_endian)
-{
- *cmd_ack_code = usb_in_buffer[0];
- *target_id = usb_in_buffer[1];
- *extra_word_length = usb_in_buffer[2];
- if (access_endian == AICE_BIG_ENDIAN) {
- *word = (usb_in_buffer[7] << 24) |
- (usb_in_buffer[6] << 16) |
- (usb_in_buffer[5] << 8) |
- (usb_in_buffer[4]);
- } else {
- *word = (usb_in_buffer[4] << 24) |
- (usb_in_buffer[5] << 16) |
- (usb_in_buffer[6] << 8) |
- (usb_in_buffer[7]);
- }
-}
-
-static void aice_unpack_dthma_multiple_data(uint8_t *cmd_ack_code,
- uint8_t *target_id, uint8_t *extra_word_length, uint8_t *word,
- enum aice_target_endian access_endian)
-{
- *cmd_ack_code = usb_in_buffer[0];
- *target_id = usb_in_buffer[1];
- *extra_word_length = usb_in_buffer[2];
- if (access_endian == AICE_BIG_ENDIAN) {
- word[0] = usb_in_buffer[4];
- word[1] = usb_in_buffer[5];
- word[2] = usb_in_buffer[6];
- word[3] = usb_in_buffer[7];
- } else {
- word[0] = usb_in_buffer[7];
- word[1] = usb_in_buffer[6];
- word[2] = usb_in_buffer[5];
- word[3] = usb_in_buffer[4];
- }
- word += 4;
-
- uint8_t i;
- for (i = 0; i < *extra_word_length; i++) {
- if (access_endian == AICE_BIG_ENDIAN) {
- word[0] = usb_in_buffer[8 + i * 4];
- word[1] = usb_in_buffer[9 + i * 4];
- word[2] = usb_in_buffer[10 + i * 4];
- word[3] = usb_in_buffer[11 + i * 4];
- } else {
- word[0] = usb_in_buffer[11 + i * 4];
- word[1] = usb_in_buffer[10 + i * 4];
- word[2] = usb_in_buffer[9 + i * 4];
- word[3] = usb_in_buffer[8 + i * 4];
- }
- word += 4;
- }
-}
-
-static void aice_unpack_dthmb(uint8_t *cmd_ack_code, uint8_t *target_id,
- uint8_t *extra_word_length)
-{
- *cmd_ack_code = usb_in_buffer[0];
- *target_id = usb_in_buffer[1];
- *extra_word_length = usb_in_buffer[2];
-}
-
-/***************************************************************************/
-/* End of AICE commands' pack/unpack functions */
-
-/* calls the given usb_bulk_* function, allowing for the data to
- * trickle in with some timeouts */
-static int usb_bulk_with_retries(
- int (*f)(struct libusb_device_handle *, int, char *, int, int, int *),
- struct libusb_device_handle *dev, int ep,
- char *bytes, int size, int timeout, int *transferred)
-{
- int tries = 3, count = 0;
-
- while (tries && (count < size)) {
- int result, ret;
-
- ret = f(dev, ep, bytes + count, size - count, timeout, &result);
- if (ret == ERROR_OK)
- count += result;
- else if ((ret != ERROR_TIMEOUT_REACHED) || !--tries)
- return ret;
- }
-
- *transferred = count;
- return ERROR_OK;
-}
-
-static int wrap_usb_bulk_write(struct libusb_device_handle *dev, int ep,
- char *buff, int size, int timeout, int *transferred)
-{
-
- /* usb_bulk_write() takes const char *buff */
- jtag_libusb_bulk_write(dev, ep, buff, size, timeout, transferred);
-
- return 0;
-}
-
-static inline int usb_bulk_write_ex(struct libusb_device_handle *dev, int ep,
- char *bytes, int size, int timeout)
-{
- int tr = 0;
-
- usb_bulk_with_retries(&wrap_usb_bulk_write,
- dev, ep, bytes, size, timeout, &tr);
- return tr;
-}
-
-static inline int usb_bulk_read_ex(struct libusb_device_handle *dev, int ep,
- char *bytes, int size, int timeout)
-{
- int tr = 0;
- usb_bulk_with_retries(&jtag_libusb_bulk_read,
- dev, ep, bytes, size, timeout, &tr);
- return tr;
-}
-
-/* Write data from out_buffer to USB. */
-static int aice_usb_write(uint8_t *out_buffer, int out_length)
-{
- int result;
-
- if (out_length > AICE_OUT_BUFFER_SIZE) {
- LOG_ERROR("aice_write illegal out_length=%i (max=%i)",
- out_length, AICE_OUT_BUFFER_SIZE);
- return -1;
- }
-
- result = usb_bulk_write_ex(aice_handler.usb_handle, aice_handler.usb_write_ep,
- (char *)out_buffer, out_length, AICE_USB_TIMEOUT);
-
- LOG_DEBUG_IO("aice_usb_write, out_length = %i, result = %i",
- out_length, result);
-
- return result;
-}
-
-/* Read data from USB into in_buffer. */
-static int aice_usb_read(uint8_t *in_buffer, int expected_size)
-{
- int result = usb_bulk_read_ex(aice_handler.usb_handle, aice_handler.usb_read_ep,
- (char *)in_buffer, expected_size, AICE_USB_TIMEOUT);
-
- LOG_DEBUG_IO("aice_usb_read, result = %d", result);
-
- return result;
-}
-
-static uint8_t usb_out_packets_buffer[AICE_OUT_PACKETS_BUFFER_SIZE];
-static uint8_t usb_in_packets_buffer[AICE_IN_PACKETS_BUFFER_SIZE];
-static uint32_t usb_out_packets_buffer_length;
-static uint32_t usb_in_packets_buffer_length;
-static enum aice_command_mode aice_command_mode;
-
-static int aice_batch_buffer_write(uint8_t buf_index, const uint8_t *word,
- uint32_t num_of_words);
-
-static int aice_usb_packet_flush(void)
-{
- if (usb_out_packets_buffer_length == 0)
- return 0;
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- LOG_DEBUG("Flush usb packets (AICE_COMMAND_MODE_PACK)");
-
- if (aice_usb_write(usb_out_packets_buffer,
- usb_out_packets_buffer_length) < 0)
- return ERROR_FAIL;
-
- if (aice_usb_read(usb_in_packets_buffer,
- usb_in_packets_buffer_length) < 0)
- return ERROR_FAIL;
-
- usb_out_packets_buffer_length = 0;
- usb_in_packets_buffer_length = 0;
-
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- LOG_DEBUG("Flush usb packets (AICE_COMMAND_MODE_BATCH)");
-
- /* use BATCH_BUFFER_WRITE to fill command-batch-buffer */
- if (aice_batch_buffer_write(AICE_BATCH_COMMAND_BUFFER_0,
- usb_out_packets_buffer,
- (usb_out_packets_buffer_length + 3) / 4) != ERROR_OK)
- return ERROR_FAIL;
-
- usb_out_packets_buffer_length = 0;
- usb_in_packets_buffer_length = 0;
-
- /* enable BATCH command */
- aice_command_mode = AICE_COMMAND_MODE_NORMAL;
- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CTRL, 0x80000000) != ERROR_OK)
- return ERROR_FAIL;
- aice_command_mode = AICE_COMMAND_MODE_BATCH;
-
- /* wait 1 second (AICE bug, workaround) */
- alive_sleep(1000);
-
- /* check status */
- uint32_t i;
- uint32_t batch_status;
-
- i = 0;
- while (1) {
- int retval = aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status);
- if (retval != ERROR_OK)
- return retval;
-
- if (batch_status & 0x1)
- return ERROR_OK;
- else if (batch_status & 0xE)
- return ERROR_FAIL;
-
- if ((i % 30) == 0)
- keep_alive();
-
- i++;
- }
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_packet_append(uint8_t *out_buffer, int out_length, int in_length)
-{
- uint32_t max_packet_size = AICE_OUT_PACKETS_BUFFER_SIZE;
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- max_packet_size = AICE_OUT_PACK_COMMAND_SIZE;
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- max_packet_size = AICE_OUT_BATCH_COMMAND_SIZE;
- } else {
- /* AICE_COMMAND_MODE_NORMAL */
- if (aice_usb_packet_flush() != ERROR_OK)
- return ERROR_FAIL;
- }
-
- if (usb_out_packets_buffer_length + out_length > max_packet_size)
- if (aice_usb_packet_flush() != ERROR_OK) {
- LOG_DEBUG("Flush usb packets failed");
- return ERROR_FAIL;
- }
-
- LOG_DEBUG("Append usb packets 0x%02x", out_buffer[0]);
-
- memcpy(usb_out_packets_buffer + usb_out_packets_buffer_length, out_buffer, out_length);
- usb_out_packets_buffer_length += out_length;
- usb_in_packets_buffer_length += in_length;
-
- return ERROR_OK;
-}
-
-/***************************************************************************/
-/* AICE commands */
-static int aice_reset_box(void)
-{
- if (aice_write_ctrl(AICE_WRITE_CTRL_CLEAR_TIMEOUT_STATUS, 0x1) != ERROR_OK)
- return ERROR_FAIL;
-
- /* turn off FASTMODE */
- uint32_t pin_status;
- if (aice_read_ctrl(AICE_READ_CTRL_GET_JTAG_PIN_STATUS, &pin_status)
- != ERROR_OK)
- return ERROR_FAIL;
-
- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status & (~0x2))
- != ERROR_OK)
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int aice_scan_chain(uint32_t *id_codes, uint8_t *num_of_ids)
-{
- int retry_times = 0;
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH))
- aice_usb_packet_flush();
-
- do {
- aice_pack_htda(AICE_CMD_SCAN_CHAIN, 0x0F, 0x0);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDA);
-
- LOG_DEBUG("SCAN_CHAIN, length: 0x0F");
-
- /** TODO: modify receive length */
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHA);
- if (result != AICE_FORMAT_DTHA) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHA, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- aice_unpack_dtha_multiple_data(&cmd_ack_code, num_of_ids, id_codes,
- 0x10, AICE_LITTLE_ENDIAN);
-
- if (cmd_ack_code != AICE_CMD_SCAN_CHAIN) {
-
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_SCAN_CHAIN, cmd_ack_code);
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- continue;
- }
-
- LOG_DEBUG("SCAN_CHAIN response, # of IDs: %" PRIu8, *num_of_ids);
-
- if (*num_of_ids == 0xFF) {
- LOG_ERROR("No target connected");
- return ERROR_FAIL;
- } else if (*num_of_ids == AICE_MAX_NUM_CORE) {
- LOG_INFO("The ice chain over 16 targets");
- } else {
- (*num_of_ids)++;
- }
- break;
- } while (1);
-
- return ERROR_OK;
-}
-
-int aice_read_ctrl(uint32_t address, uint32_t *data)
-{
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH))
- aice_usb_packet_flush();
-
- aice_pack_htda(AICE_CMD_READ_CTRL, 0, address);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDA);
-
- LOG_DEBUG("READ_CTRL, address: 0x%" PRIx32, address);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHA);
- if (result != AICE_FORMAT_DTHA) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHA, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- aice_unpack_dtha(&cmd_ack_code, &extra_length, data, AICE_LITTLE_ENDIAN);
-
- LOG_DEBUG("READ_CTRL response, data: 0x%" PRIx32, *data);
-
- if (cmd_ack_code != AICE_CMD_READ_CTRL) {
- LOG_ERROR("aice command error (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_READ_CTRL, cmd_ack_code);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-int aice_write_ctrl(uint32_t address, uint32_t data)
-{
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- aice_usb_packet_flush();
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- aice_pack_htdc(AICE_CMD_WRITE_CTRL, 0, address, data, AICE_LITTLE_ENDIAN);
- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDC,
- AICE_FORMAT_DTHB);
- }
-
- aice_pack_htdc(AICE_CMD_WRITE_CTRL, 0, address, data, AICE_LITTLE_ENDIAN);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDC);
-
- LOG_DEBUG("WRITE_CTRL, address: 0x%" PRIx32 ", data: 0x%" PRIx32, address, data);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHB);
- if (result != AICE_FORMAT_DTHB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- aice_unpack_dthb(&cmd_ack_code, &extra_length);
-
- LOG_DEBUG("WRITE_CTRL response");
-
- if (cmd_ack_code != AICE_CMD_WRITE_CTRL) {
- LOG_ERROR("aice command error (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_WRITE_CTRL, cmd_ack_code);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int aice_read_dtr(uint8_t target_id, uint32_t *data)
-{
- int retry_times = 0;
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH))
- aice_usb_packet_flush();
-
- do {
- aice_pack_htdma(AICE_CMD_T_READ_DTR, target_id, 0, 0);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA);
-
- LOG_DEBUG("READ_DTR, COREID: %" PRIu8, target_id);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA);
- if (result != AICE_FORMAT_DTHMA) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMA, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length,
- data, AICE_LITTLE_ENDIAN);
-
- if (cmd_ack_code == AICE_CMD_T_READ_DTR) {
- LOG_DEBUG("READ_DTR response, data: 0x%" PRIx32, *data);
- break;
- } else {
-
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_READ_DTR, cmd_ack_code);
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_read_dtr_to_buffer(uint8_t target_id, uint32_t buffer_idx)
-{
- int retry_times = 0;
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- aice_usb_packet_flush();
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- aice_pack_htdma(AICE_CMD_READ_DTR_TO_BUFFER, target_id, 0, buffer_idx);
- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMA,
- AICE_FORMAT_DTHMB);
- }
-
- do {
- aice_pack_htdma(AICE_CMD_READ_DTR_TO_BUFFER, target_id, 0, buffer_idx);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA);
-
- LOG_DEBUG("READ_DTR_TO_BUFFER, COREID: %" PRIu8, target_id);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_READ_DTR_TO_BUFFER) {
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_READ_DTR_TO_BUFFER, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_write_dtr(uint8_t target_id, uint32_t data)
-{
- int retry_times = 0;
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- aice_usb_packet_flush();
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- aice_pack_htdmc(AICE_CMD_T_WRITE_DTR, target_id, 0, 0, data, AICE_LITTLE_ENDIAN);
- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC,
- AICE_FORMAT_DTHMB);
- }
-
- do {
- aice_pack_htdmc(AICE_CMD_T_WRITE_DTR, target_id, 0, 0, data, AICE_LITTLE_ENDIAN);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC);
-
- LOG_DEBUG("WRITE_DTR, COREID: %" PRIu8 ", data: 0x%" PRIx32, target_id, data);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_T_WRITE_DTR) {
- LOG_DEBUG("WRITE_DTR response");
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_WRITE_DTR, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_write_dtr_from_buffer(uint8_t target_id, uint32_t buffer_idx)
-{
- int retry_times = 0;
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- aice_usb_packet_flush();
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- aice_pack_htdma(AICE_CMD_WRITE_DTR_FROM_BUFFER, target_id, 0, buffer_idx);
- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMA,
- AICE_FORMAT_DTHMB);
- }
-
- do {
- aice_pack_htdma(AICE_CMD_WRITE_DTR_FROM_BUFFER, target_id, 0, buffer_idx);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA);
-
- LOG_DEBUG("WRITE_DTR_FROM_BUFFER, COREID: %" PRIu8 "", target_id);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_WRITE_DTR_FROM_BUFFER) {
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_WRITE_DTR_FROM_BUFFER, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_read_misc(uint8_t target_id, uint32_t address, uint32_t *data)
-{
- int retry_times = 0;
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH))
- aice_usb_packet_flush();
-
- do {
- aice_pack_htdma(AICE_CMD_T_READ_MISC, target_id, 0, address);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA);
-
- LOG_DEBUG("READ_MISC, COREID: %" PRIu8 ", address: 0x%" PRIx32, target_id, address);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA);
- if (result != AICE_FORMAT_DTHMA) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMA, result);
- return ERROR_AICE_DISCONNECT;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length,
- data, AICE_LITTLE_ENDIAN);
-
- if (cmd_ack_code == AICE_CMD_T_READ_MISC) {
- LOG_DEBUG("READ_MISC response, data: 0x%" PRIx32, *data);
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_READ_MISC, cmd_ack_code);
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_write_misc(uint8_t target_id, uint32_t address, uint32_t data)
-{
- int retry_times = 0;
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- aice_usb_packet_flush();
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- aice_pack_htdmc(AICE_CMD_T_WRITE_MISC, target_id, 0, address, data,
- AICE_LITTLE_ENDIAN);
- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC,
- AICE_FORMAT_DTHMB);
- }
-
- do {
- aice_pack_htdmc(AICE_CMD_T_WRITE_MISC, target_id, 0, address,
- data, AICE_LITTLE_ENDIAN);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC);
-
- LOG_DEBUG("WRITE_MISC, COREID: %" PRIu8 ", address: 0x%" PRIx32 ", data: 0x%" PRIx32,
- target_id, address, data);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_T_WRITE_MISC) {
- LOG_DEBUG("WRITE_MISC response");
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_WRITE_MISC, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_read_edmsr(uint8_t target_id, uint32_t address, uint32_t *data)
-{
- int retry_times = 0;
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH))
- aice_usb_packet_flush();
-
- do {
- aice_pack_htdma(AICE_CMD_T_READ_EDMSR, target_id, 0, address);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA);
-
- LOG_DEBUG("READ_EDMSR, COREID: %" PRIu8 ", address: 0x%" PRIx32, target_id, address);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA);
- if (result != AICE_FORMAT_DTHMA) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMA, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length,
- data, AICE_LITTLE_ENDIAN);
-
- if (cmd_ack_code == AICE_CMD_T_READ_EDMSR) {
- LOG_DEBUG("READ_EDMSR response, data: 0x%" PRIx32, *data);
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_READ_EDMSR, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_write_edmsr(uint8_t target_id, uint32_t address, uint32_t data)
-{
- int retry_times = 0;
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- aice_usb_packet_flush();
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- aice_pack_htdmc(AICE_CMD_T_WRITE_EDMSR, target_id, 0, address, data,
- AICE_LITTLE_ENDIAN);
- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC,
- AICE_FORMAT_DTHMB);
- }
-
- do {
- aice_pack_htdmc(AICE_CMD_T_WRITE_EDMSR, target_id, 0, address,
- data, AICE_LITTLE_ENDIAN);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC);
-
- LOG_DEBUG("WRITE_EDMSR, COREID: %" PRIu8 ", address: 0x%" PRIx32 ", data: 0x%" PRIx32,
- target_id, address, data);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_T_WRITE_EDMSR) {
- LOG_DEBUG("WRITE_EDMSR response");
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_WRITE_EDMSR, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_switch_to_big_endian(uint32_t *word, uint8_t num_of_words)
-{
- uint32_t tmp;
-
- for (uint8_t i = 0 ; i < num_of_words ; i++) {
- tmp = ((word[i] >> 24) & 0x000000FF) |
- ((word[i] >> 8) & 0x0000FF00) |
- ((word[i] << 8) & 0x00FF0000) |
- ((word[i] << 24) & 0xFF000000);
- word[i] = tmp;
- }
-
- return ERROR_OK;
-}
-
-static int aice_write_dim(uint8_t target_id, uint32_t *word, uint8_t num_of_words)
-{
- uint32_t big_endian_word[4];
- int retry_times = 0;
-
- /** instruction is big-endian */
- memcpy(big_endian_word, word, sizeof(big_endian_word));
- aice_switch_to_big_endian(big_endian_word, num_of_words);
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- aice_usb_packet_flush();
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- aice_pack_htdmc_multiple_data(AICE_CMD_T_WRITE_DIM, target_id,
- num_of_words - 1, 0, big_endian_word, num_of_words,
- AICE_LITTLE_ENDIAN);
- return aice_usb_packet_append(usb_out_buffer,
- AICE_FORMAT_HTDMC + (num_of_words - 1) * 4,
- AICE_FORMAT_DTHMB);
- }
-
- do {
- aice_pack_htdmc_multiple_data(AICE_CMD_T_WRITE_DIM, target_id, num_of_words - 1, 0,
- big_endian_word, num_of_words, AICE_LITTLE_ENDIAN);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC + (num_of_words - 1) * 4);
-
- LOG_DEBUG("WRITE_DIM, COREID: %" PRIu8
- ", data: 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32,
- target_id,
- big_endian_word[0],
- big_endian_word[1],
- big_endian_word[2],
- big_endian_word[3]);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
-
- if (cmd_ack_code == AICE_CMD_T_WRITE_DIM) {
- LOG_DEBUG("WRITE_DIM response");
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_WRITE_DIM, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_do_execute(uint8_t target_id)
-{
- int retry_times = 0;
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- aice_usb_packet_flush();
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- aice_pack_htdmc(AICE_CMD_T_EXECUTE, target_id, 0, 0, 0, AICE_LITTLE_ENDIAN);
- return aice_usb_packet_append(usb_out_buffer,
- AICE_FORMAT_HTDMC,
- AICE_FORMAT_DTHMB);
- }
-
- do {
- aice_pack_htdmc(AICE_CMD_T_EXECUTE, target_id, 0, 0, 0, AICE_LITTLE_ENDIAN);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC);
-
- LOG_DEBUG("EXECUTE, COREID: %" PRIu8 "", target_id);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_T_EXECUTE) {
- LOG_DEBUG("EXECUTE response");
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_EXECUTE, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_write_mem_b(uint8_t target_id, uint32_t address, uint32_t data)
-{
- int retry_times = 0;
-
- LOG_DEBUG("WRITE_MEM_B, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32,
- target_id,
- address,
- data);
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) {
- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_B, target_id, 0, address,
- data & 0x000000FF, data_endian);
- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD,
- AICE_FORMAT_DTHMB);
- } else {
- do {
- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_B, target_id, 0,
- address, data & 0x000000FF, data_endian);
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_T_WRITE_MEM_B) {
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_WRITE_MEM_B, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
- }
-
- return ERROR_OK;
-}
-
-static int aice_write_mem_h(uint8_t target_id, uint32_t address, uint32_t data)
-{
- int retry_times = 0;
-
- LOG_DEBUG("WRITE_MEM_H, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32,
- target_id,
- address,
- data);
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) {
- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_H, target_id, 0,
- (address >> 1) & 0x7FFFFFFF, data & 0x0000FFFF, data_endian);
- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD,
- AICE_FORMAT_DTHMB);
- } else {
- do {
- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_H, target_id, 0,
- (address >> 1) & 0x7FFFFFFF, data & 0x0000FFFF, data_endian);
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_T_WRITE_MEM_H) {
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_WRITE_MEM_H, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
- }
-
- return ERROR_OK;
-}
-
-static int aice_write_mem(uint8_t target_id, uint32_t address, uint32_t data)
-{
- int retry_times = 0;
-
- LOG_DEBUG("WRITE_MEM, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32,
- target_id,
- address,
- data);
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) {
- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM, target_id, 0,
- (address >> 2) & 0x3FFFFFFF, data, data_endian);
- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD,
- AICE_FORMAT_DTHMB);
- } else {
- do {
- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM, target_id, 0,
- (address >> 2) & 0x3FFFFFFF, data, data_endian);
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_T_WRITE_MEM) {
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_WRITE_MEM, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
- }
-
- return ERROR_OK;
-}
-
-static int aice_fastread_mem(uint8_t target_id, uint8_t *word, uint32_t num_of_words)
-{
- int retry_times = 0;
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH))
- aice_usb_packet_flush();
-
- do {
- aice_pack_htdmb(AICE_CMD_T_FASTREAD_MEM, target_id, num_of_words - 1, 0);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB);
-
- LOG_DEBUG("FASTREAD_MEM, COREID: %" PRIu8 ", # of DATA %08" PRIx32,
- target_id, num_of_words);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA + (num_of_words - 1) * 4);
- if (result < 0) {
- LOG_ERROR("aice_usb_read failed (requested=%" PRIu32 ", result=%d)",
- AICE_FORMAT_DTHMA + (num_of_words - 1) * 4, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthma_multiple_data(&cmd_ack_code, &res_target_id,
- &extra_length, word, data_endian);
-
- if (cmd_ack_code == AICE_CMD_T_FASTREAD_MEM) {
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_FASTREAD_MEM, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_fastwrite_mem(uint8_t target_id, const uint8_t *word, uint32_t num_of_words)
-{
- int retry_times = 0;
-
- if (aice_command_mode == AICE_COMMAND_MODE_PACK) {
- aice_usb_packet_flush();
- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) {
- aice_pack_htdmd_multiple_data(AICE_CMD_T_FASTWRITE_MEM, target_id,
- num_of_words - 1, 0, word, data_endian);
- return aice_usb_packet_append(usb_out_buffer,
- AICE_FORMAT_HTDMD + (num_of_words - 1) * 4,
- AICE_FORMAT_DTHMB);
- }
-
- do {
- aice_pack_htdmd_multiple_data(AICE_CMD_T_FASTWRITE_MEM, target_id,
- num_of_words - 1, 0, word, data_endian);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD + (num_of_words - 1) * 4);
-
- LOG_DEBUG("FASTWRITE_MEM, COREID: %" PRIu8 ", # of DATA %08" PRIx32,
- target_id, num_of_words);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_T_FASTWRITE_MEM) {
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_FASTWRITE_MEM, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_read_mem_b(uint8_t target_id, uint32_t address, uint32_t *data)
-{
- int retry_times = 0;
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH))
- aice_usb_packet_flush();
-
- do {
- aice_pack_htdmb(AICE_CMD_T_READ_MEM_B, target_id, 0, address);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB);
-
- LOG_DEBUG("READ_MEM_B, COREID: %" PRIu8 "", target_id);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA);
- if (result != AICE_FORMAT_DTHMA) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMA, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length,
- data, data_endian);
-
- if (cmd_ack_code == AICE_CMD_T_READ_MEM_B) {
- LOG_DEBUG("READ_MEM_B response, data: 0x%02" PRIx32, *data);
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_READ_MEM_B, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_read_mem_h(uint8_t target_id, uint32_t address, uint32_t *data)
-{
- int retry_times = 0;
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH))
- aice_usb_packet_flush();
-
- do {
- aice_pack_htdmb(AICE_CMD_T_READ_MEM_H, target_id, 0, (address >> 1) & 0x7FFFFFFF);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB);
-
- LOG_DEBUG("READ_MEM_H, CORE_ID: %" PRIu8 "", target_id);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA);
- if (result != AICE_FORMAT_DTHMA) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMA, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length,
- data, data_endian);
-
- if (cmd_ack_code == AICE_CMD_T_READ_MEM_H) {
- LOG_DEBUG("READ_MEM_H response, data: 0x%" PRIx32, *data);
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_READ_MEM_H, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_read_mem(uint8_t target_id, uint32_t address, uint32_t *data)
-{
- int retry_times = 0;
-
- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) ||
- (aice_command_mode == AICE_COMMAND_MODE_BATCH))
- aice_usb_packet_flush();
-
- do {
- aice_pack_htdmb(AICE_CMD_T_READ_MEM, target_id, 0,
- (address >> 2) & 0x3FFFFFFF);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB);
-
- LOG_DEBUG("READ_MEM, COREID: %" PRIu8 "", target_id);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA);
- if (result != AICE_FORMAT_DTHMA) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMA, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length,
- data, data_endian);
-
- if (cmd_ack_code == AICE_CMD_T_READ_MEM) {
- LOG_DEBUG("READ_MEM response, data: 0x%" PRIx32, *data);
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_T_READ_MEM, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-static int aice_batch_buffer_read(uint8_t buf_index, uint32_t *word, uint32_t num_of_words)
-{
- int retry_times = 0;
-
- do {
- aice_pack_htdma(AICE_CMD_BATCH_BUFFER_READ, 0, num_of_words - 1, buf_index);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA);
-
- LOG_DEBUG("BATCH_BUFFER_READ, # of DATA %08" PRIx32, num_of_words);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA + (num_of_words - 1) * 4);
- if (result < 0) {
- LOG_ERROR("aice_usb_read failed (requested=%" PRIu32 ", result=%d)",
- AICE_FORMAT_DTHMA + (num_of_words - 1) * 4, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthma_multiple_data(&cmd_ack_code, &res_target_id,
- &extra_length, (uint8_t *)word, data_endian);
-
- if (cmd_ack_code == AICE_CMD_BATCH_BUFFER_READ) {
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_BATCH_BUFFER_READ, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-int aice_batch_buffer_write(uint8_t buf_index, const uint8_t *word, uint32_t num_of_words)
-{
- int retry_times = 0;
-
- if (num_of_words == 0)
- return ERROR_OK;
-
- do {
- /* only pack AICE_CMD_BATCH_BUFFER_WRITE command header */
- aice_pack_htdmc(AICE_CMD_BATCH_BUFFER_WRITE, 0, num_of_words - 1, buf_index,
- 0, data_endian);
-
- /* use append instead of pack */
- memcpy(usb_out_buffer + 4, word, num_of_words * 4);
-
- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC + (num_of_words - 1) * 4);
-
- LOG_DEBUG("BATCH_BUFFER_WRITE, # of DATA %08" PRIx32, num_of_words);
-
- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB);
- if (result != AICE_FORMAT_DTHMB) {
- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)",
- AICE_FORMAT_DTHMB, result);
- return ERROR_FAIL;
- }
-
- uint8_t cmd_ack_code;
- uint8_t extra_length;
- uint8_t res_target_id;
- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length);
-
- if (cmd_ack_code == AICE_CMD_BATCH_BUFFER_WRITE) {
- break;
- } else {
- if (retry_times > aice_max_retry_times) {
- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")",
- AICE_CMD_BATCH_BUFFER_WRITE, cmd_ack_code);
-
- return ERROR_FAIL;
- }
-
- /* clear timeout and retry */
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- retry_times++;
- }
- } while (1);
-
- return ERROR_OK;
-}
-
-/***************************************************************************/
-/* End of AICE commands */
-
-typedef int (*read_mem_func_t)(uint32_t coreid, uint32_t address, uint32_t *data);
-typedef int (*write_mem_func_t)(uint32_t coreid, uint32_t address, uint32_t data);
-
-static struct aice_nds32_info core_info[AICE_MAX_NUM_CORE];
-static uint8_t total_num_of_core;
-
-static char *custom_srst_script;
-static char *custom_trst_script;
-static char *custom_restart_script;
-static uint32_t aice_count_to_check_dbger = 30;
-
-static int aice_read_reg(uint32_t coreid, uint32_t num, uint32_t *val);
-static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val);
-
-static int check_suppressed_exception(uint32_t coreid, uint32_t dbger_value)
-{
- uint32_t ir4_value = 0;
- uint32_t ir6_value = 0;
- /* the default value of handling_suppressed_exception is false */
- static bool handling_suppressed_exception;
-
- if (handling_suppressed_exception)
- return ERROR_OK;
-
- if ((dbger_value & NDS_DBGER_ALL_SUPRS_EX) == NDS_DBGER_ALL_SUPRS_EX) {
- LOG_ERROR("<-- TARGET WARNING! Exception is detected and suppressed. -->");
- handling_suppressed_exception = true;
-
- aice_read_reg(coreid, IR4, &ir4_value);
- /* Clear IR6.SUPRS_EXC, IR6.IMP_EXC */
- aice_read_reg(coreid, IR6, &ir6_value);
- /*
- * For MCU version(MSC_CFG.MCU == 1) like V3m
- * | SWID[30:16] | Reserved[15:10] | SUPRS_EXC[9] | IMP_EXC[8]
- * |VECTOR[7:5] | INST[4] | Exc Type[3:0] |
- *
- * For non-MCU version(MSC_CFG.MCU == 0) like V3
- * | SWID[30:16] | Reserved[15:14] | SUPRS_EXC[13] | IMP_EXC[12]
- * | VECTOR[11:5] | INST[4] | Exc Type[3:0] |
- */
- LOG_INFO("EVA: 0x%08" PRIx32, ir4_value);
- LOG_INFO("ITYPE: 0x%08" PRIx32, ir6_value);
-
- ir6_value = ir6_value & (~0x300); /* for MCU */
- ir6_value = ir6_value & (~0x3000); /* for non-MCU */
- aice_write_reg(coreid, IR6, ir6_value);
-
- handling_suppressed_exception = false;
- }
-
- return ERROR_OK;
-}
-
-static int check_privilege(uint32_t coreid, uint32_t dbger_value)
-{
- if ((dbger_value & NDS_DBGER_ILL_SEC_ACC) == NDS_DBGER_ILL_SEC_ACC) {
- LOG_ERROR("<-- TARGET ERROR! Insufficient security privilege "
- "to execute the debug operations. -->");
-
- /* Clear DBGER.ILL_SEC_ACC */
- if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER,
- NDS_DBGER_ILL_SEC_ACC) != ERROR_OK)
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int aice_check_dbger(uint32_t coreid, uint32_t expect_status)
-{
- uint32_t i = 0;
- uint32_t value_dbger = 0;
-
- while (1) {
- aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &value_dbger);
-
- if ((value_dbger & expect_status) == expect_status) {
- if (check_suppressed_exception(coreid, value_dbger) != ERROR_OK)
- return ERROR_FAIL;
- if (check_privilege(coreid, value_dbger) != ERROR_OK)
- return ERROR_FAIL;
- return ERROR_OK;
- }
-
- if ((i % 30) == 0)
- keep_alive();
-
- int64_t then = 0;
- if (i == aice_count_to_check_dbger)
- then = timeval_ms();
- if (i >= aice_count_to_check_dbger) {
- if ((timeval_ms() - then) > 1000) {
- LOG_ERROR("Timeout (1000ms) waiting for $DBGER status "
- "being 0x%08" PRIx32, expect_status);
- return ERROR_FAIL;
- }
- }
- i++;
- }
-
- return ERROR_FAIL;
-}
-
-static int aice_execute_dim(uint32_t coreid, uint32_t *insts, uint8_t n_inst)
-{
- /** fill DIM */
- if (aice_write_dim(coreid, insts, n_inst) != ERROR_OK)
- return ERROR_FAIL;
-
- /** clear DBGER.DPED */
- if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_DPED) != ERROR_OK)
- return ERROR_FAIL;
-
- /** execute DIM */
- if (aice_do_execute(coreid) != ERROR_OK)
- return ERROR_FAIL;
-
- /** read DBGER.DPED */
- if (aice_check_dbger(coreid, NDS_DBGER_DPED) != ERROR_OK) {
- LOG_ERROR("<-- TARGET ERROR! Debug operations do not finish properly: "
- "0x%08" PRIx32 "0x%08" PRIx32 "0x%08" PRIx32 "0x%08" PRIx32 ". -->",
- insts[0],
- insts[1],
- insts[2],
- insts[3]);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int aice_read_reg(uint32_t coreid, uint32_t num, uint32_t *val)
-{
- LOG_DEBUG("aice_read_reg, reg_no: 0x%08" PRIx32, num);
-
- uint32_t instructions[4]; /** execute instructions in DIM */
-
- if (nds32_reg_type(num) == NDS32_REG_TYPE_GPR) { /* general registers */
- instructions[0] = MTSR_DTR(num);
- instructions[1] = DSB;
- instructions[2] = NOP;
- instructions[3] = BEQ_MINUS_12;
- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_SPR) { /* user special registers */
- instructions[0] = MFUSR_G0(0, nds32_reg_sr_index(num));
- instructions[1] = MTSR_DTR(0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_AUMR) { /* audio registers */
- if ((num >= CB_CTL) && (num <= CBE3)) {
- instructions[0] = AMFAR2(0, nds32_reg_sr_index(num));
- instructions[1] = MTSR_DTR(0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- } else {
- instructions[0] = AMFAR(0, nds32_reg_sr_index(num));
- instructions[1] = MTSR_DTR(0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- }
- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_FPU) { /* fpu registers */
- if (num == FPCSR) {
- instructions[0] = FMFCSR;
- instructions[1] = MTSR_DTR(0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- } else if (num == FPCFG) {
- instructions[0] = FMFCFG;
- instructions[1] = MTSR_DTR(0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- } else {
- if (num >= FS0 && num <= FS31) { /* single precision */
- instructions[0] = FMFSR(0, nds32_reg_sr_index(num));
- instructions[1] = MTSR_DTR(0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- } else if (num >= FD0 && num <= FD31) { /* double precision */
- instructions[0] = FMFDR(0, nds32_reg_sr_index(num));
- instructions[1] = MTSR_DTR(0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- }
- }
- } else { /* system registers */
- instructions[0] = MFSR(0, nds32_reg_sr_index(num));
- instructions[1] = MTSR_DTR(0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- }
-
- aice_execute_dim(coreid, instructions, 4);
-
- uint32_t value_edmsw = 0;
- aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw);
- if (value_edmsw & NDS_EDMSW_WDV)
- aice_read_dtr(coreid, val);
- else {
- LOG_ERROR("<-- TARGET ERROR! The debug target failed to update "
- "the DTR register. -->");
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_read_reg(uint32_t coreid, uint32_t num, uint32_t *val)
-{
- LOG_DEBUG("aice_usb_read_reg");
-
- if (num == R0) {
- *val = core_info[coreid].r0_backup;
- } else if (num == R1) {
- *val = core_info[coreid].r1_backup;
- } else if (num == DR41) {
- /* As target is halted, OpenOCD will backup DR41/DR42/DR43.
- * As user wants to read these registers, OpenOCD should return
- * the backup values, instead of reading the real values.
- * As user wants to write these registers, OpenOCD should write
- * to the backup values, instead of writing to real registers. */
- *val = core_info[coreid].edmsw_backup;
- } else if (num == DR42) {
- *val = core_info[coreid].edm_ctl_backup;
- } else if ((core_info[coreid].target_dtr_valid == true) && (num == DR43)) {
- *val = core_info[coreid].target_dtr_backup;
- } else {
- if (aice_read_reg(coreid, num, val) != ERROR_OK)
- *val = 0xBBADBEEF;
- }
-
- return ERROR_OK;
-}
-
-static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val)
-{
- LOG_DEBUG("aice_write_reg, reg_no: 0x%08" PRIx32 ", value: 0x%08" PRIx32, num, val);
-
- uint32_t instructions[4]; /** execute instructions in DIM */
- uint32_t value_edmsw = 0;
-
- aice_write_dtr(coreid, val);
- aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw);
- if (0 == (value_edmsw & NDS_EDMSW_RDV)) {
- LOG_ERROR("<-- TARGET ERROR! AICE failed to write to the DTR register. -->");
- return ERROR_FAIL;
- }
-
- if (nds32_reg_type(num) == NDS32_REG_TYPE_GPR) { /* general registers */
- instructions[0] = MFSR_DTR(num);
- instructions[1] = DSB;
- instructions[2] = NOP;
- instructions[3] = BEQ_MINUS_12;
- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_SPR) { /* user special registers */
- instructions[0] = MFSR_DTR(0);
- instructions[1] = MTUSR_G0(0, nds32_reg_sr_index(num));
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_AUMR) { /* audio registers */
- if ((num >= CB_CTL) && (num <= CBE3)) {
- instructions[0] = MFSR_DTR(0);
- instructions[1] = AMTAR2(0, nds32_reg_sr_index(num));
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- } else {
- instructions[0] = MFSR_DTR(0);
- instructions[1] = AMTAR(0, nds32_reg_sr_index(num));
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- }
- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_FPU) { /* fpu registers */
- if (num == FPCSR) {
- instructions[0] = MFSR_DTR(0);
- instructions[1] = FMTCSR;
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- } else if (num == FPCFG) {
- /* FPCFG is readonly */
- } else {
- if (num >= FS0 && num <= FS31) { /* single precision */
- instructions[0] = MFSR_DTR(0);
- instructions[1] = FMTSR(0, nds32_reg_sr_index(num));
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- } else if (num >= FD0 && num <= FD31) { /* double precision */
- instructions[0] = MFSR_DTR(0);
- instructions[1] = FMTDR(0, nds32_reg_sr_index(num));
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- }
- }
- } else {
- instructions[0] = MFSR_DTR(0);
- instructions[1] = MTSR(0, nds32_reg_sr_index(num));
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- }
-
- return aice_execute_dim(coreid, instructions, 4);
-}
-
-static int aice_usb_write_reg(uint32_t coreid, uint32_t num, uint32_t val)
-{
- LOG_DEBUG("aice_usb_write_reg");
-
- if (num == R0)
- core_info[coreid].r0_backup = val;
- else if (num == R1)
- core_info[coreid].r1_backup = val;
- else if (num == DR42)
- /* As target is halted, OpenOCD will backup DR41/DR42/DR43.
- * As user wants to read these registers, OpenOCD should return
- * the backup values, instead of reading the real values.
- * As user wants to write these registers, OpenOCD should write
- * to the backup values, instead of writing to real registers. */
- core_info[coreid].edm_ctl_backup = val;
- else if ((core_info[coreid].target_dtr_valid == true) && (num == DR43))
- core_info[coreid].target_dtr_backup = val;
- else
- return aice_write_reg(coreid, num, val);
-
- return ERROR_OK;
-}
-
-static int aice_usb_open(struct aice_port_param_s *param)
-{
- const uint16_t vids[] = { param->vid, 0 };
- const uint16_t pids[] = { param->pid, 0 };
- struct libusb_device_handle *devh;
-
- if (jtag_libusb_open(vids, pids, &devh, NULL) != ERROR_OK)
- return ERROR_FAIL;
-
- /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS
- * AREA!!!!!!!!!!! The behavior of libusb is not completely
- * consistent across Windows, Linux, and Mac OS X platforms.
- * The actions taken in the following compiler conditionals may
- * not agree with published documentation for libusb, but were
- * found to be necessary through trials and tribulations. Even
- * little tweaks can break one or more platforms, so if you do
- * make changes test them carefully on all platforms before
- * committing them!
- */
-
-#if IS_WIN32 == 0
-
- libusb_reset_device(devh);
-
-#if IS_DARWIN == 0
-
- int timeout = 5;
- /* reopen jlink after usb_reset
- * on win32 this may take a second or two to re-enumerate */
- int retval;
- while ((retval = jtag_libusb_open(vids, pids, &devh, NULL)) != ERROR_OK) {
- usleep(1000);
- timeout--;
- if (!timeout)
- break;
- }
- if (retval != ERROR_OK)
- return ERROR_FAIL;
-#endif
-
-#endif
-
- /* usb_set_configuration required under win32 */
- libusb_set_configuration(devh, 0);
- libusb_claim_interface(devh, 0);
-
- unsigned int aice_read_ep;
- unsigned int aice_write_ep;
-
- jtag_libusb_choose_interface(devh, &aice_read_ep, &aice_write_ep, -1, -1, -1, LIBUSB_TRANSFER_TYPE_BULK);
- LOG_DEBUG("aice_read_ep=0x%x, aice_write_ep=0x%x", aice_read_ep, aice_write_ep);
-
- aice_handler.usb_read_ep = aice_read_ep;
- aice_handler.usb_write_ep = aice_write_ep;
- aice_handler.usb_handle = devh;
-
- return ERROR_OK;
-}
-
-static int aice_usb_read_reg_64(uint32_t coreid, uint32_t num, uint64_t *val)
-{
- LOG_DEBUG("aice_usb_read_reg_64, %s", nds32_reg_simple_name(num));
-
- uint32_t value;
- uint32_t high_value;
-
- if (aice_read_reg(coreid, num, &value) != ERROR_OK)
- value = 0xBBADBEEF;
-
- aice_read_reg(coreid, R1, &high_value);
-
- LOG_DEBUG("low: 0x%08" PRIx32 ", high: 0x%08" PRIx32 "\n", value, high_value);
-
- if (data_endian == AICE_BIG_ENDIAN)
- *val = (((uint64_t)high_value) << 32) | value;
- else
- *val = (((uint64_t)value) << 32) | high_value;
-
- return ERROR_OK;
-}
-
-static int aice_usb_write_reg_64(uint32_t coreid, uint32_t num, uint64_t val)
-{
- uint32_t value;
- uint32_t high_value;
-
- if (data_endian == AICE_BIG_ENDIAN) {
- value = val & 0xFFFFFFFF;
- high_value = (val >> 32) & 0xFFFFFFFF;
- } else {
- high_value = val & 0xFFFFFFFF;
- value = (val >> 32) & 0xFFFFFFFF;
- }
-
- LOG_DEBUG("aice_usb_write_reg_64, %s, low: 0x%08" PRIx32 ", high: 0x%08" PRIx32 "\n",
- nds32_reg_simple_name(num), value, high_value);
-
- aice_write_reg(coreid, R1, high_value);
- return aice_write_reg(coreid, num, value);
-}
-
-static int aice_get_version_info(void)
-{
- uint32_t hardware_version;
- uint32_t firmware_version;
- uint32_t fpga_version;
-
- if (aice_read_ctrl(AICE_READ_CTRL_GET_HARDWARE_VERSION, &hardware_version) != ERROR_OK)
- return ERROR_FAIL;
-
- if (aice_read_ctrl(AICE_READ_CTRL_GET_FIRMWARE_VERSION, &firmware_version) != ERROR_OK)
- return ERROR_FAIL;
-
- if (aice_read_ctrl(AICE_READ_CTRL_GET_FPGA_VERSION, &fpga_version) != ERROR_OK)
- return ERROR_FAIL;
-
- LOG_INFO("AICE version: hw_ver = 0x%" PRIx32 ", fw_ver = 0x%" PRIx32 ", fpga_ver = 0x%" PRIx32,
- hardware_version, firmware_version, fpga_version);
-
- return ERROR_OK;
-}
-
-#define LINE_BUFFER_SIZE 1024
-
-static int aice_execute_custom_script(const char *script)
-{
- FILE *script_fd;
- char line_buffer[LINE_BUFFER_SIZE];
- char *op_str;
- char *reset_str;
- uint32_t delay;
- uint32_t write_ctrl_value;
- bool set_op;
-
- script_fd = fopen(script, "r");
- if (!script_fd) {
- return ERROR_FAIL;
- } else {
- while (fgets(line_buffer, LINE_BUFFER_SIZE, script_fd)) {
- /* execute operations */
- set_op = false;
- op_str = strstr(line_buffer, "set");
- if (op_str) {
- set_op = true;
- goto get_reset_type;
- }
-
- op_str = strstr(line_buffer, "clear");
- if (!op_str)
- continue;
-get_reset_type:
- reset_str = strstr(op_str, "srst");
- if (reset_str) {
- if (set_op)
- write_ctrl_value = AICE_CUSTOM_DELAY_SET_SRST;
- else
- write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_SRST;
- goto get_delay;
- }
- reset_str = strstr(op_str, "dbgi");
- if (reset_str) {
- if (set_op)
- write_ctrl_value = AICE_CUSTOM_DELAY_SET_DBGI;
- else
- write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_DBGI;
- goto get_delay;
- }
- reset_str = strstr(op_str, "trst");
- if (reset_str) {
- if (set_op)
- write_ctrl_value = AICE_CUSTOM_DELAY_SET_TRST;
- else
- write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_TRST;
- goto get_delay;
- }
- continue;
-get_delay:
- /* get delay */
- delay = strtoul(reset_str + 4, NULL, 0);
- write_ctrl_value |= (delay << 16);
-
- if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY,
- write_ctrl_value) != ERROR_OK) {
- fclose(script_fd);
- return ERROR_FAIL;
- }
- }
- fclose(script_fd);
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_set_clock(int set_clock)
-{
- if (set_clock & AICE_TCK_CONTROL_TCK_SCAN) {
- if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL,
- AICE_TCK_CONTROL_TCK_SCAN) != ERROR_OK)
- return ERROR_FAIL;
-
- /* Read out TCK_SCAN clock value */
- uint32_t scan_clock;
- if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &scan_clock) != ERROR_OK)
- return ERROR_FAIL;
-
- scan_clock &= 0x0F;
-
- uint32_t scan_base_freq;
- if (scan_clock & 0x8)
- scan_base_freq = 48000; /* 48 MHz */
- else
- scan_base_freq = 30000; /* 30 MHz */
-
- uint32_t set_base_freq;
- if (set_clock & 0x8)
- set_base_freq = 48000;
- else
- set_base_freq = 30000;
-
- uint32_t set_freq;
- uint32_t scan_freq;
- set_freq = set_base_freq >> (set_clock & 0x7);
- scan_freq = scan_base_freq >> (scan_clock & 0x7);
-
- if (scan_freq < set_freq) {
- LOG_ERROR("User specifies higher jtag clock than TCK_SCAN clock");
- return ERROR_FAIL;
- }
- }
-
- if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL, set_clock) != ERROR_OK)
- return ERROR_FAIL;
-
- uint32_t check_speed;
- if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &check_speed) != ERROR_OK)
- return ERROR_FAIL;
-
- if (((int)check_speed & 0x0F) != set_clock) {
- LOG_ERROR("Set jtag clock failed");
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int aice_edm_init(uint32_t coreid)
-{
- aice_write_edmsr(coreid, NDS_EDM_SR_DIMBR, 0xFFFF0000);
- aice_write_misc(coreid, NDS_EDM_MISC_DIMIR, 0);
-
- /* unconditionally try to turn on V3_EDM_MODE */
- uint32_t edm_ctl_value;
- aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, &edm_ctl_value);
- aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value | 0x00000040);
-
- /* clear DBGER */
- aice_write_misc(coreid, NDS_EDM_MISC_DBGER,
- NDS_DBGER_DPED | NDS_DBGER_CRST | NDS_DBGER_AT_MAX);
-
- /* get EDM version */
- uint32_t value_edmcfg;
- aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CFG, &value_edmcfg);
- core_info[coreid].edm_version = (value_edmcfg >> 16) & 0xFFFF;
-
- return ERROR_OK;
-}
-
-static bool is_v2_edm(uint32_t coreid)
-{
- if ((core_info[coreid].edm_version & 0x1000) == 0)
- return true;
- else
- return false;
-}
-
-static int aice_init_edm_registers(uint32_t coreid, bool clear_dex_use_psw)
-{
- /* enable DEH_SEL & MAX_STOP & V3_EDM_MODE & DBGI_MASK */
- uint32_t host_edm_ctl = core_info[coreid].edm_ctl_backup | 0xA000004F;
- if (clear_dex_use_psw)
- /* After entering debug mode, OpenOCD may set
- * DEX_USE_PSW accidentally through backup value
- * of target EDM_CTL.
- * So, clear DEX_USE_PSW by force. */
- host_edm_ctl &= ~(0x40000000);
-
- LOG_DEBUG("aice_init_edm_registers - EDM_CTL: 0x%08" PRIx32, host_edm_ctl);
-
- int result = aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, host_edm_ctl);
-
- return result;
-}
-
-/**
- * EDM_CTL will be modified by OpenOCD as debugging. OpenOCD has the
- * responsibility to keep EDM_CTL untouched after debugging.
- *
- * There are two scenarios to consider:
- * 1. single step/running as debugging (running under debug session)
- * 2. detached from gdb (exit debug session)
- *
- * So, we need to bakcup EDM_CTL before halted and restore it after
- * running. The difference of these two scenarios is EDM_CTL.DEH_SEL
- * is on for scenario 1, and off for scenario 2.
- */
-static int aice_backup_edm_registers(uint32_t coreid)
-{
- int result = aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL,
- &core_info[coreid].edm_ctl_backup);
-
- /* To call aice_backup_edm_registers() after DEX on, DEX_USE_PSW
- * may be not correct. (For example, hit breakpoint, then backup
- * EDM_CTL. EDM_CTL.DEX_USE_PSW will be cleared.) Because debug
- * interrupt will clear DEX_USE_PSW, DEX_USE_PSW is always off after
- * DEX is on. It only backups correct value before OpenOCD issues DBGI.
- * (Backup EDM_CTL, then issue DBGI actively (refer aice_usb_halt())) */
- if (core_info[coreid].edm_ctl_backup & 0x40000000)
- core_info[coreid].dex_use_psw_on = true;
- else
- core_info[coreid].dex_use_psw_on = false;
-
- LOG_DEBUG("aice_backup_edm_registers - EDM_CTL: 0x%08" PRIx32 ", DEX_USE_PSW: %s",
- core_info[coreid].edm_ctl_backup,
- core_info[coreid].dex_use_psw_on ? "on" : "off");
-
- return result;
-}
-
-static int aice_restore_edm_registers(uint32_t coreid)
-{
- LOG_DEBUG("aice_restore_edm_registers -");
-
- /* set DEH_SEL, because target still under EDM control */
- int result = aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL,
- core_info[coreid].edm_ctl_backup | 0x80000000);
-
- return result;
-}
-
-static int aice_backup_tmp_registers(uint32_t coreid)
-{
- LOG_DEBUG("backup_tmp_registers -");
-
- /* backup target DTR first(if the target DTR is valid) */
- uint32_t value_edmsw = 0;
- aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw);
- core_info[coreid].edmsw_backup = value_edmsw;
- if (value_edmsw & 0x1) { /* EDMSW.WDV == 1 */
- aice_read_dtr(coreid, &core_info[coreid].target_dtr_backup);
- core_info[coreid].target_dtr_valid = true;
-
- LOG_DEBUG("Backup target DTR: 0x%08" PRIx32, core_info[coreid].target_dtr_backup);
- } else {
- core_info[coreid].target_dtr_valid = false;
- }
-
- /* Target DTR has been backup, then backup $R0 and $R1 */
- aice_read_reg(coreid, R0, &core_info[coreid].r0_backup);
- aice_read_reg(coreid, R1, &core_info[coreid].r1_backup);
-
- /* backup host DTR(if the host DTR is valid) */
- if (value_edmsw & 0x2) { /* EDMSW.RDV == 1*/
- /* read out host DTR and write into target DTR, then use aice_read_edmsr to
- * read out */
- uint32_t instructions[4] = {
- MFSR_DTR(R0), /* R0 has already been backup */
- DSB,
- MTSR_DTR(R0),
- BEQ_MINUS_12
- };
- aice_execute_dim(coreid, instructions, 4);
-
- aice_read_dtr(coreid, &core_info[coreid].host_dtr_backup);
- core_info[coreid].host_dtr_valid = true;
-
- LOG_DEBUG("Backup host DTR: 0x%08" PRIx32, core_info[coreid].host_dtr_backup);
- } else {
- core_info[coreid].host_dtr_valid = false;
- }
-
- LOG_DEBUG("r0: 0x%08" PRIx32 ", r1: 0x%08" PRIx32,
- core_info[coreid].r0_backup, core_info[coreid].r1_backup);
-
- return ERROR_OK;
-}
-
-static int aice_restore_tmp_registers(uint32_t coreid)
-{
- LOG_DEBUG("restore_tmp_registers - r0: 0x%08" PRIx32 ", r1: 0x%08" PRIx32,
- core_info[coreid].r0_backup, core_info[coreid].r1_backup);
-
- if (core_info[coreid].target_dtr_valid) {
- uint32_t instructions[4] = {
- SETHI(R0, core_info[coreid].target_dtr_backup >> 12),
- ORI(R0, R0, core_info[coreid].target_dtr_backup & 0x00000FFF),
- NOP,
- BEQ_MINUS_12
- };
- aice_execute_dim(coreid, instructions, 4);
-
- instructions[0] = MTSR_DTR(R0);
- instructions[1] = DSB;
- instructions[2] = NOP;
- instructions[3] = BEQ_MINUS_12;
- aice_execute_dim(coreid, instructions, 4);
-
- LOG_DEBUG("Restore target DTR: 0x%08" PRIx32, core_info[coreid].target_dtr_backup);
- }
-
- aice_write_reg(coreid, R0, core_info[coreid].r0_backup);
- aice_write_reg(coreid, R1, core_info[coreid].r1_backup);
-
- if (core_info[coreid].host_dtr_valid) {
- aice_write_dtr(coreid, core_info[coreid].host_dtr_backup);
-
- LOG_DEBUG("Restore host DTR: 0x%08" PRIx32, core_info[coreid].host_dtr_backup);
- }
-
- return ERROR_OK;
-}
-
-static int aice_open_device(struct aice_port_param_s *param)
-{
- if (aice_usb_open(param) != ERROR_OK)
- return ERROR_FAIL;
-
- if (aice_get_version_info() == ERROR_FAIL) {
- LOG_ERROR("Cannot get AICE version!");
- return ERROR_FAIL;
- }
-
- LOG_INFO("AICE initialization started");
-
- /* attempt to reset Andes EDM */
- if (aice_reset_box() == ERROR_FAIL) {
- LOG_ERROR("Cannot initial AICE box!");
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_set_jtag_clock(uint32_t a_clock)
-{
- jtag_clock = a_clock;
-
- if (aice_usb_set_clock(a_clock) != ERROR_OK) {
- LOG_ERROR("Cannot set AICE JTAG clock!");
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_close(void)
-{
- jtag_libusb_close(aice_handler.usb_handle);
-
- free(custom_srst_script);
- free(custom_trst_script);
- free(custom_restart_script);
- return ERROR_OK;
-}
-
-static int aice_core_init(uint32_t coreid)
-{
- core_info[coreid].access_channel = NDS_MEMORY_ACC_CPU;
- core_info[coreid].memory_select = NDS_MEMORY_SELECT_AUTO;
- core_info[coreid].core_state = AICE_TARGET_UNKNOWN;
-
- return ERROR_OK;
-}
-
-static int aice_usb_idcode(uint32_t *idcode, uint8_t *num_of_idcode)
-{
- int retval;
-
- retval = aice_scan_chain(idcode, num_of_idcode);
- if (retval == ERROR_OK) {
- for (int i = 0; i < *num_of_idcode; i++) {
- aice_core_init(i);
- aice_edm_init(i);
- }
- total_num_of_core = *num_of_idcode;
- }
-
- return retval;
-}
-
-static int aice_usb_halt(uint32_t coreid)
-{
- if (core_info[coreid].core_state == AICE_TARGET_HALTED) {
- LOG_DEBUG("aice_usb_halt check halted");
- return ERROR_OK;
- }
-
- LOG_DEBUG("aice_usb_halt");
-
- /** backup EDM registers */
- aice_backup_edm_registers(coreid);
- /** init EDM for host debugging */
- /** no need to clear dex_use_psw, because dbgi will clear it */
- aice_init_edm_registers(coreid, false);
-
- /** Clear EDM_CTL.DBGIM & EDM_CTL.DBGACKM */
- uint32_t edm_ctl_value = 0;
- aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, &edm_ctl_value);
- if (edm_ctl_value & 0x3)
- aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value & ~(0x3));
-
- uint32_t dbger = 0;
- uint32_t acc_ctl_value = 0;
-
- core_info[coreid].debug_under_dex_on = false;
- aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &dbger);
-
- if (dbger & NDS_DBGER_AT_MAX)
- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level. -->");
-
- if (dbger & NDS_DBGER_DEX) {
- if (is_v2_edm(coreid) == false) {
- /** debug 'debug mode'. use force_debug to issue dbgi */
- aice_read_misc(coreid, NDS_EDM_MISC_ACC_CTL, &acc_ctl_value);
- acc_ctl_value |= 0x8;
- aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, acc_ctl_value);
- core_info[coreid].debug_under_dex_on = true;
-
- aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0);
- /* If CPU stalled due to AT_MAX, clear AT_MAX status. */
- if (dbger & NDS_DBGER_AT_MAX)
- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_AT_MAX);
- }
- } else {
- /** Issue DBGI normally */
- aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0);
- /* If CPU stalled due to AT_MAX, clear AT_MAX status. */
- if (dbger & NDS_DBGER_AT_MAX)
- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_AT_MAX);
- }
-
- if (aice_check_dbger(coreid, NDS_DBGER_DEX) != ERROR_OK) {
- LOG_ERROR("<-- TARGET ERROR! Unable to stop the debug target through DBGI. -->");
- return ERROR_FAIL;
- }
-
- if (core_info[coreid].debug_under_dex_on) {
- if (core_info[coreid].dex_use_psw_on == false) {
- /* under debug 'debug mode', force $psw to 'debug mode' behavior */
- /* !!!NOTICE!!! this is workaround for debug 'debug mode'.
- * it is only for debugging 'debug exception handler' purpose.
- * after openocd detaches from target, target behavior is
- * undefined. */
- uint32_t ir0_value = 0;
- uint32_t debug_mode_ir0_value;
- aice_read_reg(coreid, IR0, &ir0_value);
- debug_mode_ir0_value = ir0_value | 0x408; /* turn on DEX, set POM = 1 */
- debug_mode_ir0_value &= ~(0x000000C1); /* turn off DT/IT/GIE */
- aice_write_reg(coreid, IR0, debug_mode_ir0_value);
- }
- }
-
- /** set EDM_CTL.DBGIM & EDM_CTL.DBGACKM after halt */
- if (edm_ctl_value & 0x3)
- aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value);
-
- /* backup r0 & r1 */
- aice_backup_tmp_registers(coreid);
- core_info[coreid].core_state = AICE_TARGET_HALTED;
-
- return ERROR_OK;
-}
-
-static int aice_usb_state(uint32_t coreid, enum aice_target_state_s *state)
-{
- uint32_t dbger_value;
- uint32_t ice_state;
-
- int result = aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &dbger_value);
-
- if (result == ERROR_AICE_TIMEOUT) {
- if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &ice_state) != ERROR_OK) {
- LOG_ERROR("<-- AICE ERROR! AICE is unplugged. -->");
- return ERROR_FAIL;
- }
-
- if ((ice_state & 0x20) == 0) {
- LOG_ERROR("<-- TARGET ERROR! Target is disconnected with AICE. -->");
- return ERROR_FAIL;
- } else {
- return ERROR_FAIL;
- }
- } else if (result == ERROR_AICE_DISCONNECT) {
- LOG_ERROR("<-- AICE ERROR! AICE is unplugged. -->");
- return ERROR_FAIL;
- }
-
- if ((dbger_value & NDS_DBGER_ILL_SEC_ACC) == NDS_DBGER_ILL_SEC_ACC) {
- LOG_ERROR("<-- TARGET ERROR! Insufficient security privilege. -->");
-
- /* Clear ILL_SEC_ACC */
- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_ILL_SEC_ACC);
-
- *state = AICE_TARGET_RUNNING;
- core_info[coreid].core_state = AICE_TARGET_RUNNING;
- } else if ((dbger_value & NDS_DBGER_AT_MAX) == NDS_DBGER_AT_MAX) {
- /* Issue DBGI to exit cpu stall */
- aice_usb_halt(coreid);
-
- /* Read OIPC to find out the trigger point */
- uint32_t ir11_value;
- aice_read_reg(coreid, IR11, &ir11_value);
-
- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level; "
- "CPU is stalled at 0x%08" PRIx32 " for debugging. -->", ir11_value);
-
- *state = AICE_TARGET_HALTED;
- } else if ((dbger_value & NDS_DBGER_CRST) == NDS_DBGER_CRST) {
- LOG_DEBUG("DBGER.CRST is on.");
-
- *state = AICE_TARGET_RESET;
- core_info[coreid].core_state = AICE_TARGET_RUNNING;
-
- /* Clear CRST */
- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_CRST);
- } else if ((dbger_value & NDS_DBGER_DEX) == NDS_DBGER_DEX) {
- if (core_info[coreid].core_state == AICE_TARGET_RUNNING) {
- /* enter debug mode, init EDM registers */
- /* backup EDM registers */
- aice_backup_edm_registers(coreid);
- /* init EDM for host debugging */
- aice_init_edm_registers(coreid, true);
- aice_backup_tmp_registers(coreid);
- core_info[coreid].core_state = AICE_TARGET_HALTED;
- } else if (core_info[coreid].core_state == AICE_TARGET_UNKNOWN) {
- /* debug 'debug mode', use force debug to halt core */
- aice_usb_halt(coreid);
- }
- *state = AICE_TARGET_HALTED;
- } else {
- *state = AICE_TARGET_RUNNING;
- core_info[coreid].core_state = AICE_TARGET_RUNNING;
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_reset(void)
-{
- if (aice_reset_box() != ERROR_OK)
- return ERROR_FAIL;
-
- /* issue TRST */
- if (!custom_trst_script) {
- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL,
- AICE_JTAG_PIN_CONTROL_TRST) != ERROR_OK)
- return ERROR_FAIL;
- } else {
- /* custom trst operations */
- if (aice_execute_custom_script(custom_trst_script) != ERROR_OK)
- return ERROR_FAIL;
- }
-
- if (aice_usb_set_clock(jtag_clock) != ERROR_OK)
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int aice_issue_srst(uint32_t coreid)
-{
- LOG_DEBUG("aice_issue_srst");
-
- /* After issuing srst, target will be running. So we need to restore EDM_CTL. */
- aice_restore_edm_registers(coreid);
-
- if (!custom_srst_script) {
- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL,
- AICE_JTAG_PIN_CONTROL_SRST) != ERROR_OK)
- return ERROR_FAIL;
- } else {
- /* custom srst operations */
- if (aice_execute_custom_script(custom_srst_script) != ERROR_OK)
- return ERROR_FAIL;
- }
-
- /* wait CRST infinitely */
- uint32_t dbger_value;
- int i = 0;
- while (1) {
- if (aice_read_misc(coreid,
- NDS_EDM_MISC_DBGER, &dbger_value) != ERROR_OK)
- return ERROR_FAIL;
-
- if (dbger_value & NDS_DBGER_CRST)
- break;
-
- if ((i % 30) == 0)
- keep_alive();
- i++;
- }
-
- core_info[coreid].host_dtr_valid = false;
- core_info[coreid].target_dtr_valid = false;
-
- core_info[coreid].core_state = AICE_TARGET_RUNNING;
- return ERROR_OK;
-}
-
-static int aice_issue_reset_hold(uint32_t coreid)
-{
- LOG_DEBUG("aice_issue_reset_hold");
-
- /* set no_dbgi_pin to 0 */
- uint32_t pin_status;
- aice_read_ctrl(AICE_READ_CTRL_GET_JTAG_PIN_STATUS, &pin_status);
- if (pin_status & 0x4)
- aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status & (~0x4));
-
- /* issue restart */
- if (!custom_restart_script) {
- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL,
- AICE_JTAG_PIN_CONTROL_RESTART) != ERROR_OK)
- return ERROR_FAIL;
- } else {
- /* custom restart operations */
- if (aice_execute_custom_script(custom_restart_script) != ERROR_OK)
- return ERROR_FAIL;
- }
-
- if (aice_check_dbger(coreid, NDS_DBGER_CRST | NDS_DBGER_DEX) == ERROR_OK) {
- aice_backup_tmp_registers(coreid);
- core_info[coreid].core_state = AICE_TARGET_HALTED;
-
- return ERROR_OK;
- } else {
- /* set no_dbgi_pin to 1 */
- aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status | 0x4);
-
- /* issue restart again */
- if (!custom_restart_script) {
- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL,
- AICE_JTAG_PIN_CONTROL_RESTART) != ERROR_OK)
- return ERROR_FAIL;
- } else {
- /* custom restart operations */
- if (aice_execute_custom_script(custom_restart_script) != ERROR_OK)
- return ERROR_FAIL;
- }
-
- if (aice_check_dbger(coreid, NDS_DBGER_CRST | NDS_DBGER_DEX) == ERROR_OK) {
- aice_backup_tmp_registers(coreid);
- core_info[coreid].core_state = AICE_TARGET_HALTED;
-
- return ERROR_OK;
- }
-
- /* do software reset-and-hold */
- aice_issue_srst(coreid);
- aice_usb_halt(coreid);
-
- uint32_t value_ir3;
- aice_read_reg(coreid, IR3, &value_ir3);
- aice_write_reg(coreid, PC, value_ir3 & 0xFFFF0000);
- }
-
- return ERROR_FAIL;
-}
-
-static int aice_issue_reset_hold_multi(void)
-{
- uint32_t write_ctrl_value = 0;
-
- /* set SRST */
- write_ctrl_value = AICE_CUSTOM_DELAY_SET_SRST;
- write_ctrl_value |= (0x200 << 16);
- if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY,
- write_ctrl_value) != ERROR_OK)
- return ERROR_FAIL;
-
- for (uint8_t i = 0 ; i < total_num_of_core ; i++)
- aice_write_misc(i, NDS_EDM_MISC_EDM_CMDR, 0);
-
- /* clear SRST */
- write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_SRST;
- write_ctrl_value |= (0x200 << 16);
- if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY,
- write_ctrl_value) != ERROR_OK)
- return ERROR_FAIL;
-
- for (uint8_t i = 0; i < total_num_of_core; i++)
- aice_edm_init(i);
-
- return ERROR_FAIL;
-}
-
-static int aice_usb_assert_srst(uint32_t coreid, enum aice_srst_type_s srst)
-{
- if ((srst != AICE_SRST) && (srst != AICE_RESET_HOLD))
- return ERROR_FAIL;
-
- /* clear DBGER */
- if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER,
- NDS_DBGER_CLEAR_ALL) != ERROR_OK)
- return ERROR_FAIL;
-
- int result = ERROR_OK;
- if (srst == AICE_SRST)
- result = aice_issue_srst(coreid);
- else {
- if (total_num_of_core == 1)
- result = aice_issue_reset_hold(coreid);
- else
- result = aice_issue_reset_hold_multi();
- }
-
- /* Clear DBGER.CRST after reset to avoid 'core-reset checking' errors.
- * assert_srst is user-intentional reset behavior, so we could
- * clear DBGER.CRST safely.
- */
- if (aice_write_misc(coreid,
- NDS_EDM_MISC_DBGER, NDS_DBGER_CRST) != ERROR_OK)
- return ERROR_FAIL;
-
- return result;
-}
-
-static int aice_usb_run(uint32_t coreid)
-{
- LOG_DEBUG("aice_usb_run");
-
- uint32_t dbger_value;
- if (aice_read_misc(coreid,
- NDS_EDM_MISC_DBGER, &dbger_value) != ERROR_OK)
- return ERROR_FAIL;
-
- if ((dbger_value & NDS_DBGER_DEX) != NDS_DBGER_DEX) {
- LOG_WARNING("<-- TARGET WARNING! The debug target exited "
- "the debug mode unexpectedly. -->");
- return ERROR_FAIL;
- }
-
- /* restore r0 & r1 before free run */
- aice_restore_tmp_registers(coreid);
- core_info[coreid].core_state = AICE_TARGET_RUNNING;
-
- /* clear DBGER */
- aice_write_misc(coreid, NDS_EDM_MISC_DBGER,
- NDS_DBGER_CLEAR_ALL);
-
- /** restore EDM registers */
- /** OpenOCD should restore EDM_CTL **before** to exit debug state.
- * Otherwise, following instruction will read wrong EDM_CTL value.
- *
- * pc -> mfsr $p0, EDM_CTL (single step)
- * slli $p0, $p0, 1
- * slri $p0, $p0, 31
- */
- aice_restore_edm_registers(coreid);
-
- /** execute instructions in DIM */
- uint32_t instructions[4] = {
- NOP,
- NOP,
- NOP,
- IRET
- };
- int result = aice_execute_dim(coreid, instructions, 4);
-
- return result;
-}
-
-static int aice_usb_step(uint32_t coreid)
-{
- LOG_DEBUG("aice_usb_step");
-
- uint32_t ir0_value;
- uint32_t ir0_reg_num;
-
- if (is_v2_edm(coreid) == true)
- /* V2 EDM will push interrupt stack as debug exception */
- ir0_reg_num = IR1;
- else
- ir0_reg_num = IR0;
-
- /** enable HSS */
- aice_read_reg(coreid, ir0_reg_num, &ir0_value);
- if ((ir0_value & 0x800) == 0) {
- /** set PSW.HSS */
- ir0_value |= (0x01 << 11);
- aice_write_reg(coreid, ir0_reg_num, ir0_value);
- }
-
- if (aice_usb_run(coreid) == ERROR_FAIL)
- return ERROR_FAIL;
-
- int i = 0;
- enum aice_target_state_s state;
- while (1) {
- /* read DBGER */
- if (aice_usb_state(coreid, &state) != ERROR_OK)
- return ERROR_FAIL;
-
- if (state == AICE_TARGET_HALTED)
- break;
-
- int64_t then = 0;
- if (i == 30)
- then = timeval_ms();
-
- if (i >= 30) {
- if ((timeval_ms() - then) > 1000)
- LOG_WARNING("Timeout (1000ms) waiting for halt to complete");
-
- return ERROR_FAIL;
- }
- i++;
- }
-
- /** disable HSS */
- aice_read_reg(coreid, ir0_reg_num, &ir0_value);
- ir0_value &= ~(0x01 << 11);
- aice_write_reg(coreid, ir0_reg_num, ir0_value);
-
- return ERROR_OK;
-}
-
-static int aice_usb_read_mem_b_bus(uint32_t coreid, uint32_t address, uint32_t *data)
-{
- return aice_read_mem_b(coreid, address, data);
-}
-
-static int aice_usb_read_mem_h_bus(uint32_t coreid, uint32_t address, uint32_t *data)
-{
- return aice_read_mem_h(coreid, address, data);
-}
-
-static int aice_usb_read_mem_w_bus(uint32_t coreid, uint32_t address, uint32_t *data)
-{
- return aice_read_mem(coreid, address, data);
-}
-
-static int aice_usb_read_mem_b_dim(uint32_t coreid, uint32_t address, uint32_t *data)
-{
- uint32_t value;
- uint32_t instructions[4] = {
- LBI_BI(R1, R0),
- MTSR_DTR(R1),
- DSB,
- BEQ_MINUS_12
- };
-
- aice_execute_dim(coreid, instructions, 4);
-
- aice_read_dtr(coreid, &value);
- *data = value & 0xFF;
-
- return ERROR_OK;
-}
-
-static int aice_usb_read_mem_h_dim(uint32_t coreid, uint32_t address, uint32_t *data)
-{
- uint32_t value;
- uint32_t instructions[4] = {
- LHI_BI(R1, R0),
- MTSR_DTR(R1),
- DSB,
- BEQ_MINUS_12
- };
-
- aice_execute_dim(coreid, instructions, 4);
-
- aice_read_dtr(coreid, &value);
- *data = value & 0xFFFF;
-
- return ERROR_OK;
-}
-
-static int aice_usb_read_mem_w_dim(uint32_t coreid, uint32_t address, uint32_t *data)
-{
- uint32_t instructions[4] = {
- LWI_BI(R1, R0),
- MTSR_DTR(R1),
- DSB,
- BEQ_MINUS_12
- };
-
- aice_execute_dim(coreid, instructions, 4);
-
- aice_read_dtr(coreid, data);
-
- return ERROR_OK;
-}
-
-static int aice_usb_set_address_dim(uint32_t coreid, uint32_t address)
-{
- uint32_t instructions[4] = {
- SETHI(R0, address >> 12),
- ORI(R0, R0, address & 0x00000FFF),
- NOP,
- BEQ_MINUS_12
- };
-
- return aice_execute_dim(coreid, instructions, 4);
-}
-
-static int aice_usb_read_memory_unit(uint32_t coreid, uint32_t addr, uint32_t size,
- uint32_t count, uint8_t *buffer)
-{
- LOG_DEBUG("aice_usb_read_memory_unit, addr: 0x%08" PRIx32
- ", size: %" PRIu32 ", count: %" PRIu32 "",
- addr, size, count);
-
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU)
- aice_usb_set_address_dim(coreid, addr);
-
- uint32_t value;
- size_t i;
- read_mem_func_t read_mem_func;
-
- switch (size) {
- case 1:
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS)
- read_mem_func = aice_usb_read_mem_b_bus;
- else
- read_mem_func = aice_usb_read_mem_b_dim;
-
- for (i = 0; i < count; i++) {
- read_mem_func(coreid, addr, &value);
- *buffer++ = (uint8_t)value;
- addr++;
- }
- break;
- case 2:
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS)
- read_mem_func = aice_usb_read_mem_h_bus;
- else
- read_mem_func = aice_usb_read_mem_h_dim;
-
- for (i = 0; i < count; i++) {
- read_mem_func(coreid, addr, &value);
- uint16_t svalue = value;
- memcpy(buffer, &svalue, sizeof(uint16_t));
- buffer += 2;
- addr += 2;
- }
- break;
- case 4:
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS)
- read_mem_func = aice_usb_read_mem_w_bus;
- else
- read_mem_func = aice_usb_read_mem_w_dim;
-
- for (i = 0; i < count; i++) {
- read_mem_func(coreid, addr, &value);
- memcpy(buffer, &value, sizeof(uint32_t));
- buffer += 4;
- addr += 4;
- }
- break;
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_write_mem_b_bus(uint32_t coreid, uint32_t address, uint32_t data)
-{
- return aice_write_mem_b(coreid, address, data);
-}
-
-static int aice_usb_write_mem_h_bus(uint32_t coreid, uint32_t address, uint32_t data)
-{
- return aice_write_mem_h(coreid, address, data);
-}
-
-static int aice_usb_write_mem_w_bus(uint32_t coreid, uint32_t address, uint32_t data)
-{
- return aice_write_mem(coreid, address, data);
-}
-
-static int aice_usb_write_mem_b_dim(uint32_t coreid, uint32_t address, uint32_t data)
-{
- uint32_t instructions[4] = {
- MFSR_DTR(R1),
- SBI_BI(R1, R0),
- DSB,
- BEQ_MINUS_12
- };
-
- aice_write_dtr(coreid, data & 0xFF);
- aice_execute_dim(coreid, instructions, 4);
-
- return ERROR_OK;
-}
-
-static int aice_usb_write_mem_h_dim(uint32_t coreid, uint32_t address, uint32_t data)
-{
- uint32_t instructions[4] = {
- MFSR_DTR(R1),
- SHI_BI(R1, R0),
- DSB,
- BEQ_MINUS_12
- };
-
- aice_write_dtr(coreid, data & 0xFFFF);
- aice_execute_dim(coreid, instructions, 4);
-
- return ERROR_OK;
-}
-
-static int aice_usb_write_mem_w_dim(uint32_t coreid, uint32_t address, uint32_t data)
-{
- uint32_t instructions[4] = {
- MFSR_DTR(R1),
- SWI_BI(R1, R0),
- DSB,
- BEQ_MINUS_12
- };
-
- aice_write_dtr(coreid, data);
- aice_execute_dim(coreid, instructions, 4);
-
- return ERROR_OK;
-}
-
-static int aice_usb_write_memory_unit(uint32_t coreid, uint32_t addr, uint32_t size,
- uint32_t count, const uint8_t *buffer)
-{
- LOG_DEBUG("aice_usb_write_memory_unit, addr: 0x%08" PRIx32
- ", size: %" PRIu32 ", count: %" PRIu32 "",
- addr, size, count);
-
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU)
- aice_usb_set_address_dim(coreid, addr);
-
- size_t i;
- write_mem_func_t write_mem_func;
-
- switch (size) {
- case 1:
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS)
- write_mem_func = aice_usb_write_mem_b_bus;
- else
- write_mem_func = aice_usb_write_mem_b_dim;
-
- for (i = 0; i < count; i++) {
- write_mem_func(coreid, addr, *buffer);
- buffer++;
- addr++;
- }
- break;
- case 2:
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS)
- write_mem_func = aice_usb_write_mem_h_bus;
- else
- write_mem_func = aice_usb_write_mem_h_dim;
-
- for (i = 0; i < count; i++) {
- uint16_t value;
- memcpy(&value, buffer, sizeof(uint16_t));
-
- write_mem_func(coreid, addr, value);
- buffer += 2;
- addr += 2;
- }
- break;
- case 4:
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS)
- write_mem_func = aice_usb_write_mem_w_bus;
- else
- write_mem_func = aice_usb_write_mem_w_dim;
-
- for (i = 0; i < count; i++) {
- uint32_t value;
- memcpy(&value, buffer, sizeof(uint32_t));
-
- write_mem_func(coreid, addr, value);
- buffer += 4;
- addr += 4;
- }
- break;
- }
-
- return ERROR_OK;
-}
-
-static int aice_bulk_read_mem(uint32_t coreid, uint32_t addr, uint32_t count,
- uint8_t *buffer)
-{
- uint32_t packet_size;
-
- while (count > 0) {
- packet_size = (count >= 0x100) ? 0x100 : count;
-
- /** set address */
- addr &= 0xFFFFFFFC;
- if (aice_write_misc(coreid, NDS_EDM_MISC_SBAR, addr) != ERROR_OK)
- return ERROR_FAIL;
-
- if (aice_fastread_mem(coreid, buffer,
- packet_size) != ERROR_OK)
- return ERROR_FAIL;
-
- buffer += (packet_size * 4);
- addr += (packet_size * 4);
- count -= packet_size;
- }
-
- return ERROR_OK;
-}
-
-static int aice_bulk_write_mem(uint32_t coreid, uint32_t addr, uint32_t count,
- const uint8_t *buffer)
-{
- uint32_t packet_size;
-
- while (count > 0) {
- packet_size = (count >= 0x100) ? 0x100 : count;
-
- /** set address */
- addr &= 0xFFFFFFFC;
- if (aice_write_misc(coreid, NDS_EDM_MISC_SBAR, addr | 1) != ERROR_OK)
- return ERROR_FAIL;
-
- if (aice_fastwrite_mem(coreid, buffer,
- packet_size) != ERROR_OK)
- return ERROR_FAIL;
-
- buffer += (packet_size * 4);
- addr += (packet_size * 4);
- count -= packet_size;
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_bulk_read_mem(uint32_t coreid, uint32_t addr,
- uint32_t length, uint8_t *buffer)
-{
- LOG_DEBUG("aice_usb_bulk_read_mem, addr: 0x%08" PRIx32 ", length: 0x%08" PRIx32, addr, length);
-
- int retval;
-
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU)
- aice_usb_set_address_dim(coreid, addr);
-
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU)
- retval = aice_usb_read_memory_unit(coreid, addr, 4, length / 4, buffer);
- else
- retval = aice_bulk_read_mem(coreid, addr, length / 4, buffer);
-
- return retval;
-}
-
-static int aice_usb_bulk_write_mem(uint32_t coreid, uint32_t addr,
- uint32_t length, const uint8_t *buffer)
-{
- LOG_DEBUG("aice_usb_bulk_write_mem, addr: 0x%08" PRIx32 ", length: 0x%08" PRIx32, addr, length);
-
- int retval;
-
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU)
- aice_usb_set_address_dim(coreid, addr);
-
- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU)
- retval = aice_usb_write_memory_unit(coreid, addr, 4, length / 4, buffer);
- else
- retval = aice_bulk_write_mem(coreid, addr, length / 4, buffer);
-
- return retval;
-}
-
-static int aice_usb_read_debug_reg(uint32_t coreid, uint32_t addr, uint32_t *val)
-{
- if (core_info[coreid].core_state == AICE_TARGET_HALTED) {
- if (addr == NDS_EDM_SR_EDMSW) {
- *val = core_info[coreid].edmsw_backup;
- } else if (addr == NDS_EDM_SR_EDM_DTR) {
- if (core_info[coreid].target_dtr_valid) {
- /* if EDM_DTR has read out, clear it. */
- *val = core_info[coreid].target_dtr_backup;
- core_info[coreid].edmsw_backup &= (~0x1);
- core_info[coreid].target_dtr_valid = false;
- } else {
- *val = 0;
- }
- }
- }
-
- return aice_read_edmsr(coreid, addr, val);
-}
-
-static int aice_usb_write_debug_reg(uint32_t coreid, uint32_t addr, const uint32_t val)
-{
- if (core_info[coreid].core_state == AICE_TARGET_HALTED) {
- if (addr == NDS_EDM_SR_EDM_DTR) {
- core_info[coreid].host_dtr_backup = val;
- core_info[coreid].edmsw_backup |= 0x2;
- core_info[coreid].host_dtr_valid = true;
- }
- }
-
- return aice_write_edmsr(coreid, addr, val);
-}
-
-static int aice_usb_memory_access(uint32_t coreid, enum nds_memory_access channel)
-{
- LOG_DEBUG("aice_usb_memory_access, access channel: %u", channel);
-
- core_info[coreid].access_channel = channel;
-
- return ERROR_OK;
-}
-
-static int aice_usb_memory_mode(uint32_t coreid, enum nds_memory_select mem_select)
-{
- if (core_info[coreid].memory_select == mem_select)
- return ERROR_OK;
-
- LOG_DEBUG("aice_usb_memory_mode, memory select: %u", mem_select);
-
- core_info[coreid].memory_select = mem_select;
-
- if (core_info[coreid].memory_select != NDS_MEMORY_SELECT_AUTO)
- aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL,
- core_info[coreid].memory_select - 1);
- else
- aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL,
- NDS_MEMORY_SELECT_MEM - 1);
-
- return ERROR_OK;
-}
-
-static int aice_usb_read_tlb(uint32_t coreid, target_addr_t virtual_address,
- target_addr_t *physical_address)
-{
- LOG_DEBUG("aice_usb_read_tlb, virtual address: 0x%08" TARGET_PRIxADDR, virtual_address);
-
- uint32_t instructions[4];
- uint32_t probe_result;
- uint32_t value_mr3;
- uint32_t value_mr4;
- uint32_t access_page_size;
- uint32_t virtual_offset;
- uint32_t physical_page_number;
-
- aice_write_dtr(coreid, virtual_address);
-
- /* probe TLB first */
- instructions[0] = MFSR_DTR(R0);
- instructions[1] = TLBOP_TARGET_PROBE(R1, R0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- aice_execute_dim(coreid, instructions, 4);
-
- aice_read_reg(coreid, R1, &probe_result);
-
- if (probe_result & 0x80000000)
- return ERROR_FAIL;
-
- /* read TLB entry */
- aice_write_dtr(coreid, probe_result & 0x7FF);
-
- /* probe TLB first */
- instructions[0] = MFSR_DTR(R0);
- instructions[1] = TLBOP_TARGET_READ(R0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
- aice_execute_dim(coreid, instructions, 4);
-
- /* TODO: it should backup mr3, mr4 */
- aice_read_reg(coreid, MR3, &value_mr3);
- aice_read_reg(coreid, MR4, &value_mr4);
-
- access_page_size = value_mr4 & 0xF;
- if (access_page_size == 0) { /* 4K page */
- virtual_offset = virtual_address & 0x00000FFF;
- physical_page_number = value_mr3 & 0xFFFFF000;
- } else if (access_page_size == 1) { /* 8K page */
- virtual_offset = virtual_address & 0x00001FFF;
- physical_page_number = value_mr3 & 0xFFFFE000;
- } else if (access_page_size == 5) { /* 1M page */
- virtual_offset = virtual_address & 0x000FFFFF;
- physical_page_number = value_mr3 & 0xFFF00000;
- } else {
- return ERROR_FAIL;
- }
-
- *physical_address = physical_page_number | virtual_offset;
-
- return ERROR_OK;
-}
-
-static int aice_usb_init_cache(uint32_t coreid)
-{
- LOG_DEBUG("aice_usb_init_cache");
-
- uint32_t value_cr1;
- uint32_t value_cr2;
-
- aice_read_reg(coreid, CR1, &value_cr1);
- aice_read_reg(coreid, CR2, &value_cr2);
-
- struct cache_info *icache = &core_info[coreid].icache;
-
- icache->set = value_cr1 & 0x7;
- icache->log2_set = icache->set + 6;
- icache->set = 64 << icache->set;
- icache->way = ((value_cr1 >> 3) & 0x7) + 1;
- icache->line_size = (value_cr1 >> 6) & 0x7;
- if (icache->line_size != 0) {
- icache->log2_line_size = icache->line_size + 2;
- icache->line_size = 8 << (icache->line_size - 1);
- } else {
- icache->log2_line_size = 0;
- }
-
- LOG_DEBUG("\ticache set: %" PRIu32 ", way: %" PRIu32 ", line size: %" PRIu32 ", "
- "log2(set): %" PRIu32 ", log2(line_size): %" PRIu32 "",
- icache->set, icache->way, icache->line_size,
- icache->log2_set, icache->log2_line_size);
-
- struct cache_info *dcache = &core_info[coreid].dcache;
-
- dcache->set = value_cr2 & 0x7;
- dcache->log2_set = dcache->set + 6;
- dcache->set = 64 << dcache->set;
- dcache->way = ((value_cr2 >> 3) & 0x7) + 1;
- dcache->line_size = (value_cr2 >> 6) & 0x7;
- if (dcache->line_size != 0) {
- dcache->log2_line_size = dcache->line_size + 2;
- dcache->line_size = 8 << (dcache->line_size - 1);
- } else {
- dcache->log2_line_size = 0;
- }
-
- LOG_DEBUG("\tdcache set: %" PRIu32 ", way: %" PRIu32 ", line size: %" PRIu32 ", "
- "log2(set): %" PRIu32 ", log2(line_size): %" PRIu32 "",
- dcache->set, dcache->way, dcache->line_size,
- dcache->log2_set, dcache->log2_line_size);
-
- core_info[coreid].cache_init = true;
-
- return ERROR_OK;
-}
-
-static int aice_usb_dcache_inval_all(uint32_t coreid)
-{
- LOG_DEBUG("aice_usb_dcache_inval_all");
-
- uint32_t set_index;
- uint32_t way_index;
- uint32_t cache_index;
- uint32_t instructions[4];
-
- instructions[0] = MFSR_DTR(R0);
- instructions[1] = L1D_IX_INVAL(R0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
-
- struct cache_info *dcache = &core_info[coreid].dcache;
-
- for (set_index = 0; set_index < dcache->set; set_index++) {
- for (way_index = 0; way_index < dcache->way; way_index++) {
- cache_index = (way_index << (dcache->log2_set + dcache->log2_line_size)) |
- (set_index << dcache->log2_line_size);
-
- if (aice_write_dtr(coreid, cache_index) != ERROR_OK)
- return ERROR_FAIL;
-
- if (aice_execute_dim(coreid, instructions, 4) != ERROR_OK)
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_dcache_va_inval(uint32_t coreid, uint32_t address)
-{
- LOG_DEBUG("aice_usb_dcache_va_inval");
-
- uint32_t instructions[4];
-
- aice_write_dtr(coreid, address);
-
- instructions[0] = MFSR_DTR(R0);
- instructions[1] = L1D_VA_INVAL(R0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
-
- return aice_execute_dim(coreid, instructions, 4);
-}
-
-static int aice_usb_dcache_wb_all(uint32_t coreid)
-{
- LOG_DEBUG("aice_usb_dcache_wb_all");
-
- uint32_t set_index;
- uint32_t way_index;
- uint32_t cache_index;
- uint32_t instructions[4];
-
- instructions[0] = MFSR_DTR(R0);
- instructions[1] = L1D_IX_WB(R0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
-
- struct cache_info *dcache = &core_info[coreid].dcache;
-
- for (set_index = 0; set_index < dcache->set; set_index++) {
- for (way_index = 0; way_index < dcache->way; way_index++) {
- cache_index = (way_index << (dcache->log2_set + dcache->log2_line_size)) |
- (set_index << dcache->log2_line_size);
-
- if (aice_write_dtr(coreid, cache_index) != ERROR_OK)
- return ERROR_FAIL;
-
- if (aice_execute_dim(coreid, instructions, 4) != ERROR_OK)
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_dcache_va_wb(uint32_t coreid, uint32_t address)
-{
- LOG_DEBUG("aice_usb_dcache_va_wb");
-
- uint32_t instructions[4];
-
- aice_write_dtr(coreid, address);
-
- instructions[0] = MFSR_DTR(R0);
- instructions[1] = L1D_VA_WB(R0);
- instructions[2] = DSB;
- instructions[3] = BEQ_MINUS_12;
-
- return aice_execute_dim(coreid, instructions, 4);
-}
-
-static int aice_usb_icache_inval_all(uint32_t coreid)
-{
- LOG_DEBUG("aice_usb_icache_inval_all");
-
- uint32_t set_index;
- uint32_t way_index;
- uint32_t cache_index;
- uint32_t instructions[4];
-
- instructions[0] = MFSR_DTR(R0);
- instructions[1] = L1I_IX_INVAL(R0);
- instructions[2] = ISB;
- instructions[3] = BEQ_MINUS_12;
-
- struct cache_info *icache = &core_info[coreid].icache;
-
- for (set_index = 0; set_index < icache->set; set_index++) {
- for (way_index = 0; way_index < icache->way; way_index++) {
- cache_index = (way_index << (icache->log2_set + icache->log2_line_size)) |
- (set_index << icache->log2_line_size);
-
- if (aice_write_dtr(coreid, cache_index) != ERROR_OK)
- return ERROR_FAIL;
-
- if (aice_execute_dim(coreid, instructions, 4) != ERROR_OK)
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_icache_va_inval(uint32_t coreid, uint32_t address)
-{
- LOG_DEBUG("aice_usb_icache_va_inval");
-
- uint32_t instructions[4];
-
- aice_write_dtr(coreid, address);
-
- instructions[0] = MFSR_DTR(R0);
- instructions[1] = L1I_VA_INVAL(R0);
- instructions[2] = ISB;
- instructions[3] = BEQ_MINUS_12;
-
- return aice_execute_dim(coreid, instructions, 4);
-}
-
-static int aice_usb_cache_ctl(uint32_t coreid, uint32_t subtype, uint32_t address)
-{
- LOG_DEBUG("aice_usb_cache_ctl");
-
- int result;
-
- if (core_info[coreid].cache_init == false)
- aice_usb_init_cache(coreid);
-
- switch (subtype) {
- case AICE_CACHE_CTL_L1D_INVALALL:
- result = aice_usb_dcache_inval_all(coreid);
- break;
- case AICE_CACHE_CTL_L1D_VA_INVAL:
- result = aice_usb_dcache_va_inval(coreid, address);
- break;
- case AICE_CACHE_CTL_L1D_WBALL:
- result = aice_usb_dcache_wb_all(coreid);
- break;
- case AICE_CACHE_CTL_L1D_VA_WB:
- result = aice_usb_dcache_va_wb(coreid, address);
- break;
- case AICE_CACHE_CTL_L1I_INVALALL:
- result = aice_usb_icache_inval_all(coreid);
- break;
- case AICE_CACHE_CTL_L1I_VA_INVAL:
- result = aice_usb_icache_va_inval(coreid, address);
- break;
- default:
- result = ERROR_FAIL;
- break;
- }
-
- return result;
-}
-
-static int aice_usb_set_retry_times(uint32_t a_retry_times)
-{
- aice_max_retry_times = a_retry_times;
- return ERROR_OK;
-}
-
-static int aice_usb_program_edm(uint32_t coreid, char *command_sequence)
-{
- char *command_str;
- char *reg_name_0;
- char *reg_name_1;
- uint32_t data_value;
- int i;
-
- /* init strtok() */
- command_str = strtok(command_sequence, ";");
- if (!command_str)
- return ERROR_OK;
-
- do {
- i = 0;
- /* process one command */
- while (command_str[i] == ' ' ||
- command_str[i] == '\n' ||
- command_str[i] == '\r' ||
- command_str[i] == '\t')
- i++;
-
- /* skip ' ', '\r', '\n', '\t' */
- command_str = command_str + i;
-
- if (strncmp(command_str, "write_misc", 10) == 0) {
- reg_name_0 = strstr(command_str, "gen_port0");
- reg_name_1 = strstr(command_str, "gen_port1");
-
- if (reg_name_0) {
- data_value = strtoul(reg_name_0 + 9, NULL, 0);
-
- if (aice_write_misc(coreid,
- NDS_EDM_MISC_GEN_PORT0, data_value) != ERROR_OK)
- return ERROR_FAIL;
-
- } else if (reg_name_1) {
- data_value = strtoul(reg_name_1 + 9, NULL, 0);
-
- if (aice_write_misc(coreid,
- NDS_EDM_MISC_GEN_PORT1, data_value) != ERROR_OK)
- return ERROR_FAIL;
- } else {
- LOG_ERROR("program EDM, unsupported misc register: %s", command_str);
- }
- } else {
- LOG_ERROR("program EDM, unsupported command: %s", command_str);
- }
-
- /* update command_str */
- command_str = strtok(NULL, ";");
-
- } while (command_str);
-
- return ERROR_OK;
-}
-
-static int aice_usb_set_command_mode(enum aice_command_mode command_mode)
-{
- int retval = ERROR_OK;
-
- /* flush usb_packets_buffer as users change mode */
- retval = aice_usb_packet_flush();
-
- if (command_mode == AICE_COMMAND_MODE_BATCH) {
- /* reset batch buffer */
- aice_command_mode = AICE_COMMAND_MODE_NORMAL;
- retval = aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CMD_BUF0_CTRL, 0x40000);
- }
-
- aice_command_mode = command_mode;
-
- return retval;
-}
-
-static int aice_usb_execute(uint32_t coreid, uint32_t *instructions,
- uint32_t instruction_num)
-{
- uint32_t i, j;
- uint8_t current_instruction_num;
- uint32_t dim_instructions[4] = {NOP, NOP, NOP, BEQ_MINUS_12};
-
- /* To execute 4 instructions as a special case */
- if (instruction_num == 4)
- return aice_execute_dim(coreid, instructions, 4);
-
- for (i = 0 ; i < instruction_num ; i += 3) {
- if (instruction_num - i < 3) {
- current_instruction_num = instruction_num - i;
- for (j = current_instruction_num ; j < 3 ; j++)
- dim_instructions[j] = NOP;
- } else {
- current_instruction_num = 3;
- }
-
- memcpy(dim_instructions, instructions + i,
- current_instruction_num * sizeof(uint32_t));
-
- /** fill DIM */
- if (aice_write_dim(coreid,
- dim_instructions,
- 4) != ERROR_OK)
- return ERROR_FAIL;
-
- /** clear DBGER.DPED */
- if (aice_write_misc(coreid,
- NDS_EDM_MISC_DBGER, NDS_DBGER_DPED) != ERROR_OK)
- return ERROR_FAIL;
-
- /** execute DIM */
- if (aice_do_execute(coreid) != ERROR_OK)
- return ERROR_FAIL;
-
- /** check DBGER.DPED */
- if (aice_check_dbger(coreid, NDS_DBGER_DPED) != ERROR_OK) {
-
- LOG_ERROR("<-- TARGET ERROR! Debug operations do not finish properly:"
- "0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 ". -->",
- dim_instructions[0],
- dim_instructions[1],
- dim_instructions[2],
- dim_instructions[3]);
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
-}
-
-static int aice_usb_set_custom_srst_script(const char *script)
-{
- custom_srst_script = strdup(script);
-
- return ERROR_OK;
-}
-
-static int aice_usb_set_custom_trst_script(const char *script)
-{
- custom_trst_script = strdup(script);
-
- return ERROR_OK;
-}
-
-static int aice_usb_set_custom_restart_script(const char *script)
-{
- custom_restart_script = strdup(script);
-
- return ERROR_OK;
-}
-
-static int aice_usb_set_count_to_check_dbger(uint32_t count_to_check)
-{
- aice_count_to_check_dbger = count_to_check;
-
- return ERROR_OK;
-}
-
-static int aice_usb_set_data_endian(uint32_t coreid,
- enum aice_target_endian target_data_endian)
-{
- data_endian = target_data_endian;
-
- return ERROR_OK;
-}
-
-static int fill_profiling_batch_commands(uint32_t coreid, uint32_t reg_no)
-{
- uint32_t dim_instructions[4];
-
- aice_usb_set_command_mode(AICE_COMMAND_MODE_BATCH);
-
- /* halt */
- if (aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0) != ERROR_OK)
- return ERROR_FAIL;
-
- /* backup $r0 */
- dim_instructions[0] = MTSR_DTR(0);
- dim_instructions[1] = DSB;
- dim_instructions[2] = NOP;
- dim_instructions[3] = BEQ_MINUS_12;
- if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK)
- return ERROR_FAIL;
- aice_read_dtr_to_buffer(coreid, AICE_BATCH_DATA_BUFFER_0);
-
- /* get samples */
- if (nds32_reg_type(reg_no) == NDS32_REG_TYPE_GPR) {
- /* general registers */
- dim_instructions[0] = MTSR_DTR(reg_no);
- dim_instructions[1] = DSB;
- dim_instructions[2] = NOP;
- dim_instructions[3] = BEQ_MINUS_12;
- } else if (nds32_reg_type(reg_no) == NDS32_REG_TYPE_SPR) {
- /* user special registers */
- dim_instructions[0] = MFUSR_G0(0, nds32_reg_sr_index(reg_no));
- dim_instructions[1] = MTSR_DTR(0);
- dim_instructions[2] = DSB;
- dim_instructions[3] = BEQ_MINUS_12;
- } else { /* system registers */
- dim_instructions[0] = MFSR(0, nds32_reg_sr_index(reg_no));
- dim_instructions[1] = MTSR_DTR(0);
- dim_instructions[2] = DSB;
- dim_instructions[3] = BEQ_MINUS_12;
- }
- if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK)
- return ERROR_FAIL;
- aice_read_dtr_to_buffer(coreid, AICE_BATCH_DATA_BUFFER_1);
-
- /* restore $r0 */
- aice_write_dtr_from_buffer(coreid, AICE_BATCH_DATA_BUFFER_0);
- dim_instructions[0] = MFSR_DTR(0);
- dim_instructions[1] = DSB;
- dim_instructions[2] = NOP;
- dim_instructions[3] = IRET; /* free run */
- if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK)
- return ERROR_FAIL;
-
- aice_command_mode = AICE_COMMAND_MODE_NORMAL;
-
- /* use BATCH_BUFFER_WRITE to fill command-batch-buffer */
- if (aice_batch_buffer_write(AICE_BATCH_COMMAND_BUFFER_0,
- usb_out_packets_buffer,
- (usb_out_packets_buffer_length + 3) / 4) != ERROR_OK)
- return ERROR_FAIL;
-
- usb_out_packets_buffer_length = 0;
- usb_in_packets_buffer_length = 0;
-
- return ERROR_OK;
-}
-
-static int aice_usb_profiling(uint32_t coreid, uint32_t interval, uint32_t iteration,
- uint32_t reg_no, uint32_t *samples, uint32_t *num_samples)
-{
- uint32_t iteration_count;
- uint32_t this_iteration;
- int retval = ERROR_OK;
- const uint32_t MAX_ITERATION = 250;
-
- *num_samples = 0;
-
- /* init DIM size */
- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DIM_SIZE, 4) != ERROR_OK)
- return ERROR_FAIL;
-
- /* Use AICE_BATCH_DATA_BUFFER_0 to read/write $DTR.
- * Set it to circular buffer */
- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DATA_BUF0_CTRL, 0xC0000) != ERROR_OK)
- return ERROR_FAIL;
-
- fill_profiling_batch_commands(coreid, reg_no);
-
- iteration_count = 0;
- while (iteration_count < iteration) {
- if (iteration - iteration_count < MAX_ITERATION)
- this_iteration = iteration - iteration_count;
- else
- this_iteration = MAX_ITERATION;
-
- /* set number of iterations */
- uint32_t val_iteration;
- val_iteration = interval << 16 | this_iteration;
- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_ITERATION,
- val_iteration) != ERROR_OK) {
- retval = ERROR_FAIL;
- goto end_profiling;
- }
-
- /* init AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL to store $PC */
- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL,
- 0x40000) != ERROR_OK) {
- retval = ERROR_FAIL;
- goto end_profiling;
- }
-
- aice_usb_run(coreid);
-
- /* enable BATCH command */
- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CTRL,
- 0x80000000) != ERROR_OK) {
- aice_usb_halt(coreid);
- retval = ERROR_FAIL;
- goto end_profiling;
- }
-
- /* wait a while (AICE bug, workaround) */
- alive_sleep(this_iteration);
-
- /* check status */
- uint32_t i;
- uint32_t batch_status = 0;
-
- i = 0;
- while (1) {
- aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status);
-
- if (batch_status & 0x1) {
- break;
- } else if (batch_status & 0xE) {
- aice_usb_halt(coreid);
- retval = ERROR_FAIL;
- goto end_profiling;
- }
-
- if ((i % 30) == 0)
- keep_alive();
-
- i++;
- }
-
- aice_usb_halt(coreid);
-
- /* get samples from batch data buffer */
- if (aice_batch_buffer_read(AICE_BATCH_DATA_BUFFER_1,
- samples + iteration_count, this_iteration) != ERROR_OK) {
- retval = ERROR_FAIL;
- goto end_profiling;
- }
-
- iteration_count += this_iteration;
- }
-
-end_profiling:
- *num_samples = iteration_count;
-
- return retval;
-}
-
-/** */
-struct aice_port_api_s aice_usb_api = {
- /** */
- .open = aice_open_device,
- /** */
- .close = aice_usb_close,
- /** */
- .idcode = aice_usb_idcode,
- /** */
- .state = aice_usb_state,
- /** */
- .reset = aice_usb_reset,
- /** */
- .assert_srst = aice_usb_assert_srst,
- /** */
- .run = aice_usb_run,
- /** */
- .halt = aice_usb_halt,
- /** */
- .step = aice_usb_step,
- /** */
- .read_reg = aice_usb_read_reg,
- /** */
- .write_reg = aice_usb_write_reg,
- /** */
- .read_reg_64 = aice_usb_read_reg_64,
- /** */
- .write_reg_64 = aice_usb_write_reg_64,
- /** */
- .read_mem_unit = aice_usb_read_memory_unit,
- /** */
- .write_mem_unit = aice_usb_write_memory_unit,
- /** */
- .read_mem_bulk = aice_usb_bulk_read_mem,
- /** */
- .write_mem_bulk = aice_usb_bulk_write_mem,
- /** */
- .read_debug_reg = aice_usb_read_debug_reg,
- /** */
- .write_debug_reg = aice_usb_write_debug_reg,
- /** */
- .set_jtag_clock = aice_usb_set_jtag_clock,
- /** */
- .memory_access = aice_usb_memory_access,
- /** */
- .memory_mode = aice_usb_memory_mode,
- /** */
- .read_tlb = aice_usb_read_tlb,
- /** */
- .cache_ctl = aice_usb_cache_ctl,
- /** */
- .set_retry_times = aice_usb_set_retry_times,
- /** */
- .program_edm = aice_usb_program_edm,
- /** */
- .set_command_mode = aice_usb_set_command_mode,
- /** */
- .execute = aice_usb_execute,
- /** */
- .set_custom_srst_script = aice_usb_set_custom_srst_script,
- /** */
- .set_custom_trst_script = aice_usb_set_custom_trst_script,
- /** */
- .set_custom_restart_script = aice_usb_set_custom_restart_script,
- /** */
- .set_count_to_check_dbger = aice_usb_set_count_to_check_dbger,
- /** */
- .set_data_endian = aice_usb_set_data_endian,
- /** */
- .profiling = aice_usb_profiling,
-};
diff --git a/src/jtag/aice/aice_usb.h b/src/jtag/aice/aice_usb.h
deleted file mode 100644
index d85d25f..0000000
--- a/src/jtag/aice/aice_usb.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 by Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_JTAG_AICE_AICE_USB_H
-#define OPENOCD_JTAG_AICE_AICE_USB_H
-
-#include "aice_port.h"
-
-/* AICE USB timeout value */
-#define AICE_USB_TIMEOUT 5000
-
-/* AICE USB buffer size */
-#define AICE_IN_BUFFER_SIZE 2048
-#define AICE_OUT_BUFFER_SIZE 2048
-#define AICE_IN_PACKETS_BUFFER_SIZE 2048
-#define AICE_OUT_PACKETS_BUFFER_SIZE 2048
-#define AICE_IN_BATCH_COMMAND_SIZE 512
-#define AICE_OUT_BATCH_COMMAND_SIZE 512
-#define AICE_IN_PACK_COMMAND_SIZE 2048
-#define AICE_OUT_PACK_COMMAND_SIZE 2048
-
-/* Constants for AICE command READ_CTRL */
-#define AICE_READ_CTRL_GET_ICE_STATE 0x00
-#define AICE_READ_CTRL_GET_HARDWARE_VERSION 0x01
-#define AICE_READ_CTRL_GET_FPGA_VERSION 0x02
-#define AICE_READ_CTRL_GET_FIRMWARE_VERSION 0x03
-#define AICE_READ_CTRL_GET_JTAG_PIN_STATUS 0x04
-#define AICE_READ_CTRL_BATCH_BUF_INFO 0x22
-#define AICE_READ_CTRL_BATCH_STATUS 0x23
-#define AICE_READ_CTRL_BATCH_BUF0_STATE 0x31
-#define AICE_READ_CTRL_BATCH_BUF4_STATE 0x39
-#define AICE_READ_CTRL_BATCH_BUF5_STATE 0x3b
-
-/* Constants for AICE command WRITE_CTRL */
-#define AICE_WRITE_CTRL_TCK_CONTROL 0x00
-#define AICE_WRITE_CTRL_JTAG_PIN_CONTROL 0x01
-#define AICE_WRITE_CTRL_CLEAR_TIMEOUT_STATUS 0x02
-#define AICE_WRITE_CTRL_RESERVED 0x03
-#define AICE_WRITE_CTRL_JTAG_PIN_STATUS 0x04
-#define AICE_WRITE_CTRL_CUSTOM_DELAY 0x0d
-#define AICE_WRITE_CTRL_BATCH_CTRL 0x20
-#define AICE_WRITE_CTRL_BATCH_ITERATION 0x21
-#define AICE_WRITE_CTRL_BATCH_DIM_SIZE 0x22
-#define AICE_WRITE_CTRL_BATCH_CMD_BUF0_CTRL 0x30
-#define AICE_WRITE_CTRL_BATCH_DATA_BUF0_CTRL 0x38
-#define AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL 0x3a
-
-#define AICE_BATCH_COMMAND_BUFFER_0 0x0
-#define AICE_BATCH_COMMAND_BUFFER_1 0x1
-#define AICE_BATCH_COMMAND_BUFFER_2 0x2
-#define AICE_BATCH_COMMAND_BUFFER_3 0x3
-#define AICE_BATCH_DATA_BUFFER_0 0x4
-#define AICE_BATCH_DATA_BUFFER_1 0x5
-#define AICE_BATCH_DATA_BUFFER_2 0x6
-#define AICE_BATCH_DATA_BUFFER_3 0x7
-
-/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */
-#define AICE_TCK_CONTROL_TCK3048 0x08
-#define AICE_TCK_CONTROL_TCK_SCAN 0x10
-
-/* Constants for AICE command WRITE_CTRL:JTAG_PIN_CONTROL */
-#define AICE_JTAG_PIN_CONTROL_SRST 0x01
-#define AICE_JTAG_PIN_CONTROL_TRST 0x02
-#define AICE_JTAG_PIN_CONTROL_STOP 0x04
-#define AICE_JTAG_PIN_CONTROL_RESTART 0x08
-
-/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */
-#define AICE_TCK_CONTROL_TCK_SCAN 0x10
-
-/* Custom SRST/DBGI/TRST */
-#define AICE_CUSTOM_DELAY_SET_SRST 0x01
-#define AICE_CUSTOM_DELAY_CLEAN_SRST 0x02
-#define AICE_CUSTOM_DELAY_SET_DBGI 0x04
-#define AICE_CUSTOM_DELAY_CLEAN_DBGI 0x08
-#define AICE_CUSTOM_DELAY_SET_TRST 0x10
-#define AICE_CUSTOM_DELAY_CLEAN_TRST 0x20
-
-struct aice_usb_handler_s {
- unsigned int usb_read_ep;
- unsigned int usb_write_ep;
- struct libusb_device_handle *usb_handle;
-};
-
-struct cache_info {
- uint32_t set;
- uint32_t way;
- uint32_t line_size;
-
- uint32_t log2_set;
- uint32_t log2_line_size;
-};
-
-struct aice_nds32_info {
- uint32_t edm_version;
- uint32_t r0_backup;
- uint32_t r1_backup;
- uint32_t host_dtr_backup;
- uint32_t target_dtr_backup;
- uint32_t edmsw_backup;
- uint32_t edm_ctl_backup;
- bool debug_under_dex_on;
- bool dex_use_psw_on;
- bool host_dtr_valid;
- bool target_dtr_valid;
- enum nds_memory_access access_channel;
- enum nds_memory_select memory_select;
- enum aice_target_state_s core_state;
- bool cache_init;
- struct cache_info icache;
- struct cache_info dcache;
-};
-
-extern struct aice_port_api_s aice_usb_api;
-
-int aice_read_ctrl(uint32_t address, uint32_t *data);
-int aice_write_ctrl(uint32_t address, uint32_t data);
-
-#endif /* OPENOCD_JTAG_AICE_AICE_USB_H */
diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c
index a3e9e17..7db3c7b 100644
--- a/src/jtag/drivers/arm-jtag-ew.c
+++ b/src/jtag/drivers/arm-jtag-ew.c
@@ -776,17 +776,12 @@ static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length)
static void armjtagew_debug_buffer(uint8_t *buffer, int length)
{
- char line[81];
- char s[4];
- int i;
- int j;
+ char line[8 + 3 * BYTES_PER_LINE + 1];
- for (i = 0; i < length; i += BYTES_PER_LINE) {
- snprintf(line, 5, "%04x", i);
- for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
- snprintf(s, 4, " %02x", buffer[j]);
- strcat(line, s);
- }
+ 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);
/* Prevent GDB timeout (writing to log might take some time) */
diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c
index bd44fca..5aa1a99 100644
--- a/src/jtag/drivers/bcm2835gpio.c
+++ b/src/jtag/drivers/bcm2835gpio.c
@@ -57,6 +57,15 @@ static struct initial_gpio_state {
} initial_gpio_state[ADAPTER_GPIO_IDX_NUM];
static uint32_t initial_drive_strength_etc;
+static inline void bcm2835_gpio_synchronize(void)
+{
+ /* Ensure that previous writes to GPIO registers are flushed out of
+ * the inner shareable domain to prevent pipelined writes to the
+ * same address being merged.
+ */
+ __sync_synchronize();
+}
+
static bool is_gpio_config_valid(enum adapter_gpio_config_index idx)
{
/* Only chip 0 is supported, accept unset value (-1) too */
@@ -96,6 +105,7 @@ static void set_gpio_value(const struct adapter_gpio_config *gpio_config, int va
}
break;
}
+ bcm2835_gpio_synchronize();
}
static void restore_gpio(enum adapter_gpio_config_index idx)
@@ -109,6 +119,7 @@ static void restore_gpio(enum adapter_gpio_config_index idx)
GPIO_CLR = 1 << adapter_gpio_config[idx].gpio_num;
}
}
+ bcm2835_gpio_synchronize();
}
static void initialize_gpio(enum adapter_gpio_config_index idx)
@@ -143,6 +154,7 @@ static void initialize_gpio(enum adapter_gpio_config_index idx)
/* Direction for non push-pull is already set by set_gpio_value() */
if (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL)
OUT_GPIO(adapter_gpio_config[idx].gpio_num);
+ bcm2835_gpio_synchronize();
}
static bb_value_t bcm2835gpio_read(void)
@@ -164,6 +176,7 @@ static int bcm2835gpio_write(int tck, int tms, int tdi)
GPIO_SET = set;
GPIO_CLR = clear;
+ bcm2835_gpio_synchronize();
for (unsigned int i = 0; i < jtag_delay; i++)
asm volatile ("");
@@ -184,6 +197,7 @@ static int bcm2835gpio_swd_write_fast(int swclk, int swdio)
GPIO_SET = set;
GPIO_CLR = clear;
+ bcm2835_gpio_synchronize();
for (unsigned int i = 0; i < jtag_delay; i++)
asm volatile ("");
@@ -234,6 +248,7 @@ static void bcm2835_swdio_drive(bool is_output)
if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR))
set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);
}
+ bcm2835_gpio_synchronize();
}
static int bcm2835_swdio_read(void)
diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c
index d49e16f..2ab0a2a 100644
--- a/src/jtag/drivers/bitbang.c
+++ b/src/jtag/drivers/bitbang.c
@@ -380,8 +380,6 @@ static int bitbang_swd_init(void)
static void bitbang_swd_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsigned int bit_cnt)
{
- LOG_DEBUG("bitbang_swd_exchange");
-
if (bitbang_interface->blink) {
/* FIXME: we should manage errors */
bitbang_interface->blink(1);
@@ -412,11 +410,9 @@ static void bitbang_swd_exchange(bool rnw, uint8_t buf[], unsigned int offset, u
static int bitbang_swd_switch_seq(enum swd_special_seq seq)
{
- LOG_DEBUG("bitbang_swd_switch_seq");
-
switch (seq) {
case LINE_RESET:
- LOG_DEBUG("SWD line reset");
+ LOG_DEBUG_IO("SWD line reset");
bitbang_swd_exchange(false, (uint8_t *)swd_seq_line_reset, 0, swd_seq_line_reset_len);
break;
case JTAG_TO_SWD:
@@ -459,7 +455,6 @@ static void swd_clear_sticky_errors(void)
static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
{
- LOG_DEBUG("bitbang_swd_read_reg");
assert(cmd & SWD_CMD_RNW);
if (queued_retval != ERROR_OK) {
@@ -481,7 +476,7 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay
uint32_t data = buf_get_u32(trn_ack_data_parity_trn, 1 + 3, 32);
int parity = buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 32, 1);
- LOG_DEBUG("%s %s read reg %X = %08"PRIx32,
+ LOG_DEBUG_IO("%s %s read reg %X = %08" PRIx32,
ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
cmd & SWD_CMD_APNDP ? "AP" : "DP",
(cmd & SWD_CMD_A32) >> 1,
@@ -510,7 +505,6 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay
static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
{
- LOG_DEBUG("bitbang_swd_write_reg");
assert(!(cmd & SWD_CMD_RNW));
if (queued_retval != ERROR_OK) {
@@ -537,7 +531,7 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay
int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);
- LOG_DEBUG("%s%s %s write reg %X = %08"PRIx32,
+ LOG_DEBUG_IO("%s%s %s write reg %X = %08" PRIx32,
check_ack ? "" : "ack ignored ",
ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
cmd & SWD_CMD_APNDP ? "AP" : "DP",
@@ -562,14 +556,13 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay
static int bitbang_swd_run_queue(void)
{
- LOG_DEBUG("bitbang_swd_run_queue");
/* A transaction must be followed by another transaction or at least 8 idle cycles to
* ensure that data is clocked through the AP. */
bitbang_swd_exchange(true, NULL, 0, 8);
int retval = queued_retval;
queued_retval = ERROR_OK;
- LOG_DEBUG("SWD queue return value: %02x", retval);
+ LOG_DEBUG_IO("SWD queue return value: %02x", retval);
return retval;
}
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index e708d52..44a7dd8 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -573,6 +573,8 @@ static int cmsis_dap_metacmd_targetsel(uint32_t instance_id)
The purpose of this operation is to select the target
corresponding to the instance_id that is written */
+ LOG_DEBUG_IO("DP write reg TARGETSEL %" PRIx32, instance_id);
+
size_t idx = 0;
command[idx++] = CMD_DAP_SWD_SEQUENCE;
command[idx++] = 3; /* sequence count */
@@ -658,7 +660,7 @@ static int cmsis_dap_cmd_dap_swo_baudrate(
command[0] = CMD_DAP_SWO_BAUDRATE;
h_u32_to_le(&command[1], in_baudrate);
- int retval = cmsis_dap_xfer(cmsis_dap_handle, 4);
+ int retval = cmsis_dap_xfer(cmsis_dap_handle, 5);
uint32_t rvbr = le_to_h_u32(&cmsis_dap_handle->response[1]);
if (retval != ERROR_OK || rvbr == 0) {
LOG_ERROR("CMSIS-DAP: command CMD_SWO_Baudrate(%u) -> %u failed.", in_baudrate, rvbr);
@@ -783,7 +785,7 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
uint8_t cmd = transfer->cmd;
uint32_t data = transfer->data;
- LOG_DEBUG_IO("%s %s reg %x %"PRIx32,
+ LOG_DEBUG_IO("%s %s reg %x %" PRIx32,
cmd & SWD_CMD_APNDP ? "AP" : "DP",
cmd & SWD_CMD_RNW ? "read" : "write",
(cmd & SWD_CMD_A32) >> 1, data);
@@ -889,7 +891,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms)
uint32_t tmp = data;
idx += 4;
- LOG_DEBUG_IO("Read result: %"PRIx32, data);
+ LOG_DEBUG_IO("Read result: %" PRIx32, data);
/* Imitate posted AP reads */
if ((transfer->cmd & SWD_CMD_APNDP) ||
diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c
index a738200..55b9a55 100644
--- a/src/jtag/drivers/cmsis_dap_usb_bulk.c
+++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c
@@ -262,8 +262,10 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
/* If the interface is reliably identified
* then we need not insist on setting USB class, subclass and protocol
* exactly as the specification requires.
+ * Just filter out the well known classes, mainly CDC and MSC.
* At least KitProg3 uses class 0 contrary to the specification */
- if (intf_identified_reliably) {
+ if (intf_identified_reliably &&
+ (intf_desc->bInterfaceClass == 0 || intf_desc->bInterfaceClass > 0x12)) {
LOG_WARNING("Using CMSIS-DAPv2 interface %d with wrong class %" PRId8
" subclass %" PRId8 " or protocol %" PRId8,
interface_num,
diff --git a/src/jtag/drivers/esp_usb_jtag.c b/src/jtag/drivers/esp_usb_jtag.c
index 65293ee..dd96f4b 100644
--- a/src/jtag/drivers/esp_usb_jtag.c
+++ b/src/jtag/drivers/esp_usb_jtag.c
@@ -16,8 +16,6 @@
#include "bitq.h"
#include "libusb_helper.h"
-#define __packed __attribute__((packed))
-
/*
Holy Crap, it's protocol documentation, and it's even vendor-provided!
@@ -110,7 +108,7 @@ descriptor.
struct jtag_proto_caps_hdr {
uint8_t proto_ver; /* Protocol version. Expects JTAG_PROTO_CAPS_VER for now. */
uint8_t length; /* of this plus any following descriptors */
-} __packed;
+} __attribute__((packed));
/* start of the descriptor headers */
#define JTAG_BUILTIN_DESCR_START_OFF 0 /* Devices with builtin usb jtag */
@@ -133,7 +131,7 @@ of caps header to assume this. If no such caps exist, assume a minimum (in) buff
struct jtag_gen_hdr {
uint8_t type;
uint8_t length;
-} __packed;
+} __attribute__((packed));
struct jtag_proto_caps_speed_apb {
uint8_t type; /* Type, always JTAG_PROTO_CAPS_SPEED_APB_TYPE */
@@ -141,7 +139,7 @@ struct jtag_proto_caps_speed_apb {
uint8_t apb_speed_10khz[2]; /* ABP bus speed, in 10KHz increments. Base speed is half this. */
uint8_t div_min[2]; /* minimum divisor (to base speed), inclusive */
uint8_t div_max[2]; /* maximum divisor (to base speed), inclusive */
-} __packed;
+} __attribute__((packed));
#define JTAG_PROTO_CAPS_DATA_LEN 255
#define JTAG_PROTO_CAPS_SPEED_APB_TYPE 1
diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c
index d0c5277..c353aef 100644
--- a/src/jtag/drivers/opendous.c
+++ b/src/jtag/drivers/opendous.c
@@ -796,17 +796,12 @@ int opendous_usb_read(struct opendous_jtag *opendous_jtag)
void opendous_debug_buffer(uint8_t *buffer, int length)
{
- char line[81];
- char s[4];
- int i;
- int j;
+ char line[8 + 3 * BYTES_PER_LINE + 1];
- for (i = 0; i < length; i += BYTES_PER_LINE) {
- snprintf(line, 5, "%04x", i);
- for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
- snprintf(s, 4, " %02x", buffer[j]);
- strcat(line, s);
- }
+ 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);
}
}
diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c
index ef7a493..7898e9d 100644
--- a/src/jtag/drivers/vdebug.c
+++ b/src/jtag/drivers/vdebug.c
@@ -1246,7 +1246,7 @@ static const struct command_registration vdebug_command_handlers[] = {
{
.name = "mem_path",
.handler = &vdebug_set_mem,
- .mode = COMMAND_ANY,
+ .mode = COMMAND_CONFIG,
.help = "set the design memory for the code load",
.usage = "<path> <base_address> <size>",
},
diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c
index ecba36b..8e5d638 100644
--- a/src/jtag/drivers/xds110.c
+++ b/src/jtag/drivers/xds110.c
@@ -1354,11 +1354,13 @@ static void xds110_swd_queue_cmd(uint8_t cmd, uint32_t *value)
static void xds110_swd_read_reg(uint8_t cmd, uint32_t *value,
uint32_t ap_delay_clk)
{
+ assert(cmd & SWD_CMD_RNW);
xds110_swd_queue_cmd(cmd, value);
}
static void xds110_swd_write_reg(uint8_t cmd, uint32_t value,
uint32_t ap_delay_clk)
{
+ assert(!(cmd & SWD_CMD_RNW));
xds110_swd_queue_cmd(cmd, &value);
}
diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c
index 67bbb3b..12848be 100644
--- a/src/jtag/interfaces.c
+++ b/src/jtag/interfaces.c
@@ -118,9 +118,6 @@ extern struct adapter_driver linuxgpiod_adapter_driver;
#if BUILD_XLNX_PCIE_XVC == 1
extern struct adapter_driver xlnx_pcie_xvc_adapter_driver;
#endif
-#if BUILD_AICE == 1
-extern struct adapter_driver aice_adapter_driver;
-#endif
#if BUILD_BCM2835GPIO == 1
extern struct adapter_driver bcm2835gpio_adapter_driver;
#endif
@@ -238,9 +235,6 @@ struct adapter_driver *adapter_drivers[] = {
#if BUILD_XLNX_PCIE_XVC == 1
&xlnx_pcie_xvc_adapter_driver,
#endif
-#if BUILD_AICE == 1
- &aice_adapter_driver,
-#endif
#if BUILD_BCM2835GPIO == 1
&bcm2835gpio_adapter_driver,
#endif
diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl
index aeb42ed..b74775a 100644
--- a/src/jtag/startup.tcl
+++ b/src/jtag/startup.tcl
@@ -865,12 +865,6 @@ proc ft232r_restore_serial args {
eval ft232r restore_serial $args
}
-lappend _telnet_autocomplete_skip "aice serial"
-proc "aice serial" {args} {
- echo "DEPRECATED! use 'adapter serial' not 'aice serial'"
- eval adapter serial $args
-}
-
lappend _telnet_autocomplete_skip cmsis_dap_serial
proc cmsis_dap_serial args {
echo "DEPRECATED! use 'adapter serial' not 'cmsis_dap_serial'"
diff --git a/src/openocd.c b/src/openocd.c
index bef084f..875da5a 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -230,65 +230,6 @@ static int openocd_register_commands(struct command_context *cmd_ctx)
return register_commands(cmd_ctx, NULL, openocd_command_handlers);
}
-/*
- * TODO: to be removed after v0.12.0
- * workaround for syntax change of "expr" in jimtcl 0.81
- * replace "expr" with openocd version that prints the deprecated msg
- */
-struct jim_scriptobj {
- void *token;
- Jim_Obj *filename_obj;
- int len;
- int subst_flags;
- int in_use;
- int firstline;
- int linenr;
- int missing;
-};
-
-static int jim_expr_command(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- if (argc == 2)
- return Jim_EvalExpression(interp, argv[1]);
-
- if (argc > 2) {
- Jim_Obj *obj = Jim_ConcatObj(interp, argc - 1, argv + 1);
- Jim_IncrRefCount(obj);
- const char *s = Jim_String(obj);
- struct jim_scriptobj *script = Jim_GetIntRepPtr(interp->currentScriptObj);
- if (interp->currentScriptObj == interp->emptyObj ||
- strcmp(interp->currentScriptObj->typePtr->name, "script") ||
- script->subst_flags ||
- script->filename_obj == interp->emptyObj)
- LOG_WARNING("DEPRECATED! use 'expr { %s }' not 'expr %s'", s, s);
- else
- LOG_WARNING("DEPRECATED! (%s:%d) use 'expr { %s }' not 'expr %s'",
- Jim_String(script->filename_obj), script->linenr, s, s);
- int retcode = Jim_EvalExpression(interp, obj);
- Jim_DecrRefCount(interp, obj);
- return retcode;
- }
-
- Jim_WrongNumArgs(interp, 1, argv, "expression ?...?");
- return JIM_ERR;
-}
-
-static const struct command_registration expr_handler[] = {
- {
- .name = "expr",
- .jim_handler = jim_expr_command,
- .mode = COMMAND_ANY,
- .help = "",
- .usage = "",
- },
- COMMAND_REGISTRATION_DONE
-};
-
-static int workaround_for_jimtcl_expr(struct command_context *cmd_ctx)
-{
- return register_commands(cmd_ctx, NULL, expr_handler);
-}
-
struct command_context *global_cmd_ctx;
static struct command_context *setup_command_handler(Jim_Interp *interp)
@@ -301,7 +242,6 @@ static struct command_context *setup_command_handler(Jim_Interp *interp)
/* register subsystem commands */
typedef int (*command_registrant_t)(struct command_context *cmd_ctx_value);
static const command_registrant_t command_registrants[] = {
- &workaround_for_jimtcl_expr,
&openocd_register_commands,
&server_register_commands,
&gdb_register_commands,
diff --git a/src/pld/virtex2.c b/src/pld/virtex2.c
index 771af99..98fd58a 100644
--- a/src/pld/virtex2.c
+++ b/src/pld/virtex2.c
@@ -157,6 +157,8 @@ static int virtex2_load(struct pld_device *pld_device, const char *filename)
virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */
jtag_execute_queue();
+ xilinx_free_bit_file(&bit_file);
+
return ERROR_OK;
}
@@ -173,7 +175,7 @@ COMMAND_HANDLER(virtex2_handle_read_stat_command)
device = get_pld_device_by_num(dev_id);
if (!device) {
command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
- return ERROR_OK;
+ return ERROR_FAIL;
}
virtex2_read_stat(device, &status);
@@ -195,7 +197,7 @@ PLD_DEVICE_COMMAND_HANDLER(virtex2_pld_device_command)
tap = jtag_tap_by_string(CMD_ARGV[1]);
if (!tap) {
command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
- return ERROR_OK;
+ return ERROR_FAIL;
}
virtex2_info = malloc(sizeof(struct virtex2_pld_device));
diff --git a/src/pld/xilinx_bit.c b/src/pld/xilinx_bit.c
index 25deb80..792b337 100644
--- a/src/pld/xilinx_bit.c
+++ b/src/pld/xilinx_bit.c
@@ -87,26 +87,48 @@ int xilinx_read_bit_file(struct xilinx_bit_file *bit_file, const char *filename)
return ERROR_PLD_FILE_LOAD_FAILED;
}
+ bit_file->source_file = NULL;
+ bit_file->part_name = NULL;
+ bit_file->date = NULL;
+ bit_file->time = NULL;
+ bit_file->data = NULL;
+
read_count = fread(bit_file->unknown_header, 1, 13, input_file);
if (read_count != 13) {
LOG_ERROR("couldn't read unknown_header from file '%s'", filename);
+ fclose(input_file);
return ERROR_PLD_FILE_LOAD_FAILED;
}
- if (read_section(input_file, 2, 'a', NULL, &bit_file->source_file) != ERROR_OK)
+ if (read_section(input_file, 2, 'a', NULL, &bit_file->source_file) != ERROR_OK) {
+ xilinx_free_bit_file(bit_file);
+ fclose(input_file);
return ERROR_PLD_FILE_LOAD_FAILED;
+ }
- if (read_section(input_file, 2, 'b', NULL, &bit_file->part_name) != ERROR_OK)
+ if (read_section(input_file, 2, 'b', NULL, &bit_file->part_name) != ERROR_OK) {
+ xilinx_free_bit_file(bit_file);
+ fclose(input_file);
return ERROR_PLD_FILE_LOAD_FAILED;
+ }
- if (read_section(input_file, 2, 'c', NULL, &bit_file->date) != ERROR_OK)
+ if (read_section(input_file, 2, 'c', NULL, &bit_file->date) != ERROR_OK) {
+ xilinx_free_bit_file(bit_file);
+ fclose(input_file);
return ERROR_PLD_FILE_LOAD_FAILED;
+ }
- if (read_section(input_file, 2, 'd', NULL, &bit_file->time) != ERROR_OK)
+ if (read_section(input_file, 2, 'd', NULL, &bit_file->time) != ERROR_OK) {
+ xilinx_free_bit_file(bit_file);
+ fclose(input_file);
return ERROR_PLD_FILE_LOAD_FAILED;
+ }
- if (read_section(input_file, 4, 'e', &bit_file->length, &bit_file->data) != ERROR_OK)
+ if (read_section(input_file, 4, 'e', &bit_file->length, &bit_file->data) != ERROR_OK) {
+ xilinx_free_bit_file(bit_file);
+ fclose(input_file);
return ERROR_PLD_FILE_LOAD_FAILED;
+ }
LOG_DEBUG("bit_file: %s %s %s,%s %" PRIu32 "", bit_file->source_file, bit_file->part_name,
bit_file->date, bit_file->time, bit_file->length);
@@ -115,3 +137,12 @@ int xilinx_read_bit_file(struct xilinx_bit_file *bit_file, const char *filename)
return ERROR_OK;
}
+
+void xilinx_free_bit_file(struct xilinx_bit_file *bit_file)
+{
+ free(bit_file->source_file);
+ free(bit_file->part_name);
+ free(bit_file->date);
+ free(bit_file->time);
+ free(bit_file->data);
+}
diff --git a/src/pld/xilinx_bit.h b/src/pld/xilinx_bit.h
index e30ed23..f443bf7 100644
--- a/src/pld/xilinx_bit.h
+++ b/src/pld/xilinx_bit.h
@@ -22,4 +22,6 @@ struct xilinx_bit_file {
int xilinx_read_bit_file(struct xilinx_bit_file *bit_file, const char *filename);
+void xilinx_free_bit_file(struct xilinx_bit_file *bit_file);
+
#endif /* OPENOCD_PLD_XILINX_BIT_H */
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
index 5038b09..7b296cc 100644
--- a/src/rtos/FreeRTOS.c
+++ b/src/rtos/FreeRTOS.c
@@ -112,13 +112,6 @@ static int cortex_m_stacking(struct rtos *rtos, const struct rtos_register_stack
return ERROR_OK;
}
-static int nds32_stacking(struct rtos *rtos, const struct rtos_register_stacking **stacking,
- target_addr_t stack_ptr)
-{
- *stacking = &rtos_standard_nds32_n1068_stacking;
- return ERROR_OK;
-}
-
/* take 4 bytes (32 bits) as the default size,
* which is suitable for most 32-bit targets and
* configuration of configUSE_16_BIT_TICKS = 0. */
@@ -226,10 +219,6 @@ static const struct freertos_params freertos_params_list[] = {
.stacking = cortex_m_stacking
},
{
- .target_name = "nds32_v3",
- .stacking = nds32_stacking,
- },
- {
.target_name = "riscv",
.stacking = riscv_stacking,
.commands = riscv_commands,
diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c
index 7b76fb6..5bdd007 100644
--- a/src/rtos/ThreadX.c
+++ b/src/rtos/ThreadX.c
@@ -320,6 +320,12 @@ static int threadx_update_threads(struct rtos *rtos)
rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));
strcpy(rtos->thread_details->thread_name_str, tmp_str);
+ /* If we just invented thread 1 to represent the current execution, we
+ * need to make sure the RTOS object also claims it's the current thread
+ * so that threadx_get_thread_reg_list() doesn't attempt to read a
+ * thread control block at 0x00000001. */
+ rtos->current_thread = 1;
+
if (thread_list_size == 0) {
rtos->thread_count = 1;
return ERROR_OK;
@@ -364,16 +370,21 @@ static int threadx_update_threads(struct rtos *rtos)
}
/* Read the thread name */
- retval =
- target_read_buffer(rtos->target,
- name_ptr,
- THREADX_THREAD_NAME_STR_SIZE,
- (uint8_t *)&tmp_str);
- if (retval != ERROR_OK) {
- LOG_ERROR("Error reading thread name from ThreadX target");
- return retval;
+ tmp_str[0] = '\x00';
+
+ /* Check if thread has a valid name */
+ if (name_ptr != 0) {
+ retval =
+ target_read_buffer(rtos->target,
+ name_ptr,
+ THREADX_THREAD_NAME_STR_SIZE,
+ (uint8_t *)&tmp_str);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Error reading thread name from ThreadX target");
+ return retval;
+ }
+ tmp_str[THREADX_THREAD_NAME_STR_SIZE - 1] = '\x00';
}
- tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00';
if (tmp_str[0] == '\x00')
strcpy(tmp_str, "No Name");
diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c
index 3f813ac..963bb61 100644
--- a/src/rtos/eCos.c
+++ b/src/rtos/eCos.c
@@ -11,66 +11,446 @@
#include <jtag/jtag.h>
#include "target/target.h"
#include "target/target_type.h"
+#include "target/armv7m.h"
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
+#include "helper/bits.h"
+#include "rtos_standard_stackings.h"
#include "rtos_ecos_stackings.h"
+#include "server/gdb_server.h"
+
+/* Unfortunately for the moment we are limited to returning the hardwired
+ * register count (ARMV7M_NUM_CORE_REGS for Cortex-M) since the openocd RTOS
+ * support does not yet support accessing all per-thread "stacked"
+ * registers. e.g. For Cortex-M under eCos we have a per-thread BASEPRI, and for
+ * all eCos targets we may have per-thread VFP/FPU register state.
+ *
+ * So, for the moment, we continue to use the hardwired limit for the depth of
+ * the returned register description vector. The current openocd
+ * rtos_standard_stackings.c just provides the main core regs for the Cortex_M*
+ * targets regardless of whether FPU is present/enabled.
+ *
+ * However, this code is written with the expectation that we may eventually be
+ * able to provide more register information ("m-system" and "vfp" for example)
+ * and also with the expectation of supporting different register sets being
+ * returned depending on the per-thread Cortex-M eCos contex_m for
+ * example. Hence the fact that the eCos_stack_layout_*() functions below allow
+ * for the stack context descriptor vector to be returned by those calls
+ * allowing for eventual support where this code will potentially cache
+ * different sets of register descriptors for the different shapes of contexts
+ * in a *single* application/binary run-time.
+ *
+ * TODO: Extend openocd generic RTOS support to allow thread-specific system and
+ * FPU register state to be returned. */
+
+struct ecos_params;
static bool ecos_detect_rtos(struct target *target);
static int ecos_create(struct target *target);
static int ecos_update_threads(struct rtos *rtos);
static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs);
static int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);
+static int ecos_stack_layout_cortexm(struct rtos *rtos, struct ecos_params *param,
+ int64_t stack_ptr, const struct rtos_register_stacking **si);
+static int ecos_stack_layout_arm(struct rtos *rtos, struct ecos_params *param,
+ int64_t stack_ptr, const struct rtos_register_stacking **si);
+
+/* The current eCos thread IDentifier uses 0 as an unused (not a valid thread
+ * ID) value. Currently the unique_id field is 16-bits, but the eCos SMP support
+ * convention is that only 12-bits of the ID will be used. This
+ * ECOS_MAX_THREAD_COUNT manifest is provided to limit the potential for
+ * interpreting stale/inconsistent thread list state when the debug host scans
+ * the thread list before the target RTOS has completed its initialisation. This
+ * support will need to revisited when eCos is re-engineered to support more
+ * than 16 CPU SMP setups. */
+#define ECOS_MAX_THREAD_COUNT (4095)
struct ecos_thread_state {
int value;
const char *desc;
};
-static const struct ecos_thread_state ecos_thread_states[] = {
- { 0, "Ready" },
- { 1, "Sleeping" },
- { 2, "Countsleep" },
- { 4, "Suspended" },
- { 8, "Creating" },
- { 16, "Exited" }
+/* The status is actually a logical-OR bitmask of states: */
+enum ecos_thread_state_flags {
+ RUNNING = 0, /* explicit no-bits-set value */
+ SLEEPING = BIT(0),
+ COUNTSLEEP = BIT(1),
+ SUSPENDED = BIT(2),
+ CREATING = BIT(3),
+ EXITED = BIT(4),
+ SLEEPSET = (SLEEPING | COUNTSLEEP)
+};
+
+/* Cyg_Thread:: reason codes for wake and sleep fields: */
+static const struct ecos_thread_state ecos_thread_reasons[] = {
+ { 0, "NONE" }, /* normally indicates "not yet started" */
+ { 1, "WAIT" }, /* wait with no timeout */
+ { 2, "DELAY" }, /* simple time delay */
+ { 3, "TIMEOUT" }, /* wait with timeout *or* timeout expired */
+ { 4, "BREAK" }, /* forced break out of sleep */
+ { 5, "DESTRUCT" }, /* wait on object being destroyed */
+ { 6, "EXIT" }, /* forced termination */
+ { 7, "DONE" } /* wait/delay completed */
+};
+
+static const char * const target_cortex_m[] = {
+ "cortex_m",
+ "hla_target",
+ NULL
+};
+
+static const char * const target_arm[] = {
+ "cortex_a",
+ "arm7tdmi",
+ "arm720t",
+ "arm9tdmi",
+ "arm920t",
+ "arm926ejs",
+ "arm946e",
+ "arm966e",
+ "arm11",
+ NULL
};
-#define ECOS_NUM_STATES ARRAY_SIZE(ecos_thread_states)
+/* Since individual eCos application configurations may have different thread
+ * object structure layouts depending on the actual build-time enabled features
+ * we provide support for applications built containing the relevant symbolic
+ * support to match the actual application binary being debugged, rather than
+ * relying on a set of default/fixed (and potentially incorrect)
+ * offsets. However, for backwards compatibility, we do *NOT* enforce the
+ * requirement for the common extra helper symbols to be present to allow the
+ * fallback to the simple fixed CM3 model to avoid affecting existing users of
+ * older eCos worlds. Similarly we need to provide support for per-thread
+ * register context offsets, as well as for per-application-configurations,
+ * since some targets can have different stacked state on a per-thread basis
+ * (e.g. "cortex_m"). This is why the stacking_info is now set at run-time
+ * rather than being fixed. */
struct ecos_params {
- const char *target_name;
+ const char * const *target_names; /* NULL terminated list of targets */
+ int (*target_stack_layout)(struct rtos *rtos, struct ecos_params *param,
+ int64_t stack_ptr, const struct rtos_register_stacking **si);
+ bool flush_common;
unsigned char pointer_width;
- unsigned char thread_stack_offset;
- unsigned char thread_name_offset;
- unsigned char thread_state_offset;
- unsigned char thread_next_offset;
- unsigned char thread_uniqueid_offset;
+ unsigned char uid_width;
+ unsigned char state_width;
+ unsigned int thread_stack_offset;
+ unsigned int thread_name_offset;
+ unsigned int thread_state_offset;
+ unsigned int thread_next_offset;
+ unsigned int thread_uniqueid_offset;
const struct rtos_register_stacking *stacking_info;
};
-static const struct ecos_params ecos_params_list[] = {
+/* As mentioned above we provide default offset values for the "cortex_m"
+ * targets for backwards compatibility with older eCos application builds and
+ * previous users of this RTOS specific support that do not have the
+ * configuration specific offsets provided in the symbol table. The support for
+ * other targets (e.g. "cortex_a") we do expect the application to provide the
+ * required symbolic information. We do not populate the stacking_info reference
+ * until we have had a chance to interrogate the symbol table. */
+
+static struct ecos_params ecos_params_list[] = {
+ {
+ .target_names = target_cortex_m,
+ .pointer_width = 4,
+ .uid_width = 2,
+ .state_width = 4,
+ .thread_stack_offset = 0x0c,
+ .thread_name_offset = 0x9c,
+ .thread_state_offset = 0x3c,
+ .thread_next_offset = 0xa0,
+ .thread_uniqueid_offset = 0x4c,
+ .target_stack_layout = ecos_stack_layout_cortexm,
+ .stacking_info = NULL
+ },
{
- "cortex_m", /* target_name */
- 4, /* pointer_width; */
- 0x0c, /* thread_stack_offset; */
- 0x9c, /* thread_name_offset; */
- 0x3c, /* thread_state_offset; */
- 0xa0, /* thread_next_offset */
- 0x4c, /* thread_uniqueid_offset */
- &rtos_ecos_cortex_m3_stacking /* stacking_info */
+ .target_names = target_arm,
+ .pointer_width = 0,
+ .uid_width = 0,
+ .state_width = 0,
+ .thread_stack_offset = 0,
+ .thread_name_offset = 0,
+ .thread_state_offset = 0,
+ .thread_next_offset = 0,
+ .thread_uniqueid_offset = 0,
+ .target_stack_layout = ecos_stack_layout_arm,
+ .stacking_info = NULL
}
};
+#define ECOS_NUM_PARAMS ARRAY_SIZE(ecos_params_list)
+
+/* To eventually allow for more than just the ARMV7M_NUM_CORE_REGS to be
+ * returned by the Cortex-M support, and to avoid run-time lookups we manually
+ * maintain our own mapping for the supplied stack register vector entries. This
+ * enum needs to match the rtos_ecos_regoff_cortexm[] vector. Admittedly the
+ * initial indices just match the corresponding ARMV7M_R* definitions, but after
+ * the base registers the ARMV7M_* number space does not match the vector we
+ * wish to populate in this eCos support code. */
+enum ecos_reglist_cortexm {
+ ECOS_REGLIST_R0 = 0,
+ ECOS_REGLIST_R1,
+ ECOS_REGLIST_R2,
+ ECOS_REGLIST_R3,
+ ECOS_REGLIST_R4,
+ ECOS_REGLIST_R5,
+ ECOS_REGLIST_R6,
+ ECOS_REGLIST_R7,
+ ECOS_REGLIST_R8,
+ ECOS_REGLIST_R9,
+ ECOS_REGLIST_R10,
+ ECOS_REGLIST_R11,
+ ECOS_REGLIST_R12,
+ ECOS_REGLIST_R13,
+ ECOS_REGLIST_R14,
+ ECOS_REGLIST_PC,
+ ECOS_REGLIST_XPSR, /* ARMV7M_NUM_CORE_REGS */
+ ECOS_REGLIST_BASEPRI,
+ ECOS_REGLIST_FPSCR, /* Following for FPU contexts */
+ ECOS_REGLIST_D0,
+ ECOS_REGLIST_D1,
+ ECOS_REGLIST_D2,
+ ECOS_REGLIST_D3,
+ ECOS_REGLIST_D4,
+ ECOS_REGLIST_D5,
+ ECOS_REGLIST_D6,
+ ECOS_REGLIST_D7,
+ ECOS_REGLIST_D8,
+ ECOS_REGLIST_D9,
+ ECOS_REGLIST_D10,
+ ECOS_REGLIST_D11,
+ ECOS_REGLIST_D12,
+ ECOS_REGLIST_D13,
+ ECOS_REGLIST_D14,
+ ECOS_REGLIST_D15
+};
+
+#define ECOS_CORTEXM_BASE_NUMREGS (ARMV7M_NUM_CORE_REGS)
+
+/* NOTE: The offsets in this vector are overwritten by the architecture specific
+ * layout functions depending on the specific application configuration. The
+ * ordering of this vector MUST match eCos_reglist. */
+static struct stack_register_offset rtos_ecos_regoff_cortexm[] = {
+ { ARMV7M_R0, -1, 32 }, /* r0 */
+ { ARMV7M_R1, -1, 32 }, /* r1 */
+ { ARMV7M_R2, -1, 32 }, /* r2 */
+ { ARMV7M_R3, -1, 32 }, /* r3 */
+ { ARMV7M_R4, -1, 32 }, /* r4 */
+ { ARMV7M_R5, -1, 32 }, /* r5 */
+ { ARMV7M_R6, -1, 32 }, /* r6 */
+ { ARMV7M_R7, -1, 32 }, /* r7 */
+ { ARMV7M_R8, -1, 32 }, /* r8 */
+ { ARMV7M_R9, -1, 32 }, /* r9 */
+ { ARMV7M_R10, -1, 32 }, /* r10 */
+ { ARMV7M_R11, -1, 32 }, /* r11 */
+ { ARMV7M_R12, -1, 32 }, /* r12 */
+ { ARMV7M_R13, -1, 32 }, /* sp */
+ { ARMV7M_R14, -1, 32 }, /* lr */
+ { ARMV7M_PC, -1, 32 }, /* pc */
+ { ARMV7M_XPSR, -1, 32 }, /* xPSR */
+ { ARMV7M_BASEPRI, -1, 32 }, /* BASEPRI */
+ { ARMV7M_FPSCR, -1, 32 }, /* FPSCR */
+ { ARMV7M_D0, -1, 64 }, /* D0 (S0/S1) */
+ { ARMV7M_D1, -1, 64 }, /* D1 (S2/S3) */
+ { ARMV7M_D2, -1, 64 }, /* D2 (S4/S5) */
+ { ARMV7M_D3, -1, 64 }, /* D3 (S6/S7) */
+ { ARMV7M_D4, -1, 64 }, /* D4 (S8/S9) */
+ { ARMV7M_D5, -1, 64 }, /* D5 (S10/S11) */
+ { ARMV7M_D6, -1, 64 }, /* D6 (S12/S13) */
+ { ARMV7M_D7, -1, 64 }, /* D7 (S14/S15) */
+ { ARMV7M_D8, -1, 64 }, /* D8 (S16/S17) */
+ { ARMV7M_D9, -1, 64 }, /* D9 (S18/S19) */
+ { ARMV7M_D10, -1, 64 }, /* D10 (S20/S21) */
+ { ARMV7M_D11, -1, 64 }, /* D11 (S22/S23) */
+ { ARMV7M_D12, -1, 64 }, /* D12 (S24/S25) */
+ { ARMV7M_D13, -1, 64 }, /* D13 (S26/S27) */
+ { ARMV7M_D14, -1, 64 }, /* D14 (S28/S29) */
+ { ARMV7M_D15, -1, 64 }, /* D15 (S30/S31) */
+};
+
+static struct stack_register_offset rtos_ecos_regoff_arm[] = {
+ { 0, -1, 32 }, /* r0 */
+ { 1, -1, 32 }, /* r1 */
+ { 2, -1, 32 }, /* r2 */
+ { 3, -1, 32 }, /* r3 */
+ { 4, -1, 32 }, /* r4 */
+ { 5, -1, 32 }, /* r5 */
+ { 6, -1, 32 }, /* r6 */
+ { 7, -1, 32 }, /* r7 */
+ { 8, -1, 32 }, /* r8 */
+ { 9, -1, 32 }, /* r9 */
+ { 10, -1, 32 }, /* r10 */
+ { 11, -1, 32 }, /* r11 (fp) */
+ { 12, -1, 32 }, /* r12 (ip) */
+ { 13, -1, 32 }, /* sp (r13) */
+ { 14, -1, 32 }, /* lr (r14) */
+ { 15, -1, 32 }, /* pc (r15) */
+ { 16, -1, 32 }, /* xPSR */
+};
+
+static struct rtos_register_stacking rtos_ecos_stacking = {
+ .stack_registers_size = 0,
+ .stack_growth_direction = -1,
+ .num_output_registers = 0,
+ .calculate_process_stack = NULL, /* stack_alignment */
+ .register_offsets = NULL
+};
+
+/* To avoid the run-time cost of matching explicit symbol names we push the
+ * lookup offsets to this *manually* maintained enumeration which must match the
+ * ecos_symbol_list[] order below. */
enum ecos_symbol_values {
ECOS_VAL_THREAD_LIST = 0,
- ECOS_VAL_CURRENT_THREAD_PTR = 1
+ ECOS_VAL_CURRENT_THREAD_PTR,
+ ECOS_VAL_COMMON_THREAD_NEXT_OFF,
+ ECOS_VAL_COMMON_THREAD_NEXT_SIZE,
+ ECOS_VAL_COMMON_THREAD_STATE_OFF,
+ ECOS_VAL_COMMON_THREAD_STATE_SIZE,
+ ECOS_VAL_COMMON_THREAD_SLEEP_OFF,
+ ECOS_VAL_COMMON_THREAD_SLEEP_SIZE,
+ ECOS_VAL_COMMON_THREAD_WAKE_OFF,
+ ECOS_VAL_COMMON_THREAD_WAKE_SIZE,
+ ECOS_VAL_COMMON_THREAD_ID_OFF,
+ ECOS_VAL_COMMON_THREAD_ID_SIZE,
+ ECOS_VAL_COMMON_THREAD_NAME_OFF,
+ ECOS_VAL_COMMON_THREAD_NAME_SIZE,
+ ECOS_VAL_COMMON_THREAD_PRI_OFF,
+ ECOS_VAL_COMMON_THREAD_PRI_SIZE,
+ ECOS_VAL_COMMON_THREAD_STACK_OFF,
+ ECOS_VAL_COMMON_THREAD_STACK_SIZE,
+ ECOS_VAL_CORTEXM_THREAD_SAVED,
+ ECOS_VAL_CORTEXM_CTX_THREAD_SIZE,
+ ECOS_VAL_CORTEXM_CTX_TYPE_OFF,
+ ECOS_VAL_CORTEXM_CTX_TYPE_SIZE,
+ ECOS_VAL_CORTEXM_CTX_BASEPRI_OFF,
+ ECOS_VAL_CORTEXM_CTX_BASEPRI_SIZE,
+ ECOS_VAL_CORTEXM_CTX_SP_OFF,
+ ECOS_VAL_CORTEXM_CTX_SP_SIZE,
+ ECOS_VAL_CORTEXM_CTX_REG_OFF,
+ ECOS_VAL_CORTEXM_CTX_REG_SIZE,
+ ECOS_VAL_CORTEXM_CTX_PC_OFF,
+ ECOS_VAL_CORTEXM_CTX_PC_SIZE,
+ ECOS_VAL_CORTEXM_VAL_EXCEPTION,
+ ECOS_VAL_CORTEXM_VAL_THREAD,
+ ECOS_VAL_CORTEXM_VAL_INTERRUPT,
+ ECOS_VAL_CORTEXM_VAL_FPU,
+ ECOS_VAL_CORTEXM_CTX_FPSCR_OFF,
+ ECOS_VAL_CORTEXM_CTX_FPSCR_SIZE,
+ ECOS_VAL_CORTEXM_CTX_S_OFF,
+ ECOS_VAL_CORTEXM_CTX_S_SIZE,
+ ECOS_VAL_ARM_REGSIZE,
+ ECOS_VAL_ARM_CTX_R0_OFF,
+ ECOS_VAL_ARM_CTX_R1_OFF,
+ ECOS_VAL_ARM_CTX_R2_OFF,
+ ECOS_VAL_ARM_CTX_R3_OFF,
+ ECOS_VAL_ARM_CTX_R4_OFF,
+ ECOS_VAL_ARM_CTX_R5_OFF,
+ ECOS_VAL_ARM_CTX_R6_OFF,
+ ECOS_VAL_ARM_CTX_R7_OFF,
+ ECOS_VAL_ARM_CTX_R8_OFF,
+ ECOS_VAL_ARM_CTX_R9_OFF,
+ ECOS_VAL_ARM_CTX_R10_OFF,
+ ECOS_VAL_ARM_CTX_FP_OFF,
+ ECOS_VAL_ARM_CTX_IP_OFF,
+ ECOS_VAL_ARM_CTX_SP_OFF,
+ ECOS_VAL_ARM_CTX_LR_OFF,
+ ECOS_VAL_ARM_CTX_PC_OFF,
+ ECOS_VAL_ARM_CTX_CPSR_OFF,
+ ECOS_VAL_ARM_FPUSIZE,
+ ECOS_VAL_ARM_CTX_FPSCR_OFF,
+ ECOS_VAL_ARM_SCOUNT,
+ ECOS_VAL_ARM_CTX_SVEC_OFF,
+ ECOS_VAL_ARM_VFPCOUNT,
+ ECOS_VAL_ARM_CTX_VFPVEC_OFF
};
-static const char * const ecos_symbol_list[] = {
- "Cyg_Thread::thread_list",
- "Cyg_Scheduler_Base::current_thread",
- NULL
+struct symbols {
+ const char *name;
+ const char * const *target_names; /* non-NULL when for a specific architecture */
+ bool optional;
+};
+
+#define ECOSSYM(_n, _o, _t) { .name = _n, .optional = (_o), .target_names = _t }
+
+/* Some of offset/size helper symbols are common to all eCos
+ * targets. Unfortunately, for historical reasons, some information is in
+ * architecture specific namespaces leading to some duplication and a larger
+ * vector below. */
+static const struct symbols ecos_symbol_list[] = {
+ ECOSSYM("Cyg_Thread::thread_list", false, NULL),
+ ECOSSYM("Cyg_Scheduler_Base::current_thread", false, NULL),
+ /* Following symbols *are* required for generic application-specific
+ * configuration support, but we mark as optional for backwards
+ * compatibility with the previous fixed Cortex-M3 only RTOS plugin
+ * implementation. */
+ ECOSSYM("__ecospro_syminfo.off.cyg_thread.list_next", true, NULL),
+ ECOSSYM("__ecospro_syminfo.size.cyg_thread.list_next", true, NULL),
+ ECOSSYM("__ecospro_syminfo.off.cyg_thread.state", true, NULL),
+ ECOSSYM("__ecospro_syminfo.size.cyg_thread.state", true, NULL),
+ ECOSSYM("__ecospro_syminfo.off.cyg_thread.sleep_reason", true, NULL),
+ ECOSSYM("__ecospro_syminfo.size.cyg_thread.sleep_reason", true, NULL),
+ ECOSSYM("__ecospro_syminfo.off.cyg_thread.wake_reason", true, NULL),
+ ECOSSYM("__ecospro_syminfo.size.cyg_thread.wake_reason", true, NULL),
+ ECOSSYM("__ecospro_syminfo.off.cyg_thread.unique_id", true, NULL),
+ ECOSSYM("__ecospro_syminfo.size.cyg_thread.unique_id", true, NULL),
+ ECOSSYM("__ecospro_syminfo.off.cyg_thread.name", true, NULL),
+ ECOSSYM("__ecospro_syminfo.size.cyg_thread.name", true, NULL),
+ ECOSSYM("__ecospro_syminfo.off.cyg_thread.priority", true, NULL),
+ ECOSSYM("__ecospro_syminfo.size.cyg_thread.priority", true, NULL),
+ ECOSSYM("__ecospro_syminfo.off.cyg_thread.stack_ptr", true, NULL),
+ ECOSSYM("__ecospro_syminfo.size.cyg_thread.stack_ptr", true, NULL),
+ /* optional Cortex-M: */
+ ECOSSYM("__ecospro_syminfo.cortexm.thread.saved", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.Thread", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.type", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.type", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.basepri", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.basepri", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.sp", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.sp", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.r", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.r", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.pc", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.pc", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.value.HAL_SAVEDREGISTERS.EXCEPTION", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.value.HAL_SAVEDREGISTERS.THREAD", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.value.HAL_SAVEDREGISTERS.INTERRUPT", true, target_cortex_m),
+ /* optional Cortex-M with H/W FPU configured: */
+ ECOSSYM("__ecospro_syminfo.value.HAL_SAVEDREGISTERS.WITH_FPU", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.fpscr", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.fpscr", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.s", true, target_cortex_m),
+ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.s", true, target_cortex_m),
+ /* optional ARM: */
+ ECOSSYM("ARMREG_SIZE", true, target_arm),
+ ECOSSYM("armreg_r0", true, target_arm),
+ ECOSSYM("armreg_r1", true, target_arm),
+ ECOSSYM("armreg_r2", true, target_arm),
+ ECOSSYM("armreg_r3", true, target_arm),
+ ECOSSYM("armreg_r4", true, target_arm),
+ ECOSSYM("armreg_r5", true, target_arm),
+ ECOSSYM("armreg_r6", true, target_arm),
+ ECOSSYM("armreg_r7", true, target_arm),
+ ECOSSYM("armreg_r8", true, target_arm),
+ ECOSSYM("armreg_r9", true, target_arm),
+ ECOSSYM("armreg_r10", true, target_arm),
+ ECOSSYM("armreg_fp", true, target_arm),
+ ECOSSYM("armreg_ip", true, target_arm),
+ ECOSSYM("armreg_sp", true, target_arm),
+ ECOSSYM("armreg_lr", true, target_arm),
+ ECOSSYM("armreg_pc", true, target_arm),
+ ECOSSYM("armreg_cpsr", true, target_arm),
+ /* optional ARM FPU common: */
+ ECOSSYM("ARMREG_FPUCONTEXT_SIZE", true, target_arm),
+ ECOSSYM("armreg_fpscr", true, target_arm),
+ /* optional ARM FPU single-precision: */
+ ECOSSYM("ARMREG_S_COUNT", true, target_arm),
+ ECOSSYM("armreg_s_vec", true, target_arm),
+ /* optional ARM FPU double-precision: */
+ ECOSSYM("ARMREG_VFP_COUNT", true, target_arm),
+ ECOSSYM("armreg_vfp_vec", true, target_arm),
};
const struct rtos_type ecos_rtos = {
@@ -84,34 +464,280 @@ const struct rtos_type ecos_rtos = {
};
+static symbol_address_t ecos_value(struct rtos *rtos, unsigned int idx)
+{
+ if (idx < ARRAY_SIZE(ecos_symbol_list))
+ return rtos->symbols[idx].address;
+
+ /* We do not terminate, just return 0 in this case. */
+ LOG_ERROR("eCos: Invalid symbol index %u", idx);
+ return 0;
+}
+
+#define XMLENTRY(_c, _s) { .xc = (_c), .rs = (_s), .rlen = (sizeof(_s) - 1) }
+
+static const struct {
+ char xc;
+ const char *rs;
+ size_t rlen;
+} xmlchars[] = {
+ XMLENTRY('<', "&lt;"),
+ XMLENTRY('&', "&amp;"),
+ XMLENTRY('>', "&gt;"),
+ XMLENTRY('\'', "&apos;"),
+ XMLENTRY('"', "&quot;")
+};
+
+/** Escape any XML reserved characters in a string. */
+static bool ecos_escape_string(const char *raw, char *out, size_t limit)
+{
+ static const char *tokens = "<&>\'\"";
+ bool escaped = false;
+
+ if (!out || !limit)
+ return false;
+
+ (void)memset(out, '\0', limit);
+
+ while (raw && *raw && limit) {
+ size_t lok = strcspn(raw, tokens);
+ if (lok) {
+ size_t tocopy;
+ tocopy = ((limit < lok) ? limit : lok);
+ (void)memcpy(out, raw, tocopy);
+ limit -= tocopy;
+ out += tocopy;
+ raw += lok;
+ continue;
+ }
+
+ char *fidx = strchr(tokens, *raw);
+ if (!fidx) {
+ /* Should never happen assuming xmlchars
+ * vector and tokens string match. */
+ LOG_ERROR("eCos: Unexpected XML char %c", *raw);
+ continue;
+ }
+
+ uint32_t cidx = (fidx - tokens);
+ size_t tocopy = xmlchars[cidx].rlen;
+ if (limit < tocopy)
+ break;
+
+ escaped = true;
+ (void)memcpy(out, xmlchars[cidx].rs, tocopy);
+ limit -= tocopy;
+ out += tocopy;
+ raw++;
+ }
+
+ return escaped;
+}
+
+static int ecos_check_app_info(struct rtos *rtos, struct ecos_params *param)
+{
+ if (!rtos || !param)
+ return -1;
+
+ if (param->flush_common) {
+ if (debug_level >= LOG_LVL_DEBUG) {
+ for (unsigned int idx = 0; idx < ARRAY_SIZE(ecos_symbol_list); idx++) {
+ LOG_DEBUG("eCos: %s 0x%016" PRIX64 " %s",
+ rtos->symbols[idx].optional ? "OPTIONAL" : " ",
+ rtos->symbols[idx].address, rtos->symbols[idx].symbol_name);
+ }
+ }
+
+ /* If "__ecospro_syminfo.size.cyg_thread.list_next" is non-zero then we
+ * expect all of the generic thread structure symbols to have been
+ * provided. */
+ symbol_address_t thread_next_size = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_NEXT_SIZE);
+ if (thread_next_size != 0) {
+ param->pointer_width = thread_next_size;
+ param->uid_width = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_ID_SIZE);
+ param->state_width = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_STATE_SIZE);
+ param->thread_stack_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_STACK_OFF);
+ param->thread_name_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_NAME_OFF);
+ param->thread_state_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_STATE_OFF);
+ param->thread_next_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_NEXT_OFF);
+ param->thread_uniqueid_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_ID_OFF);
+ }
+
+ if (param->uid_width != sizeof(uint16_t)) {
+ /* Currently all eCos configurations use a 16-bit field to hold the
+ * unique thread ID. */
+ LOG_WARNING("eCos: Unexpected unique_id width %" PRIu8, param->uid_width);
+ param->uid_width = (unsigned char)sizeof(uint16_t);
+ }
+
+ param->stacking_info = NULL;
+ param->flush_common = false;
+ }
+
+ return ERROR_OK;
+}
+
+/* The Cortex-M eCosPro "thread" contexts have a "type" indicator, which tracks
+ * the context state of (THREAD | EXCEPTION | INTERRUPT) and whether FPU
+ * registers are saved.
+ *
+ * For thread-aware debugging from GDB we are only interested in THREAD states
+ * and so do not need to implement support for INTERRUPT or EXCEPTION thread
+ * contexts since this code does not expose those stack contexts via the
+ * constructed thread list support. */
+static int ecos_stack_layout_cortexm(struct rtos *rtos,
+ struct ecos_params *param, int64_t stack_ptr,
+ const struct rtos_register_stacking **si)
+{
+ int retval = ERROR_OK;
+
+ /* CONSIDER: We could return
+ * ecos_value(rtos, ECOS_VAL_CORTEXM_THREAD_SAVED) as the actual PC
+ * address of a context switch, with the LR being set to the context PC
+ * field to give a true representation of where the thread switch
+ * occurs. However that would require extending the common
+ * rtos_generic_stack_read() code with suitable support for applying a
+ * supplied value, or just implementing our own version of that code that
+ * can inject data into what is passed onwards to GDB. */
+
+ /* UPDATE: When we can return VFP register state then we will NOT be
+ * basing the cached state on the single param->stacking_info value,
+ * since we will need a different stacking_info structure returned for
+ * each thread type when FPU support is enabled. The use of the single
+ * param->stacking_info is a holder whilst we are limited to the fixed
+ * ARMV7M_NUM_CORE_REGS set of descriptors. */
+
+ if (!param->stacking_info &&
+ ecos_value(rtos, ECOS_VAL_CORTEXM_THREAD_SAVED) &&
+ ecos_value(rtos, ECOS_VAL_CORTEXM_VAL_THREAD)) {
+ unsigned char numoutreg = ECOS_CORTEXM_BASE_NUMREGS;
+
+ rtos_ecos_stacking.stack_registers_size = ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_THREAD_SIZE);
+ rtos_ecos_stacking.calculate_process_stack = rtos_generic_stack_align8;
+ rtos_ecos_stacking.register_offsets = rtos_ecos_regoff_cortexm;
+
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R0].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x00);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R1].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x04);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R2].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x08);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R3].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x0C);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R4].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x10);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R5].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x14);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R6].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x18);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R7].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x1C);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R8].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x20);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R9].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x24);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R10].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x28);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R11].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x2C);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R12].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x30);
+ /* Rather than using the stacked ECOS_VAL_CORTEXM_CTX_SP_OFF
+ * value we force the reported sp to be after the stacked
+ * register context. */
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R13].offset = -2;
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R14].offset = -1;
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_PC].offset = ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_PC_OFF);
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_XPSR].offset = -1;
+
+ param->stacking_info = &rtos_ecos_stacking;
+
+ /* Common Cortex-M thread register offsets for the current
+ * symbol table: */
+ if (retval == ERROR_OK && param->stacking_info) {
+ if (numoutreg > ECOS_REGLIST_BASEPRI) {
+ rtos_ecos_regoff_cortexm[ECOS_REGLIST_BASEPRI].offset =
+ ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_BASEPRI_OFF);
+ }
+
+ rtos_ecos_stacking.num_output_registers = numoutreg;
+ }
+ }
+
+ if (si)
+ *si = param->stacking_info;
+
+ return retval;
+}
+
+static int ecos_stack_layout_arm(struct rtos *rtos, struct ecos_params *param,
+ int64_t stack_ptr, const struct rtos_register_stacking **si)
+{
+ int retval = ERROR_OK;
+
+ if (!param->stacking_info && ecos_value(rtos, ECOS_VAL_ARM_REGSIZE)) {
+ /* When OpenOCD is extended to allow FPU registers to be returned from a
+ * stacked thread context we can check:
+ * if (0 != ecos_value(rtos, ECOS_VAL_ARM_FPUSIZE)) { FPU }
+ * for presence of FPU registers in the context. */
+
+ rtos_ecos_stacking.stack_registers_size = ecos_value(rtos, ECOS_VAL_ARM_REGSIZE);
+ rtos_ecos_stacking.num_output_registers = ARRAY_SIZE(rtos_ecos_regoff_arm);
+ rtos_ecos_stacking.register_offsets = rtos_ecos_regoff_arm;
+
+ rtos_ecos_regoff_arm[0].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R0_OFF);
+ rtos_ecos_regoff_arm[1].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R1_OFF);
+ rtos_ecos_regoff_arm[2].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R2_OFF);
+ rtos_ecos_regoff_arm[3].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R3_OFF);
+ rtos_ecos_regoff_arm[4].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R4_OFF);
+ rtos_ecos_regoff_arm[5].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R5_OFF);
+ rtos_ecos_regoff_arm[6].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R6_OFF);
+ rtos_ecos_regoff_arm[7].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R7_OFF);
+ rtos_ecos_regoff_arm[8].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R8_OFF);
+ rtos_ecos_regoff_arm[9].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R9_OFF);
+ rtos_ecos_regoff_arm[10].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R10_OFF);
+ rtos_ecos_regoff_arm[11].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_FP_OFF);
+ rtos_ecos_regoff_arm[12].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_IP_OFF);
+ rtos_ecos_regoff_arm[13].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_SP_OFF);
+ rtos_ecos_regoff_arm[14].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_LR_OFF);
+ rtos_ecos_regoff_arm[15].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_PC_OFF);
+ rtos_ecos_regoff_arm[16].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_CPSR_OFF);
+
+ param->stacking_info = &rtos_ecos_stacking;
+ }
+
+ if (si)
+ *si = param->stacking_info;
+
+ return retval;
+}
+
+/* We see this function called on a new connection, it looks like before and
+ * after the "tar rem"/"tar extended-remote". It might be the only point we can
+ * decide to cache information (to check if the symbol table has changed). */
static int ecos_update_threads(struct rtos *rtos)
{
int retval;
int tasks_found = 0;
int thread_list_size = 0;
- const struct ecos_params *param;
+ struct ecos_params *param;
if (!rtos)
return -1;
+ /* wipe out previous thread details if any */
+ rtos_free_threadlist(rtos);
+
if (!rtos->rtos_specific_params)
return -3;
- param = (const struct ecos_params *) rtos->rtos_specific_params;
+ param = rtos->rtos_specific_params;
if (!rtos->symbols) {
+ /* NOTE: We only see this when connecting from GDB the first
+ * time before the application image is loaded. So it is not a
+ * hook for detecting an application change. */
+ param->flush_common = true;
LOG_ERROR("No symbols for eCos");
return -4;
}
+ retval = ecos_check_app_info(rtos, param);
+ if (retval != ERROR_OK)
+ return retval;
+
if (rtos->symbols[ECOS_VAL_THREAD_LIST].address == 0) {
LOG_ERROR("Don't have the thread list head");
return -2;
}
- /* wipe out previous thread details if any */
- rtos_free_threadlist(rtos);
-
/* determine the number of current threads */
uint32_t thread_list_head = rtos->symbols[ECOS_VAL_THREAD_LIST].address;
uint32_t thread_index;
@@ -120,50 +746,82 @@ static int ecos_update_threads(struct rtos *rtos)
param->pointer_width,
(uint8_t *) &thread_index);
uint32_t first_thread = thread_index;
- do {
- thread_list_size++;
- retval = target_read_buffer(rtos->target,
- thread_index + param->thread_next_offset,
- param->pointer_width,
- (uint8_t *) &thread_index);
- if (retval != ERROR_OK)
- return retval;
- } while (thread_index != first_thread);
+
+ /* Even if 0==first_thread indicates a system with no defined eCos
+ * threads, instead of early exiting here we fall through the code to
+ * allow the creation of a faked "Current Execution" descriptor as
+ * needed. */
+
+ if (first_thread) {
+ /* Since the OpenOCD RTOS support can attempt to obtain thread
+ * information on initial connection when the system *may* have
+ * undefined memory state it is possible for a simple thread count scan
+ * to produce invalid results. To avoid blocking indefinitely when
+ * encountering an invalid closed loop we limit the number of threads to
+ * the maximum possible, and if we pass that limit then something is
+ * wrong so treat the system as having no threads defined. */
+ do {
+ thread_list_size++;
+ if (thread_list_size > ECOS_MAX_THREAD_COUNT) {
+ /* Treat as "no threads" case: */
+ first_thread = 0;
+ thread_list_size = 0;
+ break;
+ }
+ retval = target_read_buffer(rtos->target,
+ thread_index + param->thread_next_offset,
+ param->pointer_width,
+ (uint8_t *)&thread_index);
+ if (retval != ERROR_OK)
+ return retval;
+ } while (thread_index != first_thread);
+ }
/* read the current thread id */
+ rtos->current_thread = 0;
+
uint32_t current_thread_addr;
retval = target_read_buffer(rtos->target,
rtos->symbols[ECOS_VAL_CURRENT_THREAD_PTR].address,
- 4,
+ param->pointer_width,
(uint8_t *)&current_thread_addr);
- if (retval != ERROR_OK)
- return retval;
- rtos->current_thread = 0;
- retval = target_read_buffer(rtos->target,
- current_thread_addr + param->thread_uniqueid_offset,
- 2,
- (uint8_t *)&rtos->current_thread);
if (retval != ERROR_OK) {
- LOG_ERROR("Could not read eCos current thread from target");
+ LOG_ERROR("Reading active thread address");
return retval;
}
- if ((thread_list_size == 0) || (rtos->current_thread == 0)) {
+ if (current_thread_addr) {
+ uint16_t id = 0;
+ retval = target_read_buffer(rtos->target,
+ current_thread_addr + param->thread_uniqueid_offset,
+ param->uid_width,
+ (uint8_t *)&id);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Could not read eCos current thread from target");
+ return retval;
+ }
+ rtos->current_thread = (threadid_t)id;
+ }
+
+ if (thread_list_size == 0 || rtos->current_thread == 0) {
/* Either : No RTOS threads - there is always at least the current execution though */
/* OR : No current thread - all threads suspended - show the current execution
* of idling */
- char tmp_str[] = "Current Execution";
+ static const char tmp_str[] = "Current Execution";
thread_list_size++;
tasks_found++;
rtos->thread_details = malloc(
sizeof(struct thread_detail) * thread_list_size);
- rtos->thread_details->threadid = 1;
+ /* 1 is a valid eCos thread id, so we return 0 for this faked
+ * "current" CPU state: */
+ rtos->thread_details->threadid = 0;
rtos->thread_details->exists = true;
rtos->thread_details->extra_info_str = NULL;
rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));
strcpy(rtos->thread_details->thread_name_str, tmp_str);
- if (thread_list_size == 0) {
+ /* Early exit if current CPU state our only "thread": */
+ if (thread_list_size == 1) {
rtos->thread_count = 1;
return ERROR_OK;
}
@@ -176,18 +834,18 @@ static int ecos_update_threads(struct rtos *rtos)
/* loop over all threads */
thread_index = first_thread;
do {
-
#define ECOS_THREAD_NAME_STR_SIZE (200)
char tmp_str[ECOS_THREAD_NAME_STR_SIZE];
- unsigned int i = 0;
uint32_t name_ptr = 0;
uint32_t prev_thread_ptr;
- /* Save the thread pointer */
- uint16_t thread_id;
+ /* Save the thread ID. For eCos the thread has a unique ID distinct from
+ * the thread_index descriptor pointer. We present this scheduler ID
+ * instead of the descriptor memory address. */
+ uint16_t thread_id = 0;
retval = target_read_buffer(rtos->target,
thread_index + param->thread_uniqueid_offset,
- 2,
+ param->uid_width,
(uint8_t *)&thread_id);
if (retval != ERROR_OK) {
LOG_ERROR("Could not read eCos thread id from target");
@@ -195,7 +853,7 @@ static int ecos_update_threads(struct rtos *rtos)
}
rtos->thread_details[tasks_found].threadid = thread_id;
- /* read the name pointer */
+ /* Read the name pointer */
retval = target_read_buffer(rtos->target,
thread_index + param->thread_name_offset,
param->pointer_width,
@@ -217,8 +875,26 @@ static int ecos_update_threads(struct rtos *rtos)
}
tmp_str[ECOS_THREAD_NAME_STR_SIZE-1] = '\x00';
- if (tmp_str[0] == '\x00')
- strcpy(tmp_str, "No Name");
+ /* Since eCos can have arbitrary C string names we can sometimes
+ * get an internal warning from GDB about "not well-formed
+ * (invalid token)" since the XML post-processing done by GDB on
+ * the OpenOCD returned response containing the thread strings
+ * is not escaped. For example the eCos kernel testsuite
+ * application tm_basic uses the thread name "<<NULL>>" which
+ * will trigger this failure unless escaped. */
+ if (tmp_str[0] == '\x00') {
+ snprintf(tmp_str, ECOS_THREAD_NAME_STR_SIZE, "NoName:[0x%08" PRIX32 "]", thread_index);
+ } else {
+ /* The following is a workaround to avoid any issues
+ * from arbitrary eCos thread names causing GDB/OpenOCD
+ * issues. We limit the escaped thread name passed to
+ * GDB to the same length as the un-escaped just to
+ * avoid overly long strings. */
+ char esc_str[ECOS_THREAD_NAME_STR_SIZE];
+ bool escaped = ecos_escape_string(tmp_str, esc_str, sizeof(esc_str));
+ if (escaped)
+ strcpy(tmp_str, esc_str);
+ }
rtos->thread_details[tasks_found].thread_name_str =
malloc(strlen(tmp_str)+1);
@@ -228,28 +904,109 @@ static int ecos_update_threads(struct rtos *rtos)
int64_t thread_status = 0;
retval = target_read_buffer(rtos->target,
thread_index + param->thread_state_offset,
- 4,
+ param->state_width,
(uint8_t *)&thread_status);
if (retval != ERROR_OK) {
LOG_ERROR("Error reading thread state from eCos target");
return retval;
}
- for (i = 0; (i < ECOS_NUM_STATES) && (ecos_thread_states[i].value != thread_status); i++) {
- /*
- * empty
- */
- }
+ /* The thread_status is a BITMASK */
+ char state_desc[21]; /* Enough for "suspended+countsleep\0" maximum */
- const char *state_desc;
- if (i < ECOS_NUM_STATES)
- state_desc = ecos_thread_states[i].desc;
+ if (thread_status & SUSPENDED)
+ strcpy(state_desc, "suspended+");
else
- state_desc = "Unknown state";
+ state_desc[0] = '\0';
+
+ switch (thread_status & ~SUSPENDED) {
+ case RUNNING:
+ if (thread_index == current_thread_addr)
+ strcat(state_desc, "running");
+ else if (thread_status & SUSPENDED)
+ state_desc[9] = '\0'; /* Drop '+' from "suspended+" */
+ else
+ strcat(state_desc, "ready");
+ break;
+ case SLEEPING:
+ strcat(state_desc, "sleeping");
+ break;
+ case SLEEPSET:
+ case COUNTSLEEP:
+ strcat(state_desc, "counted sleep");
+ break;
+ case CREATING:
+ strcpy(state_desc, "creating");
+ break;
+ case EXITED:
+ strcpy(state_desc, "exited");
+ break;
+ default:
+ strcpy(state_desc, "unknown state");
+ break;
+ }
+
+ /* For the moment we do not bother decoding the wake reason for the
+ * active "running" thread, but it is useful providing the sleep reason
+ * for stacked threads. */
+ int64_t sleep_reason = 0; /* sleep reason */
+
+ if (thread_index != current_thread_addr &&
+ ecos_value(rtos, ECOS_VAL_COMMON_THREAD_SLEEP_SIZE)) {
+ retval = target_read_buffer(rtos->target,
+ (thread_index + ecos_value(rtos, ECOS_VAL_COMMON_THREAD_SLEEP_OFF)),
+ ecos_value(rtos, ECOS_VAL_COMMON_THREAD_SLEEP_SIZE),
+ (uint8_t *)&sleep_reason);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Error reading thread sleep reason from eCos target");
+ return retval;
+ }
+ if (sleep_reason < 0 ||
+ sleep_reason > (int64_t)ARRAY_SIZE(ecos_thread_reasons)) {
+ sleep_reason = 0;
+ }
+ }
+
+ /* We do not display anything for the Cyg_Thread::NONE reason */
+ size_t tr_extra = 0;
+ const char *reason_desc = NULL;
+ if (sleep_reason)
+ reason_desc = ecos_thread_reasons[sleep_reason].desc;
+ if (reason_desc)
+ tr_extra = 2 + strlen(reason_desc) + 1;
- rtos->thread_details[tasks_found].extra_info_str = malloc(strlen(
- state_desc)+8);
- sprintf(rtos->thread_details[tasks_found].extra_info_str, "State: %s", state_desc);
+ /* Display thread priority if available: */
+ int64_t priority = 0;
+ size_t pri_extra = 0;
+ if (ecos_value(rtos, ECOS_VAL_COMMON_THREAD_PRI_SIZE)) {
+ retval = target_read_buffer(rtos->target,
+ (thread_index + ecos_value(rtos, ECOS_VAL_COMMON_THREAD_PRI_OFF)),
+ ecos_value(rtos, ECOS_VAL_COMMON_THREAD_PRI_SIZE),
+ (uint8_t *)&priority);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Error reading thread priority from eCos target");
+ return retval;
+ }
+ pri_extra = (12 + 20); /* worst-case ", Priority: " */
+ }
+
+ size_t eilen = (8 + strlen(state_desc) + tr_extra + pri_extra);
+ char *eistr = malloc(eilen);
+ /* We do not need to treat a malloc failure as a fatal error here since
+ * the code below will just not report extra thread information if NULL,
+ * thus allowing all of the threads to be enumerated even with reduced
+ * information when the host is low on memory. However... */
+ if (!eistr) {
+ LOG_ERROR("OOM allocating extra information buffer");
+ return ERROR_FAIL;
+ }
+
+ int soff = snprintf(eistr, eilen, "State: %s", state_desc);
+ if (tr_extra && reason_desc)
+ soff += snprintf(&eistr[soff], (eilen - soff), " (%s)", reason_desc);
+ if (pri_extra)
+ (void)snprintf(&eistr[soff], (eilen - soff), ", Priority: %" PRId64 "", priority);
+ rtos->thread_details[tasks_found].extra_info_str = eistr;
rtos->thread_details[tasks_found].exists = true;
@@ -269,14 +1026,14 @@ static int ecos_update_threads(struct rtos *rtos)
} while (thread_index != first_thread);
rtos->thread_count = tasks_found;
- return 0;
+ return ERROR_OK;
}
static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
struct rtos_reg **reg_list, int *num_regs)
{
int retval;
- const struct ecos_params *param;
+ struct ecos_params *param;
if (!rtos)
return -1;
@@ -287,7 +1044,22 @@ static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
if (!rtos->rtos_specific_params)
return -3;
- param = (const struct ecos_params *) rtos->rtos_specific_params;
+ param = rtos->rtos_specific_params;
+
+ retval = ecos_check_app_info(rtos, param);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* We can get memory access errors reported by this function on
+ * re-connecting to a board with stale thread information in memory. The
+ * initial ecos_update_threads() is called twice and may read
+ * stale/invalid information depending on the memory state. This happens
+ * as part of the "target remote" connection so cannot be avoided by GDB
+ * scripting. It is not critical and allowing the application to run and
+ * initialise its BSS etc. will allow correct thread and register
+ * information to be obtained. This really only affects debug sessions
+ * where "info thr" is used before the initial run-time initialisation
+ * has occurred. */
/* Find the thread with that thread id */
uint16_t id = 0;
@@ -299,10 +1071,10 @@ static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
while (!done) {
retval = target_read_buffer(rtos->target,
thread_index + param->thread_uniqueid_offset,
- 2,
+ param->uid_width,
(uint8_t *)&id);
if (retval != ERROR_OK) {
- LOG_ERROR("Error reading unique id from eCos thread");
+ LOG_ERROR("Error reading unique id from eCos thread 0x%08" PRIX32 "", thread_index);
return retval;
}
@@ -328,8 +1100,24 @@ static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
return retval;
}
+ if (!stack_ptr) {
+ LOG_ERROR("NULL stack pointer in thread %" PRIu64, thread_id);
+ return -5;
+ }
+
+ const struct rtos_register_stacking *stacking_info = NULL;
+ if (param->target_stack_layout) {
+ retval = param->target_stack_layout(rtos, param, stack_ptr, &stacking_info);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Error reading stack layout for eCos thread");
+ return retval;
+ }
+ }
+ if (!stacking_info)
+ stacking_info = &rtos_ecos_cortex_m3_stacking;
+
return rtos_generic_stack_read(rtos->target,
- param->stacking_info,
+ stacking_info,
stack_ptr,
reg_list,
num_regs);
@@ -338,18 +1126,31 @@ static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
return -1;
}
+/* NOTE: This is only called once when the first GDB connection is made to
+ * OpenOCD and not on subsequent connections (when the application symbol table
+ * may have changed, affecting the offsets of critical fields and the stacked
+ * context shape). */
static int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
{
unsigned int i;
*symbol_list = calloc(
ARRAY_SIZE(ecos_symbol_list), sizeof(struct symbol_table_elem));
- for (i = 0; i < ARRAY_SIZE(ecos_symbol_list); i++)
- (*symbol_list)[i].symbol_name = ecos_symbol_list[i];
+ /* If the target reference was passed into this function we could limit
+ * the symbols we need to lookup to the target->type->name based
+ * range. For the moment we need to provide a single vector with all of
+ * the symbols across all of the supported architectures. */
+ for (i = 0; i < ARRAY_SIZE(ecos_symbol_list); i++) {
+ (*symbol_list)[i].symbol_name = ecos_symbol_list[i].name;
+ (*symbol_list)[i].optional = ecos_symbol_list[i].optional;
+ }
return 0;
}
+/* NOTE: Only called by rtos.c:rtos_qsymbol() when auto-detecting the RTOS. If
+ * the target configuration uses the explicit "-rtos" config option then this
+ * detection routine is NOT called. */
static bool ecos_detect_rtos(struct target *target)
{
if ((target->rtos->symbols) &&
@@ -360,15 +1161,67 @@ static bool ecos_detect_rtos(struct target *target)
return false;
}
+extern int rtos_thread_packet(struct connection *connection,
+ const char *packet, int packet_size);
+
+/* Since we should never have 0 as a valid eCos thread ID we use $Hg0 as the
+ * indicator of a new session as regards flushing any cached state. */
+static int ecos_packet_hook(struct connection *connection,
+ const char *packet, int packet_size)
+{
+ int64_t current_threadid;
+
+ if (packet[0] == 'H' && packet[1] == 'g') {
+ int numscan = sscanf(packet, "Hg%16" SCNx64, &current_threadid);
+ if (numscan == 1 && current_threadid == 0) {
+ struct target *target = get_target_from_connection(connection);
+ if (target && target->rtos && target->rtos->rtos_specific_params) {
+ struct ecos_params *param;
+ param = target->rtos->rtos_specific_params;
+ param->flush_common = true;
+ }
+ }
+ }
+
+ return rtos_thread_packet(connection, packet, packet_size);
+}
+
+/* Called at start of day when eCos detected or specified in config file. */
static int ecos_create(struct target *target)
{
- for (unsigned int i = 0; i < ARRAY_SIZE(ecos_params_list); i++)
- if (strcmp(ecos_params_list[i].target_name, target->type->name) == 0) {
- target->rtos->rtos_specific_params = (void *)&ecos_params_list[i];
- target->rtos->current_thread = 0;
- target->rtos->thread_details = NULL;
- return 0;
+ for (unsigned int i = 0; i < ARRAY_SIZE(ecos_params_list); i++) {
+ const char * const *tnames = ecos_params_list[i].target_names;
+ while (*tnames) {
+ if (strcmp(*tnames, target->type->name) == 0) {
+ /* LOG_DEBUG("eCos: matched target \"%s\"", target->type->name); */
+ target->rtos->rtos_specific_params = (void *)&ecos_params_list[i];
+ ecos_params_list[i].flush_common = true;
+ ecos_params_list[i].stacking_info = NULL;
+ target->rtos->current_thread = 0;
+ target->rtos->thread_details = NULL;
+
+ /* We use the $Hg0 packet as a new GDB connection "start-of-day" hook to
+ * force a re-cache of information. It is possible for a single OpenOCD
+ * session to be connected to a target with multiple GDB debug sessions
+ * started/stopped. With eCos it is possible for those GDB sessions to
+ * present applications with different offsets within a thread
+ * descriptor for fields used by this module, and for the stacked
+ * context within the connected target architecture to differ between
+ * applications and even between threads in a single application. So we
+ * need to ensure any information we cache is flushed on an application
+ * change, and GDB referencing an invalid eCos thread ID (0) is a good
+ * enough point, since we can accept the re-cache hit if that packet
+ * appears during an established session, whilst benefiting from not
+ * re-loading information on every update_threads or get_thread_reg_list
+ * call. */
+ target->rtos->gdb_thread_packet = ecos_packet_hook;
+ /* We do not currently use the target->rtos->gdb_target_for_threadid
+ * hook. */
+ return 0;
+ }
+ tnames++;
}
+ }
LOG_ERROR("Could not find target in eCos compatibility list");
return -1;
diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c
index 5e60c61..eac72fc 100644
--- a/src/rtos/hwthread.c
+++ b/src/rtos/hwthread.c
@@ -87,6 +87,7 @@ 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 */
enum target_debug_reason current_reason = DBG_REASON_UNDEFINED;
if (!rtos)
@@ -108,10 +109,14 @@ static int hwthread_update_threads(struct rtos *rtos)
} else
thread_list_size = 1;
- /* Wipe out previous thread details if any, but preserve threadid. */
- int64_t current_threadid = rtos->current_threadid;
- rtos_free_threadlist(rtos);
- rtos->current_threadid = current_threadid;
+ /* restore the threadid which is currently selected by GDB
+ * because rtos_free_threadlist() wipes out it
+ * (GDB thread id is 1-based indexing) */
+ if (current_threadid <= thread_list_size)
+ rtos->current_threadid = current_threadid;
+ else
+ LOG_WARNING("SMP node change, disconnect GDB from core/thread %" PRId64,
+ current_threadid);
/* create space for new thread details */
rtos->thread_details = malloc(sizeof(struct thread_detail) * thread_list_size);
@@ -264,10 +269,19 @@ static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
for (int i = 0; i < reg_list_size; i++) {
if (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden)
continue;
- (*rtos_reg_list)[j].number = (*reg_list)[i].number;
- (*rtos_reg_list)[j].size = (*reg_list)[i].size;
- memcpy((*rtos_reg_list)[j].value, (*reg_list)[i].value,
- ((*reg_list)[i].size + 7) / 8);
+ if (!reg_list[i]->valid) {
+ retval = reg_list[i]->type->get(reg_list[i]);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Couldn't get register %s.", reg_list[i]->name);
+ free(reg_list);
+ free(*rtos_reg_list);
+ return retval;
+ }
+ }
+ (*rtos_reg_list)[j].number = reg_list[i]->number;
+ (*rtos_reg_list)[j].size = reg_list[i]->size;
+ memcpy((*rtos_reg_list)[j].value, reg_list[i]->value,
+ DIV_ROUND_UP(reg_list[i]->size, 8));
j++;
}
free(reg_list);
diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c
index 0f54e86..86e1765 100644
--- a/src/rtos/rtos_ecos_stackings.c
+++ b/src/rtos/rtos_ecos_stackings.c
@@ -8,6 +8,13 @@
#include "rtos_standard_stackings.h"
#include "target/armv7m.h"
+/* For Cortex-M eCos applications the actual thread context register layout can
+ * be different between active threads of an application depending on whether
+ * the FPU is in use, configured for lazy FPU context saving, etc. */
+
+/* Default fixed thread register context description used for older eCos
+ * application builds without the necessary symbolic information describing the
+ * actual configuration-dependent offsets. */
static const struct stack_register_offset rtos_ecos_cortex_m3_stack_offsets[ARMV7M_NUM_CORE_REGS] = {
{ ARMV7M_R0, 0x0c, 32 }, /* r0 */
{ ARMV7M_R1, 0x10, 32 }, /* r1 */
diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c
index f2b4e15..7f0c3c7 100644
--- a/src/rtos/rtos_standard_stackings.c
+++ b/src/rtos/rtos_standard_stackings.c
@@ -103,45 +103,6 @@ static const struct stack_register_offset rtos_standard_cortex_r4_stack_offsets[
{ 26, 0x04, 32 }, /* CSPR */
};
-static const struct stack_register_offset rtos_standard_nds32_n1068_stack_offsets[] = {
- { 0, 0x88, 32 }, /* R0 */
- { 1, 0x8C, 32 }, /* R1 */
- { 2, 0x14, 32 }, /* R2 */
- { 3, 0x18, 32 }, /* R3 */
- { 4, 0x1C, 32 }, /* R4 */
- { 5, 0x20, 32 }, /* R5 */
- { 6, 0x24, 32 }, /* R6 */
- { 7, 0x28, 32 }, /* R7 */
- { 8, 0x2C, 32 }, /* R8 */
- { 9, 0x30, 32 }, /* R9 */
- { 10, 0x34, 32 }, /* R10 */
- { 11, 0x38, 32 }, /* R11 */
- { 12, 0x3C, 32 }, /* R12 */
- { 13, 0x40, 32 }, /* R13 */
- { 14, 0x44, 32 }, /* R14 */
- { 15, 0x48, 32 }, /* R15 */
- { 16, 0x4C, 32 }, /* R16 */
- { 17, 0x50, 32 }, /* R17 */
- { 18, 0x54, 32 }, /* R18 */
- { 19, 0x58, 32 }, /* R19 */
- { 20, 0x5C, 32 }, /* R20 */
- { 21, 0x60, 32 }, /* R21 */
- { 22, 0x64, 32 }, /* R22 */
- { 23, 0x68, 32 }, /* R23 */
- { 24, 0x6C, 32 }, /* R24 */
- { 25, 0x70, 32 }, /* R25 */
- { 26, 0x74, 32 }, /* R26 */
- { 27, 0x78, 32 }, /* R27 */
- { 28, 0x7C, 32 }, /* R28 */
- { 29, 0x80, 32 }, /* R29 */
- { 30, 0x84, 32 }, /* R30 (LP) */
- { 31, 0x00, 32 }, /* R31 (SP) */
- { 32, 0x04, 32 }, /* PSW */
- { 33, 0x08, 32 }, /* IPC */
- { 34, 0x0C, 32 }, /* IPSW */
- { 35, 0x10, 32 }, /* IFC_LP */
-};
-
static const struct stack_register_offset rtos_metal_rv32_stack_offsets[] = {
/* zero isn't on the stack. By making its offset -1 we leave the value at 0
* inside rtos_generic_stack_read(). */
@@ -436,14 +397,6 @@ const struct rtos_register_stacking rtos_standard_cortex_r4_stacking = {
.register_offsets = rtos_standard_cortex_r4_stack_offsets
};
-const struct rtos_register_stacking rtos_standard_nds32_n1068_stacking = {
- .stack_registers_size = 0x90,
- .stack_growth_direction = -1,
- .num_output_registers = 32,
- .calculate_process_stack = rtos_generic_stack_align8,
- .register_offsets = rtos_standard_nds32_n1068_stack_offsets
-};
-
const struct rtos_register_stacking rtos_metal_rv32_stacking = {
.stack_registers_size = (32 + 2) * 4,
.stack_growth_direction = -1,
diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h
index 455acc4..70ea034 100644
--- a/src/rtos/rtos_standard_stackings.h
+++ b/src/rtos/rtos_standard_stackings.h
@@ -18,7 +18,6 @@ extern const struct rtos_register_stacking rtos_standard_cortex_m3_stacking;
extern const struct rtos_register_stacking rtos_standard_cortex_m4f_stacking;
extern const struct rtos_register_stacking rtos_standard_cortex_m4f_fpu_stacking;
extern const struct rtos_register_stacking rtos_standard_cortex_r4_stacking;
-extern const struct rtos_register_stacking rtos_standard_nds32_n1068_stacking;
target_addr_t rtos_generic_stack_align8(struct target *target,
const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
target_addr_t stack_ptr);
diff --git a/src/target/Makefile.am b/src/target/Makefile.am
index 4687092..2084de6 100644
--- a/src/target/Makefile.am
+++ b/src/target/Makefile.am
@@ -19,7 +19,6 @@ noinst_LTLIBRARIES += %D%/libtarget.la
$(ARM_MISC_SRC) \
$(AVR32_SRC) \
$(MIPS32_SRC) \
- $(NDS32_SRC) \
$(STM8_SRC) \
$(INTEL_IA32_SRC) \
$(ESIRISC_SRC) \
@@ -134,18 +133,6 @@ MIPS64_SRC = \
%D%/trace.c \
%D%/mips_ejtag.c
-NDS32_SRC = \
- %D%/nds32.c \
- %D%/nds32_reg.c \
- %D%/nds32_cmd.c \
- %D%/nds32_disassembler.c \
- %D%/nds32_tlb.c \
- %D%/nds32_v2.c \
- %D%/nds32_v3_common.c \
- %D%/nds32_v3.c \
- %D%/nds32_v3m.c \
- %D%/nds32_aice.c
-
STM8_SRC = \
%D%/stm8.c
@@ -235,18 +222,6 @@ ARC_SRC = \
%D%/avr32_jtag.h \
%D%/avr32_mem.h \
%D%/avr32_regs.h \
- %D%/nds32.h \
- %D%/nds32_cmd.h \
- %D%/nds32_disassembler.h \
- %D%/nds32_edm.h \
- %D%/nds32_insn.h \
- %D%/nds32_reg.h \
- %D%/nds32_tlb.h \
- %D%/nds32_v2.h \
- %D%/nds32_v3_common.h \
- %D%/nds32_v3.h \
- %D%/nds32_v3m.h \
- %D%/nds32_aice.h \
%D%/semihosting_common.h \
%D%/stm8.h \
%D%/lakemont.h \
@@ -265,4 +240,4 @@ ARC_SRC = \
include %D%/openrisc/Makefile.am
include %D%/riscv/Makefile.am
include %D%/xtensa/Makefile.am
-include %D%/espressif/Makefile.am \ No newline at end of file
+include %D%/espressif/Makefile.am
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 8592daa..8e90e64 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -2546,23 +2546,20 @@ static int aarch64_examine_first(struct target *target)
if (!pc)
return ERROR_FAIL;
- if (armv8->debug_ap) {
- dap_put_ap(armv8->debug_ap);
- armv8->debug_ap = NULL;
- }
-
- if (pc->adiv5_config.ap_num == DP_APSEL_INVALID) {
- /* Search for the APB-AB */
- retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);
- if (retval != ERROR_OK) {
- LOG_ERROR("Could not find APB-AP for debug access");
- return retval;
- }
- } else {
- armv8->debug_ap = dap_get_ap(swjdp, pc->adiv5_config.ap_num);
- if (!armv8->debug_ap) {
- LOG_ERROR("Cannot get AP");
- return ERROR_FAIL;
+ if (!armv8->debug_ap) {
+ if (pc->adiv5_config.ap_num == DP_APSEL_INVALID) {
+ /* Search for the APB-AB */
+ retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Could not find APB-AP for debug access");
+ return retval;
+ }
+ } else {
+ armv8->debug_ap = dap_get_ap(swjdp, pc->adiv5_config.ap_num);
+ if (!armv8->debug_ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
}
diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c
index 979c643..aea730d 100644
--- a/src/target/adi_v5_swd.c
+++ b/src/target/adi_v5_swd.c
@@ -177,6 +177,19 @@ static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr
assert(dap_is_multidrop(dap));
swd_send_sequence(dap, LINE_RESET);
+ /* From ARM IHI 0074C ADIv6.0, chapter B4.3.3 "Connection and line reset
+ * sequence":
+ * - line reset sets DP_SELECT_DPBANK to zero;
+ * - read of DP_DPIDR takes the connection out of reset;
+ * - write of DP_TARGETSEL keeps the connection in reset;
+ * - other accesses return protocol error (SWDIO not driven by target).
+ *
+ * Read DP_DPIDR to get out of reset. Initialize dap->select to zero to
+ * skip the write to DP_SELECT, avoiding the protocol error. Set again
+ * dap->select to DP_SELECT_INVALID because the rest of the register is
+ * unknown after line reset.
+ */
+ dap->select = 0;
retval = swd_queue_dp_write_inner(dap, DP_TARGETSEL, dap->multidrop_targetsel);
if (retval != ERROR_OK)
@@ -196,6 +209,8 @@ static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr
return retval;
}
+ dap->select = DP_SELECT_INVALID;
+
retval = swd_queue_dp_read_inner(dap, DP_DLPIDR, &dlpidr);
if (retval != ERROR_OK)
return retval;
@@ -257,6 +272,8 @@ static int swd_multidrop_select(struct adiv5_dap *dap)
LOG_DEBUG("Failed to select multidrop %s, retrying...",
adiv5_dap_name(dap));
+ /* we going to retry localy, do not ask for full reconnect */
+ dap->do_reconnect = false;
}
return retval;
@@ -342,6 +359,7 @@ static int swd_connect_single(struct adiv5_dap *dap)
dap->switch_through_dormant = !dap->switch_through_dormant;
} while (timeval_ms() < timeout);
+
dap->select = DP_SELECT_INVALID;
if (retval != ERROR_OK) {
diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index c446428..da5da31 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -113,7 +113,7 @@ static int mem_ap_setup_tar(struct adiv5_ap *ap, target_addr_t tar)
int retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR(ap->dap), (uint32_t)(tar & 0xffffffffUL));
if (retval == ERROR_OK && is_64bit_ap(ap)) {
/* See if bits 63:32 of tar is different from last setting */
- if ((ap->tar_value >> 32) != (tar >> 32))
+ if (!ap->tar_valid || (ap->tar_value >> 32) != (tar >> 32))
retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR64(ap->dap), (uint32_t)(tar >> 32));
}
if (retval != ERROR_OK) {
diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index 2db2ce2..1b85315 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -116,27 +116,27 @@ static const struct {
{ ARMV7M_FAULTMASK, "faultmask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
{ ARMV7M_CONTROL, "control", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
- /* ARMv8-M specific registers */
- { ARMV8M_MSP_NS, "msp_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
- { ARMV8M_PSP_NS, "psp_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
- { ARMV8M_MSP_S, "msp_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
- { ARMV8M_PSP_S, "psp_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
- { ARMV8M_MSPLIM_S, "msplim_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
- { ARMV8M_PSPLIM_S, "psplim_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
- { ARMV8M_MSPLIM_NS, "msplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
- { ARMV8M_PSPLIM_NS, "psplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" },
+ /* ARMv8-M security extension (TrustZone) specific registers */
+ { ARMV8M_MSP_NS, "msp_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_PSP_NS, "psp_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_MSP_S, "msp_s", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_PSP_S, "psp_s", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_MSPLIM_S, "msplim_s", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_PSPLIM_S, "psplim_s", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_MSPLIM_NS, "msplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_PSPLIM_NS, "psplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext" },
{ ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S, "pmsk_bpri_fltmsk_ctrl_s", 32, REG_TYPE_INT, NULL, NULL },
- { ARMV8M_PRIMASK_S, "primask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
- { ARMV8M_BASEPRI_S, "basepri_s", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
- { ARMV8M_FAULTMASK_S, "faultmask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
- { ARMV8M_CONTROL_S, "control_s", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+ { ARMV8M_PRIMASK_S, "primask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_BASEPRI_S, "basepri_s", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_FAULTMASK_S, "faultmask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_CONTROL_S, "control_s", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" },
{ ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS, "pmsk_bpri_fltmsk_ctrl_ns", 32, REG_TYPE_INT, NULL, NULL },
- { ARMV8M_PRIMASK_NS, "primask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
- { ARMV8M_BASEPRI_NS, "basepri_ns", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
- { ARMV8M_FAULTMASK_NS, "faultmask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
- { ARMV8M_CONTROL_NS, "control_ns", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" },
+ { ARMV8M_PRIMASK_NS, "primask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_BASEPRI_NS, "basepri_ns", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_FAULTMASK_NS, "faultmask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" },
+ { ARMV8M_CONTROL_NS, "control_ns", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.secext" },
/* FPU registers */
{ ARMV7M_D0, "d0", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" },
@@ -182,8 +182,11 @@ int armv7m_restore_context(struct target *target)
for (i = cache->num_regs - 1; i >= 0; i--) {
struct reg *r = &cache->reg_list[i];
- if (r->exist && r->dirty)
- armv7m->arm.write_core_reg(target, r, i, ARM_MODE_ANY, r->value);
+ if (r->exist && r->dirty) {
+ int retval = armv7m->arm.write_core_reg(target, r, i, ARM_MODE_ANY, r->value);
+ if (retval != ERROR_OK)
+ return retval;
+ }
}
return ERROR_OK;
@@ -528,11 +531,17 @@ int armv7m_start_algorithm(struct target *target,
/* Store all non-debug execution registers to armv7m_algorithm_info context */
for (unsigned i = 0; i < armv7m->arm.core_cache->num_regs; i++) {
+ struct reg *reg = &armv7m->arm.core_cache->reg_list[i];
+ if (!reg->exist)
+ continue;
- armv7m_algorithm_info->context[i] = buf_get_u32(
- armv7m->arm.core_cache->reg_list[i].value,
- 0,
- 32);
+ if (!reg->valid)
+ armv7m_get_core_reg(reg);
+
+ if (!reg->valid)
+ LOG_TARGET_WARNING(target, "Storing invalid register %s", reg->name);
+
+ armv7m_algorithm_info->context[i] = buf_get_u32(reg->value, 0, 32);
}
for (int i = 0; i < num_mem_params; i++) {
@@ -685,16 +694,19 @@ int armv7m_wait_algorithm(struct target *target,
}
for (int i = armv7m->arm.core_cache->num_regs - 1; i >= 0; i--) {
+ struct reg *reg = &armv7m->arm.core_cache->reg_list[i];
+ if (!reg->exist)
+ continue;
+
uint32_t regvalue;
- regvalue = buf_get_u32(armv7m->arm.core_cache->reg_list[i].value, 0, 32);
+ regvalue = buf_get_u32(reg->value, 0, 32);
if (regvalue != armv7m_algorithm_info->context[i]) {
LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
- armv7m->arm.core_cache->reg_list[i].name,
- armv7m_algorithm_info->context[i]);
- buf_set_u32(armv7m->arm.core_cache->reg_list[i].value,
+ reg->name, armv7m_algorithm_info->context[i]);
+ buf_set_u32(reg->value,
0, 32, armv7m_algorithm_info->context[i]);
- armv7m->arm.core_cache->reg_list[i].valid = true;
- armv7m->arm.core_cache->reg_list[i].dirty = true;
+ reg->valid = true;
+ reg->dirty = true;
}
}
@@ -726,8 +738,9 @@ int armv7m_arch_state(struct target *target)
ctrl = buf_get_u32(arm->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 32);
sp = buf_get_u32(arm->core_cache->reg_list[ARMV7M_R13].value, 0, 32);
- LOG_USER("target halted due to %s, current mode: %s %s\n"
+ LOG_USER("[%s] halted due to %s, current mode: %s %s\n"
"xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32 "%s%s",
+ target_name(target),
debug_reason_name(target),
arm_mode_name(arm->core_mode),
armv7m_exception_string(armv7m->exception_number),
diff --git a/src/target/armv8.c b/src/target/armv8.c
index de0bddb..ff71a8e 100644
--- a/src/target/armv8.c
+++ b/src/target/armv8.c
@@ -114,6 +114,166 @@ const char *armv8_mode_name(unsigned psr_mode)
return "UNRECOGNIZED";
}
+static uint8_t armv8_pa_size(uint32_t ps)
+{
+ uint8_t ret = 0;
+ switch (ps) {
+ case 0:
+ ret = 32;
+ break;
+ case 1:
+ ret = 36;
+ break;
+ case 2:
+ ret = 40;
+ break;
+ case 3:
+ ret = 42;
+ break;
+ case 4:
+ ret = 44;
+ break;
+ case 5:
+ ret = 48;
+ break;
+ default:
+ LOG_INFO("Unknown physical address size");
+ break;
+ }
+ return ret;
+}
+
+static __attribute__((unused)) int armv8_read_ttbcr32(struct target *target)
+{
+ struct armv8_common *armv8 = target_to_armv8(target);
+ struct arm_dpm *dpm = armv8->arm.dpm;
+ uint32_t ttbcr, ttbcr_n;
+ int retval = dpm->prepare(dpm);
+ if (retval != ERROR_OK)
+ goto done;
+ /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
+ retval = dpm->instr_read_data_r0(dpm,
+ ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
+ &ttbcr);
+ if (retval != ERROR_OK)
+ goto done;
+
+ LOG_DEBUG("ttbcr %" PRIx32, ttbcr);
+
+ ttbcr_n = ttbcr & 0x7;
+ armv8->armv8_mmu.ttbcr = ttbcr;
+
+ /*
+ * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition),
+ * document # ARM DDI 0406C
+ */
+ armv8->armv8_mmu.ttbr_range[0] = 0xffffffff >> ttbcr_n;
+ armv8->armv8_mmu.ttbr_range[1] = 0xffffffff;
+ armv8->armv8_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n);
+ armv8->armv8_mmu.ttbr_mask[1] = 0xffffffff << 14;
+
+ LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32 " ttbr1_mask %" PRIx32,
+ (ttbcr_n != 0) ? "used" : "not used",
+ armv8->armv8_mmu.ttbr_mask[0],
+ armv8->armv8_mmu.ttbr_mask[1]);
+
+done:
+ dpm->finish(dpm);
+ return retval;
+}
+
+static int armv8_read_ttbcr(struct target *target)
+{
+ struct armv8_common *armv8 = target_to_armv8(target);
+ struct arm_dpm *dpm = armv8->arm.dpm;
+ struct arm *arm = &armv8->arm;
+ uint32_t ttbcr;
+ uint64_t ttbcr_64;
+
+ int retval = dpm->prepare(dpm);
+ if (retval != ERROR_OK)
+ goto done;
+
+ /* clear ttrr1_used and ttbr0_mask */
+ memset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used));
+ memset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask));
+
+ switch (armv8_curel_from_core_mode(arm->core_mode)) {
+ case SYSTEM_CUREL_EL3:
+ retval = dpm->instr_read_data_r0(dpm,
+ ARMV8_MRS(SYSTEM_TCR_EL3, 0),
+ &ttbcr);
+ retval += dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_TTBR0_EL3, 0),
+ &armv8->ttbr_base);
+ if (retval != ERROR_OK)
+ goto done;
+ armv8->va_size = 64 - (ttbcr & 0x3F);
+ armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
+ armv8->page_size = (ttbcr >> 14) & 3;
+ break;
+ case SYSTEM_CUREL_EL2:
+ retval = dpm->instr_read_data_r0(dpm,
+ ARMV8_MRS(SYSTEM_TCR_EL2, 0),
+ &ttbcr);
+ retval += dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_TTBR0_EL2, 0),
+ &armv8->ttbr_base);
+ if (retval != ERROR_OK)
+ goto done;
+ armv8->va_size = 64 - (ttbcr & 0x3F);
+ armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
+ armv8->page_size = (ttbcr >> 14) & 3;
+ break;
+ case SYSTEM_CUREL_EL0:
+ armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);
+ /* fall through */
+ case SYSTEM_CUREL_EL1:
+ retval = dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_TCR_EL1, 0),
+ &ttbcr_64);
+ armv8->va_size = 64 - (ttbcr_64 & 0x3F);
+ armv8->pa_size = armv8_pa_size((ttbcr_64 >> 32) & 7);
+ armv8->page_size = (ttbcr_64 >> 14) & 3;
+ armv8->armv8_mmu.ttbr1_used = (((ttbcr_64 >> 16) & 0x3F) != 0) ? 1 : 0;
+ armv8->armv8_mmu.ttbr0_mask = 0x0000FFFFFFFFFFFF;
+ retval += dpm->instr_read_data_r0_64(dpm,
+ ARMV8_MRS(SYSTEM_TTBR0_EL1 | (armv8->armv8_mmu.ttbr1_used), 0),
+ &armv8->ttbr_base);
+ if (retval != ERROR_OK)
+ goto done;
+ break;
+ default:
+ LOG_ERROR("unknown core state");
+ retval = ERROR_FAIL;
+ break;
+ }
+ if (retval != ERROR_OK)
+ goto done;
+
+ if (armv8->armv8_mmu.ttbr1_used == 1)
+ LOG_INFO("TTBR0 access above %" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask));
+
+done:
+ armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
+ dpm->finish(dpm);
+ return retval;
+}
+
+static int armv8_get_pauth_mask(struct armv8_common *armv8, uint64_t *mask)
+{
+ struct arm *arm = &armv8->arm;
+ int retval = ERROR_OK;
+ if (armv8->va_size == 0)
+ retval = armv8_read_ttbcr(arm->target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ *mask = ~(((uint64_t)1 << armv8->va_size) - 1);
+
+ return retval;
+}
+
static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regval)
{
struct arm_dpm *dpm = &armv8->dpm;
@@ -191,6 +351,10 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv
ARMV8_MRS(SYSTEM_SPSR_EL3, 0), &value);
value_64 = value;
break;
+ case ARMV8_PAUTH_CMASK:
+ case ARMV8_PAUTH_DMASK:
+ retval = armv8_get_pauth_mask(armv8, &value_64);
+ break;
default:
retval = ERROR_FAIL;
break;
@@ -772,152 +936,6 @@ static __attribute__((unused)) void armv8_show_fault_registers(struct target *ta
armv8_show_fault_registers32(armv8);
}
-static uint8_t armv8_pa_size(uint32_t ps)
-{
- uint8_t ret = 0;
- switch (ps) {
- case 0:
- ret = 32;
- break;
- case 1:
- ret = 36;
- break;
- case 2:
- ret = 40;
- break;
- case 3:
- ret = 42;
- break;
- case 4:
- ret = 44;
- break;
- case 5:
- ret = 48;
- break;
- default:
- LOG_INFO("Unknown physical address size");
- break;
- }
- return ret;
-}
-
-static __attribute__((unused)) int armv8_read_ttbcr32(struct target *target)
-{
- struct armv8_common *armv8 = target_to_armv8(target);
- struct arm_dpm *dpm = armv8->arm.dpm;
- uint32_t ttbcr, ttbcr_n;
- int retval = dpm->prepare(dpm);
- if (retval != ERROR_OK)
- goto done;
- /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
- retval = dpm->instr_read_data_r0(dpm,
- ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
- &ttbcr);
- if (retval != ERROR_OK)
- goto done;
-
- LOG_DEBUG("ttbcr %" PRIx32, ttbcr);
-
- ttbcr_n = ttbcr & 0x7;
- armv8->armv8_mmu.ttbcr = ttbcr;
-
- /*
- * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition),
- * document # ARM DDI 0406C
- */
- armv8->armv8_mmu.ttbr_range[0] = 0xffffffff >> ttbcr_n;
- armv8->armv8_mmu.ttbr_range[1] = 0xffffffff;
- armv8->armv8_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n);
- armv8->armv8_mmu.ttbr_mask[1] = 0xffffffff << 14;
-
- LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32 " ttbr1_mask %" PRIx32,
- (ttbcr_n != 0) ? "used" : "not used",
- armv8->armv8_mmu.ttbr_mask[0],
- armv8->armv8_mmu.ttbr_mask[1]);
-
-done:
- dpm->finish(dpm);
- return retval;
-}
-
-static __attribute__((unused)) int armv8_read_ttbcr(struct target *target)
-{
- struct armv8_common *armv8 = target_to_armv8(target);
- struct arm_dpm *dpm = armv8->arm.dpm;
- struct arm *arm = &armv8->arm;
- uint32_t ttbcr;
- uint64_t ttbcr_64;
-
- int retval = dpm->prepare(dpm);
- if (retval != ERROR_OK)
- goto done;
-
- /* clear ttrr1_used and ttbr0_mask */
- memset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used));
- memset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask));
-
- switch (armv8_curel_from_core_mode(arm->core_mode)) {
- case SYSTEM_CUREL_EL3:
- retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS(SYSTEM_TCR_EL3, 0),
- &ttbcr);
- retval += dpm->instr_read_data_r0_64(dpm,
- ARMV8_MRS(SYSTEM_TTBR0_EL3, 0),
- &armv8->ttbr_base);
- if (retval != ERROR_OK)
- goto done;
- armv8->va_size = 64 - (ttbcr & 0x3F);
- armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
- armv8->page_size = (ttbcr >> 14) & 3;
- break;
- case SYSTEM_CUREL_EL2:
- retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS(SYSTEM_TCR_EL2, 0),
- &ttbcr);
- retval += dpm->instr_read_data_r0_64(dpm,
- ARMV8_MRS(SYSTEM_TTBR0_EL2, 0),
- &armv8->ttbr_base);
- if (retval != ERROR_OK)
- goto done;
- armv8->va_size = 64 - (ttbcr & 0x3F);
- armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
- armv8->page_size = (ttbcr >> 14) & 3;
- break;
- case SYSTEM_CUREL_EL0:
- armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);
- /* fall through */
- case SYSTEM_CUREL_EL1:
- retval = dpm->instr_read_data_r0_64(dpm,
- ARMV8_MRS(SYSTEM_TCR_EL1, 0),
- &ttbcr_64);
- armv8->va_size = 64 - (ttbcr_64 & 0x3F);
- armv8->pa_size = armv8_pa_size((ttbcr_64 >> 32) & 7);
- armv8->page_size = (ttbcr_64 >> 14) & 3;
- armv8->armv8_mmu.ttbr1_used = (((ttbcr_64 >> 16) & 0x3F) != 0) ? 1 : 0;
- armv8->armv8_mmu.ttbr0_mask = 0x0000FFFFFFFFFFFF;
- retval += dpm->instr_read_data_r0_64(dpm,
- ARMV8_MRS(SYSTEM_TTBR0_EL1 | (armv8->armv8_mmu.ttbr1_used), 0),
- &armv8->ttbr_base);
- if (retval != ERROR_OK)
- goto done;
- break;
- default:
- LOG_ERROR("unknown core state");
- retval = ERROR_FAIL;
- break;
- }
- if (retval != ERROR_OK)
- goto done;
-
- if (armv8->armv8_mmu.ttbr1_used == 1)
- LOG_INFO("TTBR0 access above %" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask));
-
-done:
- armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
- dpm->finish(dpm);
- return retval;
-}
-
/* method adapted to cortex A : reused arm v4 v5 method*/
int armv8_mmu_translate_va(struct target *target, target_addr_t va, target_addr_t *val)
{
@@ -1083,6 +1101,15 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command)
return ERROR_OK;
}
+COMMAND_HANDLER(armv8_pauth_command)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ struct armv8_common *armv8 = target_to_armv8(target);
+ return CALL_COMMAND_HANDLER(handle_command_parse_bool,
+ &armv8->enable_pauth,
+ "pauth feature");
+}
+
int armv8_handle_cache_info_command(struct command_invocation *cmd,
struct armv8_cache_common *armv8_cache)
{
@@ -1421,6 +1448,8 @@ static const struct {
NULL},
{ ARMV8_SPSR_EL3, "SPSR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
NULL},
+ { ARMV8_PAUTH_DMASK, "pauth_dmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL},
+ { ARMV8_PAUTH_CMASK, "pauth_cmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL},
};
static const struct {
@@ -1650,6 +1679,9 @@ struct reg_cache *armv8_build_reg_cache(struct target *target)
*reg_list[i].reg_data_type = *armv8_regs[i].data_type;
} else
LOG_ERROR("unable to allocate reg type list");
+
+ if (i == ARMV8_PAUTH_CMASK || i == ARMV8_PAUTH_DMASK)
+ reg_list[i].hidden = !armv8->enable_pauth;
}
arm->cpsr = reg_list + ARMV8_XPSR;
@@ -1745,6 +1777,17 @@ const struct command_registration armv8_command_handlers[] = {
.help = "configure exception catch",
.usage = "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
},
+ {
+ .name = "pauth",
+ .handler = armv8_pauth_command,
+ .mode = COMMAND_CONFIG,
+ .help = "enable or disable providing GDB with an 8-bytes mask to "
+ "remove signature bits added by pointer authentication."
+ "Pointer authentication feature is broken until gdb 12.1, going to be fixed. "
+ "Consider using a newer version of gdb if you want enable "
+ "pauth feature.",
+ .usage = "[on|off]",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/armv8.h b/src/target/armv8.h
index 2ed3a65..54aa086 100644
--- a/src/target/armv8.h
+++ b/src/target/armv8.h
@@ -98,6 +98,10 @@ enum {
ARMV8_ESR_EL3 = 75,
ARMV8_SPSR_EL3 = 76,
+ /* Pseudo registers defined by GDB to remove the pauth signature. */
+ ARMV8_PAUTH_DMASK = 77,
+ ARMV8_PAUTH_CMASK = 78,
+
ARMV8_LAST_REG,
};
@@ -205,6 +209,9 @@ struct armv8_common {
struct arm_cti *cti;
+ /* True if OpenOCD provides pointer auth related info to GDB */
+ bool enable_pauth;
+
/* last run-control command issued to this target (resume, halt, step) */
enum run_control_op last_run_control_op;
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 7286a30..3db9c62 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -2246,7 +2246,7 @@ static int cortex_a_write_cpu_memory(struct target *target,
/* Switch to non-blocking mode if not already in that mode. */
retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr);
if (retval != ERROR_OK)
- goto out;
+ return retval;
/* Mark R0 as dirty. */
arm_reg_current(arm, 0)->dirty = true;
@@ -2254,16 +2254,16 @@ static int cortex_a_write_cpu_memory(struct target *target,
/* Read DFAR and DFSR, as they will be modified in the event of a fault. */
retval = cortex_a_read_dfar_dfsr(target, &orig_dfar, &orig_dfsr, &dscr);
if (retval != ERROR_OK)
- goto out;
+ return retval;
/* Get the memory address into R0. */
retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DTRRX, address);
if (retval != ERROR_OK)
- goto out;
+ return retval;
retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr);
if (retval != ERROR_OK)
- goto out;
+ return retval;
if (size == 4 && (address % 4) == 0) {
/* We are doing a word-aligned transfer, so use fast mode. */
@@ -2288,7 +2288,6 @@ static int cortex_a_write_cpu_memory(struct target *target,
retval = cortex_a_write_cpu_memory_slow(target, size, count, buffer, &dscr);
}
-out:
final_retval = retval;
/* Switch to non-blocking mode if not already in that mode. */
@@ -2564,7 +2563,7 @@ static int cortex_a_read_cpu_memory(struct target *target,
/* Switch to non-blocking mode if not already in that mode. */
retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr);
if (retval != ERROR_OK)
- goto out;
+ return retval;
/* Mark R0 as dirty. */
arm_reg_current(arm, 0)->dirty = true;
@@ -2572,16 +2571,16 @@ static int cortex_a_read_cpu_memory(struct target *target,
/* Read DFAR and DFSR, as they will be modified in the event of a fault. */
retval = cortex_a_read_dfar_dfsr(target, &orig_dfar, &orig_dfsr, &dscr);
if (retval != ERROR_OK)
- goto out;
+ return retval;
/* Get the memory address into R0. */
retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DTRRX, address);
if (retval != ERROR_OK)
- goto out;
+ return retval;
retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr);
if (retval != ERROR_OK)
- goto out;
+ return retval;
if (size == 4 && (address % 4) == 0) {
/* We are doing a word-aligned transfer, so use fast mode. */
@@ -2607,7 +2606,6 @@ static int cortex_a_read_cpu_memory(struct target *target,
retval = cortex_a_read_cpu_memory_slow(target, size, count, buffer, &dscr);
}
-out:
final_retval = retval;
/* Switch to non-blocking mode if not already in that mode. */
@@ -2874,23 +2872,20 @@ static int cortex_a_examine_first(struct target *target)
int retval = ERROR_OK;
uint32_t didr, cpuid, dbg_osreg, dbg_idpfr1;
- if (armv7a->debug_ap) {
- dap_put_ap(armv7a->debug_ap);
- armv7a->debug_ap = NULL;
- }
-
- if (pc->ap_num == DP_APSEL_INVALID) {
- /* Search for the APB-AP - it is needed for access to debug registers */
- retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap);
- if (retval != ERROR_OK) {
- LOG_ERROR("Could not find APB-AP for debug access");
- return retval;
- }
- } else {
- armv7a->debug_ap = dap_get_ap(swjdp, pc->ap_num);
- if (!armv7a->debug_ap) {
- LOG_ERROR("Cannot get AP");
- return ERROR_FAIL;
+ if (!armv7a->debug_ap) {
+ if (pc->ap_num == DP_APSEL_INVALID) {
+ /* Search for the APB-AP - it is needed for access to debug registers */
+ retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Could not find APB-AP for debug access");
+ return retval;
+ }
+ } else {
+ armv7a->debug_ap = dap_get_ap(swjdp, pc->ap_num);
+ if (!armv7a->debug_ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
}
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 23d9065..88e9bb2 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -28,6 +28,7 @@
#include "register.h"
#include "arm_opcodes.h"
#include "arm_semihosting.h"
+#include "smp.h"
#include <helper/time_support.h>
#include <rtt/rtt.h>
@@ -871,7 +872,7 @@ static int cortex_m_debug_entry(struct target *target)
return ERROR_OK;
}
-static int cortex_m_poll(struct target *target)
+static int cortex_m_poll_one(struct target *target)
{
int detected_failure = ERROR_OK;
int retval = ERROR_OK;
@@ -879,16 +880,6 @@ static int cortex_m_poll(struct target *target)
struct cortex_m_common *cortex_m = target_to_cm(target);
struct armv7m_common *armv7m = &cortex_m->armv7m;
- /* Check if debug_ap is available to prevent segmentation fault.
- * If the re-examination after an error does not find a MEM-AP
- * (e.g. the target stopped communicating), debug_ap pointer
- * can suddenly become NULL.
- */
- if (!armv7m->debug_ap) {
- target->state = TARGET_UNKNOWN;
- return ERROR_TARGET_NOT_EXAMINED;
- }
-
/* Read from Debug Halting Control and Status Register */
retval = cortex_m_read_dhcsr_atomic_sticky(target);
if (retval != ERROR_OK) {
@@ -944,21 +935,26 @@ static int cortex_m_poll(struct target *target)
if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) {
retval = cortex_m_debug_entry(target);
- if (retval != ERROR_OK)
- return retval;
- if (arm_semihosting(target, &retval) != 0)
+ /* arm_semihosting needs to know registers, don't run if debug entry returned error */
+ if (retval == ERROR_OK && arm_semihosting(target, &retval) != 0)
return retval;
- target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+ if (target->smp) {
+ LOG_TARGET_DEBUG(target, "postpone target event 'halted'");
+ target->smp_halt_event_postponed = true;
+ } else {
+ /* regardless of errors returned in previous code update state */
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+ }
}
if (prev_target_state == TARGET_DEBUG_RUNNING) {
retval = cortex_m_debug_entry(target);
- if (retval != ERROR_OK)
- return retval;
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
}
+ if (retval != ERROR_OK)
+ return retval;
}
if (target->state == TARGET_UNKNOWN) {
@@ -991,7 +987,104 @@ static int cortex_m_poll(struct target *target)
return retval;
}
-static int cortex_m_halt(struct target *target)
+static int cortex_m_halt_one(struct target *target);
+
+static int cortex_m_smp_halt_all(struct list_head *smp_targets)
+{
+ int retval = ERROR_OK;
+ struct target_list *head;
+
+ foreach_smp_target(head, smp_targets) {
+ struct target *curr = head->target;
+ if (!target_was_examined(curr))
+ continue;
+ if (curr->state == TARGET_HALTED)
+ continue;
+
+ int ret2 = cortex_m_halt_one(curr);
+ if (retval == ERROR_OK)
+ retval = ret2; /* store the first error code ignore others */
+ }
+ return retval;
+}
+
+static int cortex_m_smp_post_halt_poll(struct list_head *smp_targets)
+{
+ int retval = ERROR_OK;
+ struct target_list *head;
+
+ foreach_smp_target(head, smp_targets) {
+ struct target *curr = head->target;
+ if (!target_was_examined(curr))
+ continue;
+ /* skip targets that were already halted */
+ if (curr->state == TARGET_HALTED)
+ continue;
+
+ int ret2 = cortex_m_poll_one(curr);
+ if (retval == ERROR_OK)
+ retval = ret2; /* store the first error code ignore others */
+ }
+ return retval;
+}
+
+static int cortex_m_poll_smp(struct list_head *smp_targets)
+{
+ int retval = ERROR_OK;
+ struct target_list *head;
+ bool halted = false;
+
+ foreach_smp_target(head, smp_targets) {
+ struct target *curr = head->target;
+ if (curr->smp_halt_event_postponed) {
+ halted = true;
+ break;
+ }
+ }
+
+ if (halted) {
+ retval = cortex_m_smp_halt_all(smp_targets);
+
+ int ret2 = cortex_m_smp_post_halt_poll(smp_targets);
+ if (retval == ERROR_OK)
+ retval = ret2; /* store the first error code ignore others */
+
+ foreach_smp_target(head, smp_targets) {
+ struct target *curr = head->target;
+ if (!curr->smp_halt_event_postponed)
+ continue;
+
+ curr->smp_halt_event_postponed = false;
+ if (curr->state == TARGET_HALTED) {
+ LOG_TARGET_DEBUG(curr, "sending postponed target event 'halted'");
+ target_call_event_callbacks(curr, TARGET_EVENT_HALTED);
+ }
+ }
+ /* There is no need to set gdb_service->target
+ * as hwthread_update_threads() selects an interesting thread
+ * by its own
+ */
+ }
+ return retval;
+}
+
+static int cortex_m_poll(struct target *target)
+{
+ int retval = cortex_m_poll_one(target);
+
+ if (target->smp) {
+ struct target_list *last;
+ last = list_last_entry(target->smp_targets, struct target_list, lh);
+ if (target == last->target)
+ /* After the last target in SMP group has been polled
+ * check for postponed halted events and eventually halt and re-poll
+ * other targets */
+ cortex_m_poll_smp(target->smp_targets);
+ }
+ return retval;
+}
+
+static int cortex_m_halt_one(struct target *target)
{
LOG_TARGET_DEBUG(target, "target->state: %s", target_state_name(target));
@@ -1029,6 +1122,14 @@ static int cortex_m_halt(struct target *target)
return ERROR_OK;
}
+static int cortex_m_halt(struct target *target)
+{
+ if (target->smp)
+ return cortex_m_smp_halt_all(target->smp_targets);
+ else
+ return cortex_m_halt_one(target);
+}
+
static int cortex_m_soft_reset_halt(struct target *target)
{
struct cortex_m_common *cortex_m = target_to_cm(target);
@@ -1106,8 +1207,8 @@ void cortex_m_enable_breakpoints(struct target *target)
}
}
-static int cortex_m_resume(struct target *target, int current,
- target_addr_t address, int handle_breakpoints, int debug_execution)
+static int cortex_m_restore_one(struct target *target, bool current,
+ target_addr_t *address, bool handle_breakpoints, bool debug_execution)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
struct breakpoint *breakpoint = NULL;
@@ -1115,7 +1216,7 @@ static int cortex_m_resume(struct target *target, int current,
struct reg *r;
if (target->state != TARGET_HALTED) {
- LOG_TARGET_WARNING(target, "target not halted");
+ LOG_TARGET_ERROR(target, "target not halted");
return ERROR_TARGET_NOT_HALTED;
}
@@ -1157,7 +1258,7 @@ static int cortex_m_resume(struct target *target, int current,
/* current = 1: continue on current pc, otherwise continue at <address> */
r = armv7m->arm.pc;
if (!current) {
- buf_set_u32(r->value, 0, 32, address);
+ buf_set_u32(r->value, 0, 32, *address);
r->dirty = true;
r->valid = true;
}
@@ -1171,8 +1272,12 @@ static int cortex_m_resume(struct target *target, int current,
armv7m_maybe_skip_bkpt_inst(target, NULL);
resume_pc = buf_get_u32(r->value, 0, 32);
+ if (current)
+ *address = resume_pc;
- armv7m_restore_context(target);
+ int retval = armv7m_restore_context(target);
+ if (retval != ERROR_OK)
+ return retval;
/* the front-end may request us not to handle breakpoints */
if (handle_breakpoints) {
@@ -1182,34 +1287,99 @@ static int cortex_m_resume(struct target *target, int current,
LOG_TARGET_DEBUG(target, "unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
breakpoint->address,
breakpoint->unique_id);
- cortex_m_unset_breakpoint(target, breakpoint);
- cortex_m_single_step_core(target);
- cortex_m_set_breakpoint(target, breakpoint);
+ retval = cortex_m_unset_breakpoint(target, breakpoint);
+ if (retval == ERROR_OK)
+ retval = cortex_m_single_step_core(target);
+ int ret2 = cortex_m_set_breakpoint(target, breakpoint);
+ if (retval != ERROR_OK)
+ return retval;
+ if (ret2 != ERROR_OK)
+ return ret2;
}
}
+ return ERROR_OK;
+}
+
+static int cortex_m_restart_one(struct target *target, bool debug_execution)
+{
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+
/* Restart core */
cortex_m_set_maskints_for_run(target);
cortex_m_write_debug_halt_mask(target, 0, C_HALT);
target->debug_reason = DBG_REASON_NOTHALTED;
-
/* registers are now invalid */
register_cache_invalidate(armv7m->arm.core_cache);
if (!debug_execution) {
target->state = TARGET_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
- LOG_TARGET_DEBUG(target, "target resumed at 0x%" PRIx32 "", resume_pc);
} else {
target->state = TARGET_DEBUG_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
- LOG_TARGET_DEBUG(target, "target debug resumed at 0x%" PRIx32 "", resume_pc);
}
return ERROR_OK;
}
+static int cortex_m_restore_smp(struct target *target, bool handle_breakpoints)
+{
+ struct target_list *head;
+ target_addr_t address;
+ foreach_smp_target(head, target->smp_targets) {
+ struct target *curr = head->target;
+ /* skip calling target */
+ if (curr == target)
+ continue;
+ if (!target_was_examined(curr))
+ continue;
+ /* skip running targets */
+ if (curr->state == TARGET_RUNNING)
+ continue;
+
+ int retval = cortex_m_restore_one(curr, true, &address,
+ handle_breakpoints, false);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = cortex_m_restart_one(curr, false);
+ if (retval != ERROR_OK)
+ return retval;
+
+ LOG_TARGET_DEBUG(curr, "SMP resumed at " TARGET_ADDR_FMT, address);
+ }
+ return ERROR_OK;
+}
+
+static int cortex_m_resume(struct target *target, int current,
+ target_addr_t address, int handle_breakpoints, int debug_execution)
+{
+ int retval = cortex_m_restore_one(target, !!current, &address, !!handle_breakpoints, !!debug_execution);
+ if (retval != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "context restore failed, aborting resume");
+ return retval;
+ }
+
+ if (target->smp && !debug_execution) {
+ retval = cortex_m_restore_smp(target, !!handle_breakpoints);
+ if (retval != ERROR_OK)
+ LOG_WARNING("resume of a SMP target failed, trying to resume current one");
+ }
+
+ cortex_m_restart_one(target, !!debug_execution);
+ if (retval != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "resume failed");
+ return retval;
+ }
+
+ LOG_TARGET_DEBUG(target, "%sresumed at " TARGET_ADDR_FMT,
+ debug_execution ? "debug " : "", address);
+
+ return ERROR_OK;
+}
+
/* int irqstepcount = 0; */
static int cortex_m_step(struct target *target, int current,
target_addr_t address, int handle_breakpoints)
@@ -1227,6 +1397,11 @@ static int cortex_m_step(struct target *target, int current,
return ERROR_TARGET_NOT_HALTED;
}
+ /* Just one of SMP cores will step. Set the gdb control
+ * target to current one or gdb miss gdb-end event */
+ if (target->smp && target->gdb_service)
+ target->gdb_service->target = target;
+
/* current = 1: continue on current pc, otherwise continue at <address> */
if (!current) {
buf_set_u32(pc->value, 0, 32, address);
@@ -1408,8 +1583,9 @@ static int cortex_m_assert_reset(struct target *target)
struct armv7m_common *armv7m = &cortex_m->armv7m;
enum cortex_m_soft_reset_config reset_config = cortex_m->soft_reset_config;
- LOG_TARGET_DEBUG(target, "target->state: %s",
- target_state_name(target));
+ LOG_TARGET_DEBUG(target, "target->state: %s,%s examined",
+ target_state_name(target),
+ target_was_examined(target) ? "" : " not");
enum reset_types jtag_reset_config = jtag_get_reset_config();
@@ -1428,24 +1604,40 @@ static int cortex_m_assert_reset(struct target *target)
bool srst_asserted = false;
- if (!target_was_examined(target)) {
- if (jtag_reset_config & RESET_HAS_SRST) {
- adapter_assert_reset();
+ if ((jtag_reset_config & RESET_HAS_SRST) &&
+ ((jtag_reset_config & RESET_SRST_NO_GATING) || !armv7m->debug_ap)) {
+ /* If we have no debug_ap, asserting SRST is the only thing
+ * we can do now */
+ adapter_assert_reset();
+ srst_asserted = true;
+ }
+
+ /* TODO: replace the hack calling target_examine_one()
+ * as soon as a better reset framework is available */
+ if (!target_was_examined(target) && !target->defer_examine
+ && srst_asserted && (jtag_reset_config & RESET_SRST_NO_GATING)) {
+ LOG_TARGET_DEBUG(target, "Trying to re-examine under reset");
+ target_examine_one(target);
+ }
+
+ /* We need at least debug_ap to go further.
+ * Inform user and bail out if we don't have one. */
+ if (!armv7m->debug_ap) {
+ if (srst_asserted) {
if (target->reset_halt)
- LOG_TARGET_ERROR(target, "Target not examined, will not halt after reset!");
+ LOG_TARGET_ERROR(target, "Debug AP not available, will not halt after reset!");
+
+ /* Do not propagate error: reset was asserted, proceed to deassert! */
+ target->state = TARGET_RESET;
+ register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
return ERROR_OK;
+
} else {
- LOG_TARGET_ERROR(target, "Target not examined, reset NOT asserted!");
+ LOG_TARGET_ERROR(target, "Debug AP not available, reset NOT asserted!");
return ERROR_FAIL;
}
}
- if ((jtag_reset_config & RESET_HAS_SRST) &&
- (jtag_reset_config & RESET_SRST_NO_GATING)) {
- adapter_assert_reset();
- srst_asserted = true;
- }
-
/* Enable debug requests */
int retval = cortex_m_read_dhcsr_atomic_sticky(target);
@@ -1546,7 +1738,7 @@ static int cortex_m_assert_reset(struct target *target)
if (retval != ERROR_OK)
return retval;
- if (target->reset_halt) {
+ if (target->reset_halt && target_was_examined(target)) {
retval = target_halt(target);
if (retval != ERROR_OK)
return retval;
@@ -1559,8 +1751,9 @@ static int cortex_m_deassert_reset(struct target *target)
{
struct armv7m_common *armv7m = &target_to_cm(target)->armv7m;
- LOG_TARGET_DEBUG(target, "target->state: %s",
- target_state_name(target));
+ LOG_TARGET_DEBUG(target, "target->state: %s,%s examined",
+ target_state_name(target),
+ target_was_examined(target) ? "" : " not");
/* deassert reset lines */
adapter_deassert_reset();
@@ -1568,8 +1761,8 @@ static int cortex_m_deassert_reset(struct target *target)
enum reset_types jtag_reset_config = jtag_get_reset_config();
if ((jtag_reset_config & RESET_HAS_SRST) &&
- !(jtag_reset_config & RESET_SRST_NO_GATING) &&
- target_was_examined(target)) {
+ !(jtag_reset_config & RESET_SRST_NO_GATING) &&
+ armv7m->debug_ap) {
int retval = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);
if (retval != ERROR_OK) {
@@ -2262,6 +2455,22 @@ static void cortex_m_dwt_free(struct target *target)
cm->dwt_cache = NULL;
}
+static bool cortex_m_has_tz(struct target *target)
+{
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ uint32_t dauthstatus;
+
+ if (armv7m->arm.arch != ARM_ARCH_V8M)
+ return false;
+
+ int retval = target_read_u32(target, DAUTHSTATUS, &dauthstatus);
+ if (retval != ERROR_OK) {
+ LOG_WARNING("Error reading DAUTHSTATUS register");
+ return false;
+ }
+ return (dauthstatus & DAUTHSTATUS_SID_MASK) != 0;
+}
+
#define MVFR0 0xe000ef40
#define MVFR1 0xe000ef44
@@ -2293,23 +2502,20 @@ int cortex_m_examine(struct target *target)
/* hla_target shares the examine handler but does not support
* all its calls */
if (!armv7m->is_hla_target) {
- if (armv7m->debug_ap) {
- dap_put_ap(armv7m->debug_ap);
- armv7m->debug_ap = NULL;
- }
-
- if (cortex_m->apsel == DP_APSEL_INVALID) {
- /* Search for the MEM-AP */
- retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap);
- if (retval != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Could not find MEM-AP to control the core");
- return retval;
- }
- } else {
- armv7m->debug_ap = dap_get_ap(swjdp, cortex_m->apsel);
- if (!armv7m->debug_ap) {
- LOG_ERROR("Cannot get AP");
- return ERROR_FAIL;
+ if (!armv7m->debug_ap) {
+ if (cortex_m->apsel == DP_APSEL_INVALID) {
+ /* Search for the MEM-AP */
+ retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap);
+ if (retval != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "Could not find MEM-AP to control the core");
+ return retval;
+ }
+ } else {
+ armv7m->debug_ap = dap_get_ap(swjdp, cortex_m->apsel);
+ if (!armv7m->debug_ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
}
@@ -2393,7 +2599,7 @@ int cortex_m_examine(struct target *target)
for (size_t idx = ARMV7M_FPU_FIRST_REG; idx <= ARMV7M_FPU_LAST_REG; idx++)
armv7m->arm.core_cache->reg_list[idx].exist = false;
- if (armv7m->arm.arch != ARM_ARCH_V8M)
+ if (!cortex_m_has_tz(target))
for (size_t idx = ARMV8M_FIRST_REG; idx <= ARMV8M_LAST_REG; idx++)
armv7m->arm.core_cache->reg_list[idx].exist = false;
@@ -2829,6 +3035,9 @@ static const struct command_registration cortex_m_exec_command_handlers[] = {
.help = "configure software reset handling",
.usage = "['sysresetreq'|'vectreset']",
},
+ {
+ .chain = smp_command_handlers,
+ },
COMMAND_REGISTRATION_DONE
};
static const struct command_registration cortex_m_command_handlers[] = {
diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h
index b1de26e..a1c43b5 100644
--- a/src/target/cortex_m.h
+++ b/src/target/cortex_m.h
@@ -68,6 +68,9 @@ struct cortex_m_part_info {
#define DCB_DEMCR 0xE000EDFC
#define DCB_DSCSR 0xE000EE08
+#define DAUTHSTATUS 0xE000EFB8
+#define DAUTHSTATUS_SID_MASK 0x00000030
+
#define DCRSR_WNR BIT(16)
#define DWT_CTRL 0xE0001000
diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c
index 37cf059..c90bca3 100644
--- a/src/target/dsp5680xx.c
+++ b/src/target/dsp5680xx.c
@@ -2200,8 +2200,8 @@ int dsp5680xx_f_lock(struct target *target)
struct jtag_tap *tap_chp;
struct jtag_tap *tap_cpu;
- uint16_t lock_word[] = { HFM_LOCK_FLASH };
- retval = dsp5680xx_f_wr(target, (uint8_t *) (lock_word), HFM_LOCK_ADDR_L, 2, 1);
+ uint16_t lock_word = HFM_LOCK_FLASH;
+ retval = dsp5680xx_f_wr(target, (uint8_t *)&lock_word, HFM_LOCK_ADDR_L, 2, 1);
err_check_propagate(retval);
jtag_add_reset(0, 1);
diff --git a/src/target/esirisc_jtag.c b/src/target/esirisc_jtag.c
index 54abc40..1ec1726 100644
--- a/src/target/esirisc_jtag.c
+++ b/src/target/esirisc_jtag.c
@@ -130,7 +130,9 @@ static int esirisc_jtag_recv(struct esirisc_jtag *jtag_info,
int num_in_bytes = DIV_ROUND_UP(num_in_bits, 8);
struct scan_field fields[3];
- uint8_t r[num_in_bytes * 2];
+ /* prevent zero-size variable length array */
+ int r_size = num_in_bytes ? num_in_bytes * 2 : 1;
+ uint8_t r[r_size];
esirisc_jtag_set_instr(jtag_info, INSTR_DEBUG);
diff --git a/src/target/espressif/esp32s2.c b/src/target/espressif/esp32s2.c
index 62d1ddb..64fa690 100644
--- a/src/target/espressif/esp32s2.c
+++ b/src/target/espressif/esp32s2.c
@@ -402,6 +402,8 @@ static int esp32s2_poll(struct target *target)
{
enum target_state old_state = target->state;
int ret = esp_xtensa_poll(target);
+ if (ret != ERROR_OK)
+ return ret;
if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
/* Call any event callbacks that are applicable */
diff --git a/src/target/hla_target.c b/src/target/hla_target.c
index 33126d6..8c35a90 100644
--- a/src/target/hla_target.c
+++ b/src/target/hla_target.c
@@ -347,6 +347,13 @@ static int hl_assert_reset(struct target *target)
adapter->layout->api->write_debug_reg(adapter->handle, DCB_DHCSR, DBGKEY|C_DEBUGEN);
+ if (!target_was_examined(target) && !target->defer_examine
+ && srst_asserted && res == ERROR_OK) {
+ /* If the target is not examined, now under reset it is good time to retry examination */
+ LOG_TARGET_DEBUG(target, "Trying to re-examine under reset");
+ target_examine_one(target);
+ }
+
/* only set vector catch if halt is requested */
if (target->reset_halt)
adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA|VC_CORERESET);
diff --git a/src/target/mem_ap.c b/src/target/mem_ap.c
index a662506..50dc91c 100644
--- a/src/target/mem_ap.c
+++ b/src/target/mem_ap.c
@@ -136,15 +136,12 @@ static int mem_ap_examine(struct target *target)
struct mem_ap *mem_ap = target->arch_info;
if (!target_was_examined(target)) {
- if (mem_ap->ap) {
- dap_put_ap(mem_ap->ap);
- mem_ap->ap = NULL;
- }
-
- mem_ap->ap = dap_get_ap(mem_ap->dap, mem_ap->ap_num);
if (!mem_ap->ap) {
- LOG_ERROR("Cannot get AP");
- return ERROR_FAIL;
+ mem_ap->ap = dap_get_ap(mem_ap->dap, mem_ap->ap_num);
+ if (!mem_ap->ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
target_set_examined(target);
target->state = TARGET_UNKNOWN;
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index e85018c..491b247 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -900,7 +900,7 @@ static int mips_m4k_set_watchpoint(struct target *target,
LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
}
- watchpoint->number = wp_num;
+ watchpoint_set(watchpoint, wp_num);
comparator_list[wp_num].used = 1;
comparator_list[wp_num].bp_value = watchpoint->address;
diff --git a/src/target/nds32.c b/src/target/nds32.c
deleted file mode 100644
index bd30976..0000000
--- a/src/target/nds32.c
+++ /dev/null
@@ -1,2613 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <helper/log.h>
-#include <helper/binarybuffer.h>
-#include "nds32.h"
-#include "nds32_aice.h"
-#include "nds32_tlb.h"
-#include "nds32_disassembler.h"
-
-struct nds32_edm_operation nds32_edm_ops[NDS32_EDM_OPERATION_MAX_NUM];
-uint32_t nds32_edm_ops_num;
-
-const char *nds32_debug_type_name[11] = {
- "SOFTWARE BREAK",
- "SOFTWARE BREAK_16",
- "HARDWARE BREAKPOINT",
- "DATA ADDR WATCHPOINT PRECISE",
- "DATA VALUE WATCHPOINT PRECISE",
- "DATA VALUE WATCHPOINT IMPRECISE",
- "DEBUG INTERRUPT",
- "HARDWARE SINGLE STEP",
- "DATA ADDR WATCHPOINT NEXT PRECISE",
- "DATA VALUE WATCHPOINT NEXT PRECISE",
- "LOAD STORE GLOBAL STOP",
-};
-
-static const int nds32_lm_size_table[16] = {
- 4 * 1024,
- 8 * 1024,
- 16 * 1024,
- 32 * 1024,
- 64 * 1024,
- 128 * 1024,
- 256 * 1024,
- 512 * 1024,
- 1024 * 1024,
- 1 * 1024,
- 2 * 1024,
-};
-
-static const int nds32_line_size_table[6] = {
- 0,
- 8,
- 16,
- 32,
- 64,
- 128,
-};
-
-static int nds32_get_core_reg(struct reg *reg)
-{
- int retval;
- struct nds32_reg *reg_arch_info = reg->arch_info;
- struct target *target = reg_arch_info->target;
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
-
- if (target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- if (reg->valid) {
- uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32);
- LOG_DEBUG("reading register(cached) %" PRIi32 "(%s), value: 0x%8.8" PRIx32,
- reg_arch_info->num, reg->name, val);
- return ERROR_OK;
- }
-
- int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num);
-
- if (reg_arch_info->enable == false) {
- buf_set_u32(reg_arch_info->value, 0, 32, NDS32_REGISTER_DISABLE);
- retval = ERROR_FAIL;
- } else {
- uint32_t val = 0;
- if ((nds32->fpu_enable == false)
- && (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_FPU)) {
- retval = ERROR_OK;
- } else if ((nds32->audio_enable == false)
- && (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_AUMR)) {
- retval = ERROR_OK;
- } else {
- retval = aice_read_register(aice, mapped_regnum, &val);
- }
- buf_set_u32(reg_arch_info->value, 0, 32, val);
-
- LOG_DEBUG("reading register %" PRIi32 "(%s), value: 0x%8.8" PRIx32,
- reg_arch_info->num, reg->name, val);
- }
-
- if (retval == ERROR_OK) {
- reg->valid = true;
- reg->dirty = false;
- }
-
- return retval;
-}
-
-static int nds32_get_core_reg_64(struct reg *reg)
-{
- int retval;
- struct nds32_reg *reg_arch_info = reg->arch_info;
- struct target *target = reg_arch_info->target;
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
-
- if (target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- if (reg->valid)
- return ERROR_OK;
-
- if (reg_arch_info->enable == false) {
- buf_set_u64(reg_arch_info->value, 0, 64, NDS32_REGISTER_DISABLE);
- retval = ERROR_FAIL;
- } else {
- uint64_t val = 0;
- if ((nds32->fpu_enable == false)
- && ((reg_arch_info->num >= FD0) && (reg_arch_info->num <= FD31))) {
- retval = ERROR_OK;
- } else {
- retval = aice_read_reg_64(aice, reg_arch_info->num, &val);
- }
- buf_set_u64(reg_arch_info->value, 0, 64, val);
- }
-
- if (retval == ERROR_OK) {
- reg->valid = true;
- reg->dirty = false;
- }
-
- return retval;
-}
-
-static int nds32_update_psw(struct nds32 *nds32)
-{
- uint32_t value_ir0;
- struct aice_port_s *aice = target_to_aice(nds32->target);
-
- nds32_get_mapped_reg(nds32, IR0, &value_ir0);
-
- /* Save data memory endian */
- if ((value_ir0 >> 5) & 0x1) {
- nds32->data_endian = TARGET_BIG_ENDIAN;
- aice_set_data_endian(aice, AICE_BIG_ENDIAN);
- } else {
- nds32->data_endian = TARGET_LITTLE_ENDIAN;
- aice_set_data_endian(aice, AICE_LITTLE_ENDIAN);
- }
-
- /* Save translation status */
- nds32->memory.address_translation = ((value_ir0 >> 7) & 0x1) ? true : false;
-
- return ERROR_OK;
-}
-
-static int nds32_update_mmu_info(struct nds32 *nds32)
-{
- uint32_t value;
-
- /* Update MMU control status */
- nds32_get_mapped_reg(nds32, MR0, &value);
- nds32->mmu_config.default_min_page_size = value & 0x1;
- nds32->mmu_config.multiple_page_size_in_use = (value >> 10) & 0x1;
-
- return ERROR_OK;
-}
-
-static int nds32_update_cache_info(struct nds32 *nds32)
-{
- uint32_t value;
-
- if (nds32_get_mapped_reg(nds32, MR8, &value) == ERROR_OK) {
- if (value & 0x1)
- nds32->memory.icache.enable = true;
- else
- nds32->memory.icache.enable = false;
-
- if (value & 0x2)
- nds32->memory.dcache.enable = true;
- else
- nds32->memory.dcache.enable = false;
- } else {
- nds32->memory.icache.enable = false;
- nds32->memory.dcache.enable = false;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_update_lm_info(struct nds32 *nds32)
-{
- struct nds32_memory *memory = &(nds32->memory);
- uint32_t value_mr6;
- uint32_t value_mr7;
-
- nds32_get_mapped_reg(nds32, MR6, &value_mr6);
- if (value_mr6 & 0x1)
- memory->ilm_enable = true;
- else
- memory->ilm_enable = false;
-
- if (memory->ilm_align_ver == 0) { /* 1MB aligned */
- memory->ilm_start = value_mr6 & 0xFFF00000;
- memory->ilm_end = memory->ilm_start + memory->ilm_size;
- } else if (memory->ilm_align_ver == 1) { /* aligned to local memory size */
- memory->ilm_start = value_mr6 & 0xFFFFFC00;
- memory->ilm_end = memory->ilm_start + memory->ilm_size;
- } else {
- memory->ilm_start = -1;
- memory->ilm_end = -1;
- }
-
- nds32_get_mapped_reg(nds32, MR7, &value_mr7);
- if (value_mr7 & 0x1)
- memory->dlm_enable = true;
- else
- memory->dlm_enable = false;
-
- if (memory->dlm_align_ver == 0) { /* 1MB aligned */
- memory->dlm_start = value_mr7 & 0xFFF00000;
- memory->dlm_end = memory->dlm_start + memory->dlm_size;
- } else if (memory->dlm_align_ver == 1) { /* aligned to local memory size */
- memory->dlm_start = value_mr7 & 0xFFFFFC00;
- memory->dlm_end = memory->dlm_start + memory->dlm_size;
- } else {
- memory->dlm_start = -1;
- memory->dlm_end = -1;
- }
-
- return ERROR_OK;
-}
-
-/**
- * If fpu/audio is disabled, to access fpu/audio registers will cause
- * exceptions. So, we need to check if fpu/audio is enabled or not as
- * target is halted. If fpu/audio is disabled, as users access fpu/audio
- * registers, OpenOCD will return fake value 0 instead of accessing
- * registers through DIM.
- */
-static int nds32_check_extension(struct nds32 *nds32)
-{
- uint32_t value;
-
- nds32_get_mapped_reg(nds32, FUCPR, &value);
- if (value == NDS32_REGISTER_DISABLE) {
- nds32->fpu_enable = false;
- nds32->audio_enable = false;
- return ERROR_OK;
- }
-
- if (value & 0x1)
- nds32->fpu_enable = true;
- else
- nds32->fpu_enable = false;
-
- if (value & 0x80000000)
- nds32->audio_enable = true;
- else
- nds32->audio_enable = false;
-
- return ERROR_OK;
-}
-
-static int nds32_set_core_reg(struct reg *reg, uint8_t *buf)
-{
- struct nds32_reg *reg_arch_info = reg->arch_info;
- struct target *target = reg_arch_info->target;
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
- uint32_t value = buf_get_u32(buf, 0, 32);
-
- if (target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num);
-
- /* ignore values that will generate exception */
- if (nds32_reg_exception(mapped_regnum, value))
- return ERROR_OK;
-
- LOG_DEBUG("writing register %" PRIi32 "(%s) with value 0x%8.8" PRIx32,
- reg_arch_info->num, reg->name, value);
-
- if ((nds32->fpu_enable == false) &&
- (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_FPU)) {
-
- buf_set_u32(reg->value, 0, 32, 0);
- } else if ((nds32->audio_enable == false) &&
- (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_AUMR)) {
-
- buf_set_u32(reg->value, 0, 32, 0);
- } else {
- buf_set_u32(reg->value, 0, 32, value);
- uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32);
- aice_write_register(aice, mapped_regnum, val);
-
- /* After set value to registers, read the value from target
- * to avoid W1C inconsistency. */
- aice_read_register(aice, mapped_regnum, &val);
- buf_set_u32(reg_arch_info->value, 0, 32, val);
- }
-
- reg->valid = true;
- reg->dirty = false;
-
- /* update registers to take effect right now */
- if (mapped_regnum == IR0) {
- nds32_update_psw(nds32);
- } else if (mapped_regnum == MR0) {
- nds32_update_mmu_info(nds32);
- } else if ((mapped_regnum == MR6) || (mapped_regnum == MR7)) {
- /* update lm information */
- nds32_update_lm_info(nds32);
- } else if (mapped_regnum == MR8) {
- nds32_update_cache_info(nds32);
- } else if (mapped_regnum == FUCPR) {
- /* update audio/fpu setting */
- nds32_check_extension(nds32);
- }
-
- return ERROR_OK;
-}
-
-static int nds32_set_core_reg_64(struct reg *reg, uint8_t *buf)
-{
- struct nds32_reg *reg_arch_info = reg->arch_info;
- struct target *target = reg_arch_info->target;
- struct nds32 *nds32 = target_to_nds32(target);
- uint32_t low_part = buf_get_u32(buf, 0, 32);
- uint32_t high_part = buf_get_u32(buf, 32, 32);
-
- if (target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- if ((nds32->fpu_enable == false) &&
- ((reg_arch_info->num >= FD0) && (reg_arch_info->num <= FD31))) {
-
- buf_set_u32(reg->value, 0, 32, 0);
- buf_set_u32(reg->value, 32, 32, 0);
-
- reg->valid = true;
- reg->dirty = false;
- } else {
- buf_set_u32(reg->value, 0, 32, low_part);
- buf_set_u32(reg->value, 32, 32, high_part);
-
- reg->valid = true;
- reg->dirty = true;
- }
-
- return ERROR_OK;
-}
-
-static const struct reg_arch_type nds32_reg_access_type = {
- .get = nds32_get_core_reg,
- .set = nds32_set_core_reg,
-};
-
-static const struct reg_arch_type nds32_reg_access_type_64 = {
- .get = nds32_get_core_reg_64,
- .set = nds32_set_core_reg_64,
-};
-
-static struct reg_cache *nds32_build_reg_cache(struct target *target,
- struct nds32 *nds32)
-{
- struct reg_cache *cache = calloc(sizeof(struct reg_cache), 1);
- struct reg *reg_list = calloc(TOTAL_REG_NUM, sizeof(struct reg));
- struct nds32_reg *reg_arch_info = calloc(TOTAL_REG_NUM, sizeof(struct nds32_reg));
- int i;
-
- if (!cache || !reg_list || !reg_arch_info) {
- free(cache);
- free(reg_list);
- free(reg_arch_info);
- return NULL;
- }
-
- cache->name = "Andes registers";
- cache->next = NULL;
- cache->reg_list = reg_list;
- cache->num_regs = 0;
-
- for (i = 0; i < TOTAL_REG_NUM; i++) {
- reg_arch_info[i].num = i;
- reg_arch_info[i].target = target;
- reg_arch_info[i].nds32 = nds32;
- reg_arch_info[i].enable = false;
-
- reg_list[i].name = nds32_reg_simple_name(i);
- reg_list[i].number = reg_arch_info[i].num;
- reg_list[i].size = nds32_reg_size(i);
- reg_list[i].arch_info = &reg_arch_info[i];
-
- reg_list[i].reg_data_type = calloc(sizeof(struct reg_data_type), 1);
-
- if (reg_arch_info[i].num >= FD0 && reg_arch_info[i].num <= FD31) {
- reg_list[i].value = reg_arch_info[i].value;
- reg_list[i].type = &nds32_reg_access_type_64;
-
- reg_list[i].reg_data_type->type = REG_TYPE_IEEE_DOUBLE;
- reg_list[i].reg_data_type->id = "ieee_double";
- reg_list[i].group = "float";
- } else {
- reg_list[i].value = reg_arch_info[i].value;
- reg_list[i].type = &nds32_reg_access_type;
- reg_list[i].group = "general";
-
- if ((reg_arch_info[i].num >= FS0) && (reg_arch_info[i].num <= FS31)) {
- reg_list[i].reg_data_type->type = REG_TYPE_IEEE_SINGLE;
- reg_list[i].reg_data_type->id = "ieee_single";
- reg_list[i].group = "float";
- } else if ((reg_arch_info[i].num == FPCSR) ||
- (reg_arch_info[i].num == FPCFG)) {
- reg_list[i].group = "float";
- } else if ((reg_arch_info[i].num == R28) ||
- (reg_arch_info[i].num == R29) ||
- (reg_arch_info[i].num == R31)) {
- reg_list[i].reg_data_type->type = REG_TYPE_DATA_PTR;
- reg_list[i].reg_data_type->id = "data_ptr";
- } else if ((reg_arch_info[i].num == R30) ||
- (reg_arch_info[i].num == PC)) {
- reg_list[i].reg_data_type->type = REG_TYPE_CODE_PTR;
- reg_list[i].reg_data_type->id = "code_ptr";
- } else {
- reg_list[i].reg_data_type->type = REG_TYPE_UINT32;
- reg_list[i].reg_data_type->id = "uint32";
- }
- }
-
- if (reg_arch_info[i].num >= R16 && reg_arch_info[i].num <= R25)
- reg_list[i].caller_save = true;
- else
- reg_list[i].caller_save = false;
-
- reg_list[i].feature = malloc(sizeof(struct reg_feature));
-
- if (reg_arch_info[i].num >= R0 && reg_arch_info[i].num <= IFC_LP)
- reg_list[i].feature->name = "org.gnu.gdb.nds32.core";
- else if (reg_arch_info[i].num >= CR0 && reg_arch_info[i].num <= SECUR0)
- reg_list[i].feature->name = "org.gnu.gdb.nds32.system";
- else if (reg_arch_info[i].num >= D0L24 && reg_arch_info[i].num <= CBE3)
- reg_list[i].feature->name = "org.gnu.gdb.nds32.audio";
- else if (reg_arch_info[i].num >= FPCSR && reg_arch_info[i].num <= FD31)
- reg_list[i].feature->name = "org.gnu.gdb.nds32.fpu";
-
- cache->num_regs++;
- }
-
- nds32->core_cache = cache;
-
- return cache;
-}
-
-static int nds32_reg_cache_init(struct target *target, struct nds32 *nds32)
-{
- struct reg_cache *cache;
-
- cache = nds32_build_reg_cache(target, nds32);
- if (!cache)
- return ERROR_FAIL;
-
- *register_get_last_cache_p(&target->reg_cache) = cache;
-
- return ERROR_OK;
-}
-
-static struct reg *nds32_reg_current(struct nds32 *nds32, unsigned regnum)
-{
- struct reg *r;
-
- r = nds32->core_cache->reg_list + regnum;
-
- return r;
-}
-
-int nds32_full_context(struct nds32 *nds32)
-{
- uint32_t value, value_ir0;
-
- /* save $pc & $psw */
- nds32_get_mapped_reg(nds32, PC, &value);
- nds32_get_mapped_reg(nds32, IR0, &value_ir0);
-
- nds32_update_psw(nds32);
- nds32_update_mmu_info(nds32);
- nds32_update_cache_info(nds32);
- nds32_update_lm_info(nds32);
-
- nds32_check_extension(nds32);
-
- return ERROR_OK;
-}
-
-/* get register value internally */
-int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value)
-{
- struct reg_cache *reg_cache = nds32->core_cache;
- struct reg *r;
-
- if (regnum > reg_cache->num_regs)
- return ERROR_FAIL;
-
- r = nds32_reg_current(nds32, regnum);
-
- if (r->type->get(r) != ERROR_OK)
- return ERROR_FAIL;
-
- *value = buf_get_u32(r->value, 0, 32);
-
- return ERROR_OK;
-}
-
-/** set register internally */
-int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value)
-{
- struct reg_cache *reg_cache = nds32->core_cache;
- struct reg *r;
- uint8_t set_value[4];
-
- if (regnum > reg_cache->num_regs)
- return ERROR_FAIL;
-
- r = nds32_reg_current(nds32, regnum);
-
- buf_set_u32(set_value, 0, 32, value);
-
- return r->type->set(r, set_value);
-}
-
-/** get general register list */
-static int nds32_get_general_reg_list(struct nds32 *nds32,
- struct reg **reg_list[], int *reg_list_size)
-{
- struct reg *reg_current;
- int i;
- int current_idx;
-
- /** freed in gdb_server.c */
- *reg_list = malloc(sizeof(struct reg *) * (IFC_LP - R0 + 1));
- current_idx = 0;
-
- for (i = R0; i < IFC_LP + 1; i++) {
- reg_current = nds32_reg_current(nds32, i);
- if (((struct nds32_reg *)reg_current->arch_info)->enable) {
- (*reg_list)[current_idx] = reg_current;
- current_idx++;
- }
- }
- *reg_list_size = current_idx;
-
- return ERROR_OK;
-}
-
-/** get all register list */
-static int nds32_get_all_reg_list(struct nds32 *nds32,
- struct reg **reg_list[], int *reg_list_size)
-{
- struct reg_cache *reg_cache = nds32->core_cache;
- struct reg *reg_current;
- unsigned int i;
-
- *reg_list_size = reg_cache->num_regs;
-
- /** freed in gdb_server.c */
- *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
-
- for (i = 0; i < reg_cache->num_regs; i++) {
- reg_current = nds32_reg_current(nds32, i);
- reg_current->exist = ((struct nds32_reg *)
- reg_current->arch_info)->enable;
- (*reg_list)[i] = reg_current;
- }
-
- return ERROR_OK;
-}
-
-/** get all register list */
-int nds32_get_gdb_reg_list(struct target *target,
- struct reg **reg_list[], int *reg_list_size,
- enum target_register_class reg_class)
-{
- struct nds32 *nds32 = target_to_nds32(target);
-
- switch (reg_class) {
- case REG_CLASS_ALL:
- return nds32_get_all_reg_list(nds32, reg_list, reg_list_size);
- case REG_CLASS_GENERAL:
- return nds32_get_general_reg_list(nds32, reg_list, reg_list_size);
- default:
- return ERROR_FAIL;
- }
-
- return ERROR_FAIL;
-}
-
-static int nds32_select_memory_mode(struct target *target, uint32_t address,
- uint32_t length, uint32_t *end_address)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_memory *memory = &(nds32->memory);
- struct nds32_edm *edm = &(nds32->edm);
- uint32_t dlm_start, dlm_end;
- uint32_t ilm_start, ilm_end;
- uint32_t address_end = address + length;
-
- /* init end_address */
- *end_address = address_end;
-
- if (memory->access_channel == NDS_MEMORY_ACC_CPU)
- return ERROR_OK;
-
- if (edm->access_control == false) {
- LOG_DEBUG("EDM does not support ACC_CTL");
- return ERROR_OK;
- }
-
- if (edm->direct_access_local_memory == false) {
- LOG_DEBUG("EDM does not support DALM");
- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM);
- return ERROR_OK;
- }
-
- if (memory->mode != NDS_MEMORY_SELECT_AUTO) {
- LOG_DEBUG("Memory mode is not AUTO");
- return ERROR_OK;
- }
-
- /* set default mode */
- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM);
-
- if ((memory->ilm_base != 0) && (memory->ilm_enable == true)) {
- ilm_start = memory->ilm_start;
- ilm_end = memory->ilm_end;
-
- /* case 1, address < ilm_start */
- if (address < ilm_start) {
- if (ilm_start < address_end) {
- /* update end_address to split non-ILM from ILM */
- *end_address = ilm_start;
- }
- /* MEM mode */
- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM);
- } else if ((ilm_start <= address) && (address < ilm_end)) {
- /* case 2, ilm_start <= address < ilm_end */
- if (ilm_end < address_end) {
- /* update end_address to split non-ILM from ILM */
- *end_address = ilm_end;
- }
- /* ILM mode */
- aice_memory_mode(aice, NDS_MEMORY_SELECT_ILM);
- } else { /* case 3, ilm_end <= address */
- /* MEM mode */
- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM);
- }
-
- return ERROR_OK;
- } else {
- LOG_DEBUG("ILM is not enabled");
- }
-
- if ((memory->dlm_base != 0) && (memory->dlm_enable == true)) {
- dlm_start = memory->dlm_start;
- dlm_end = memory->dlm_end;
-
- /* case 1, address < dlm_start */
- if (address < dlm_start) {
- if (dlm_start < address_end) {
- /* update end_address to split non-DLM from DLM */
- *end_address = dlm_start;
- }
- /* MEM mode */
- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM);
- } else if ((dlm_start <= address) && (address < dlm_end)) {
- /* case 2, dlm_start <= address < dlm_end */
- if (dlm_end < address_end) {
- /* update end_address to split non-DLM from DLM */
- *end_address = dlm_end;
- }
- /* DLM mode */
- aice_memory_mode(aice, NDS_MEMORY_SELECT_DLM);
- } else { /* case 3, dlm_end <= address */
- /* MEM mode */
- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM);
- }
-
- return ERROR_OK;
- } else {
- LOG_DEBUG("DLM is not enabled");
- }
-
- return ERROR_OK;
-}
-
-int nds32_read_buffer(struct target *target, uint32_t address,
- uint32_t size, uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- LOG_DEBUG("READ BUFFER: ADDR %08" PRIx32 " SIZE %08" PRIx32,
- address,
- size);
-
- int retval = ERROR_OK;
- struct aice_port_s *aice = target_to_aice(target);
- uint32_t end_address;
-
- if (((address % 2) == 0) && (size == 2)) {
- nds32_select_memory_mode(target, address, 2, &end_address);
- return aice_read_mem_unit(aice, address, 2, 1, buffer);
- }
-
- /* handle unaligned head bytes */
- if (address % 4) {
- uint32_t unaligned = 4 - (address % 4);
-
- if (unaligned > size)
- unaligned = size;
-
- nds32_select_memory_mode(target, address, unaligned, &end_address);
- retval = aice_read_mem_unit(aice, address, 1, unaligned, buffer);
- if (retval != ERROR_OK)
- return retval;
-
- buffer += unaligned;
- address += unaligned;
- size -= unaligned;
- }
-
- /* handle aligned words */
- if (size >= 4) {
- int aligned = size - (size % 4);
- int read_len;
-
- do {
- nds32_select_memory_mode(target, address, aligned, &end_address);
-
- read_len = end_address - address;
-
- if (read_len > 8)
- retval = aice_read_mem_bulk(aice, address, read_len, buffer);
- else
- retval = aice_read_mem_unit(aice, address, 4, read_len / 4, buffer);
-
- if (retval != ERROR_OK)
- return retval;
-
- buffer += read_len;
- address += read_len;
- size -= read_len;
- aligned -= read_len;
-
- } while (aligned != 0);
- }
-
- /*prevent byte access when possible (avoid AHB access limitations in some cases)*/
- if (size >= 2) {
- int aligned = size - (size % 2);
- nds32_select_memory_mode(target, address, aligned, &end_address);
- retval = aice_read_mem_unit(aice, address, 2, aligned / 2, buffer);
- if (retval != ERROR_OK)
- return retval;
-
- buffer += aligned;
- address += aligned;
- size -= aligned;
- }
- /* handle tail writes of less than 4 bytes */
- if (size > 0) {
- nds32_select_memory_mode(target, address, size, &end_address);
- retval = aice_read_mem_unit(aice, address, 1, size, buffer);
- if (retval != ERROR_OK)
- return retval;
- }
-
- return ERROR_OK;
-}
-
-int nds32_read_memory(struct target *target, uint32_t address,
- uint32_t size, uint32_t count, uint8_t *buffer)
-{
- struct aice_port_s *aice = target_to_aice(target);
-
- return aice_read_mem_unit(aice, address, size, count, buffer);
-}
-
-int nds32_read_phys_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, uint8_t *buffer)
-{
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
- enum nds_memory_access orig_channel;
- int result;
-
- /* switch to BUS access mode to skip MMU */
- orig_channel = memory->access_channel;
- memory->access_channel = NDS_MEMORY_ACC_BUS;
- aice_memory_access(aice, memory->access_channel);
-
- /* The input address is physical address. No need to do address translation. */
- result = aice_read_mem_unit(aice, address, size, count, buffer);
-
- /* restore to origin access mode */
- memory->access_channel = orig_channel;
- aice_memory_access(aice, memory->access_channel);
-
- return result;
-}
-
-int nds32_write_buffer(struct target *target, uint32_t address,
- uint32_t size, const uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- LOG_DEBUG("WRITE BUFFER: ADDR %08" PRIx32 " SIZE %08" PRIx32,
- address,
- size);
-
- struct aice_port_s *aice = target_to_aice(target);
- int retval = ERROR_OK;
- uint32_t end_address;
-
- if (((address % 2) == 0) && (size == 2)) {
- nds32_select_memory_mode(target, address, 2, &end_address);
- return aice_write_mem_unit(aice, address, 2, 1, buffer);
- }
-
- /* handle unaligned head bytes */
- if (address % 4) {
- uint32_t unaligned = 4 - (address % 4);
-
- if (unaligned > size)
- unaligned = size;
-
- nds32_select_memory_mode(target, address, unaligned, &end_address);
- retval = aice_write_mem_unit(aice, address, 1, unaligned, buffer);
- if (retval != ERROR_OK)
- return retval;
-
- buffer += unaligned;
- address += unaligned;
- size -= unaligned;
- }
-
- /* handle aligned words */
- if (size >= 4) {
- int aligned = size - (size % 4);
- int write_len;
-
- do {
- nds32_select_memory_mode(target, address, aligned, &end_address);
-
- write_len = end_address - address;
- if (write_len > 8)
- retval = aice_write_mem_bulk(aice, address, write_len, buffer);
- else
- retval = aice_write_mem_unit(aice, address, 4, write_len / 4, buffer);
- if (retval != ERROR_OK)
- return retval;
-
- buffer += write_len;
- address += write_len;
- size -= write_len;
- aligned -= write_len;
-
- } while (aligned != 0);
- }
-
- /* handle tail writes of less than 4 bytes */
- if (size > 0) {
- nds32_select_memory_mode(target, address, size, &end_address);
- retval = aice_write_mem_unit(aice, address, 1, size, buffer);
- if (retval != ERROR_OK)
- return retval;
- }
-
- return retval;
-}
-
-int nds32_write_memory(struct target *target, uint32_t address,
- uint32_t size, uint32_t count, const uint8_t *buffer)
-{
- struct aice_port_s *aice = target_to_aice(target);
-
- return aice_write_mem_unit(aice, address, size, count, buffer);
-}
-
-int nds32_write_phys_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, const uint8_t *buffer)
-{
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
- enum nds_memory_access orig_channel;
- int result;
-
- /* switch to BUS access mode to skip MMU */
- orig_channel = memory->access_channel;
- memory->access_channel = NDS_MEMORY_ACC_BUS;
- aice_memory_access(aice, memory->access_channel);
-
- /* The input address is physical address. No need to do address translation. */
- result = aice_write_mem_unit(aice, address, size, count, buffer);
-
- /* restore to origin access mode */
- memory->access_channel = orig_channel;
- aice_memory_access(aice, memory->access_channel);
-
- return result;
-}
-
-int nds32_mmu(struct target *target, int *enabled)
-{
- if (target->state != TARGET_HALTED) {
- LOG_ERROR("%s: target not halted", __func__);
- return ERROR_TARGET_INVALID;
- }
-
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
- struct nds32_mmu_config *mmu_config = &(nds32->mmu_config);
-
- if ((mmu_config->memory_protection == 2) && (memory->address_translation == true))
- *enabled = 1;
- else
- *enabled = 0;
-
- return ERROR_OK;
-}
-
-int nds32_arch_state(struct target *target)
-{
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (nds32->common_magic != NDS32_COMMON_MAGIC) {
- LOG_ERROR("BUG: called for a non-Andes target");
- return ERROR_FAIL;
- }
-
- uint32_t value_pc, value_psw;
-
- nds32_get_mapped_reg(nds32, PC, &value_pc);
- nds32_get_mapped_reg(nds32, IR0, &value_psw);
-
- LOG_USER("target halted due to %s\n"
- "psw: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s",
- debug_reason_name(target),
- value_psw,
- value_pc,
- nds32->virtual_hosting ? ", virtual hosting" : "");
-
- /* save pc value to pseudo register pc */
- struct reg *reg = register_get_by_name(target->reg_cache, "pc", true);
- buf_set_u32(reg->value, 0, 32, value_pc);
-
- return ERROR_OK;
-}
-
-static void nds32_init_must_have_registers(struct nds32 *nds32)
-{
- struct reg_cache *reg_cache = nds32->core_cache;
-
- /** MUST have general registers */
- ((struct nds32_reg *)reg_cache->reg_list[R0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R3].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R4].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R5].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R6].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R7].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R8].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R9].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R10].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R15].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R28].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R29].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R30].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R31].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[PC].arch_info)->enable = true;
-
- /** MUST have configuration system registers */
- ((struct nds32_reg *)reg_cache->reg_list[CR0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CR1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CR2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CR3].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CR4].arch_info)->enable = true;
-
- /** MUST have interrupt system registers */
- ((struct nds32_reg *)reg_cache->reg_list[IR0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR3].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR4].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR6].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR9].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR11].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR14].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR15].arch_info)->enable = true;
-
- /** MUST have MMU system registers */
- ((struct nds32_reg *)reg_cache->reg_list[MR0].arch_info)->enable = true;
-
- /** MUST have EDM system registers */
- ((struct nds32_reg *)reg_cache->reg_list[DR40].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DR42].arch_info)->enable = true;
-}
-
-static int nds32_init_memory_config(struct nds32 *nds32)
-{
- uint32_t value_cr1; /* ICM_CFG */
- uint32_t value_cr2; /* DCM_CFG */
- struct nds32_memory *memory = &(nds32->memory);
-
- /* read $cr1 to init instruction memory information */
- nds32_get_mapped_reg(nds32, CR1, &value_cr1);
- memory->icache.set = value_cr1 & 0x7;
- memory->icache.way = (value_cr1 >> 3) & 0x7;
- memory->icache.line_size = (value_cr1 >> 6) & 0x7;
- memory->icache.lock_support = (value_cr1 >> 9) & 0x1;
-
- memory->ilm_base = (value_cr1 >> 10) & 0x7;
- memory->ilm_align_ver = (value_cr1 >> 13) & 0x3;
-
- /* read $cr2 to init data memory information */
- nds32_get_mapped_reg(nds32, CR2, &value_cr2);
- memory->dcache.set = value_cr2 & 0x7;
- memory->dcache.way = (value_cr2 >> 3) & 0x7;
- memory->dcache.line_size = (value_cr2 >> 6) & 0x7;
- memory->dcache.lock_support = (value_cr2 >> 9) & 0x1;
-
- memory->dlm_base = (value_cr2 >> 10) & 0x7;
- memory->dlm_align_ver = (value_cr2 >> 13) & 0x3;
-
- return ERROR_OK;
-}
-
-static void nds32_init_config(struct nds32 *nds32)
-{
- uint32_t value_cr0;
- uint32_t value_cr3;
- uint32_t value_cr4;
- struct nds32_cpu_version *cpu_version = &(nds32->cpu_version);
- struct nds32_mmu_config *mmu_config = &(nds32->mmu_config);
- struct nds32_misc_config *misc_config = &(nds32->misc_config);
-
- nds32_get_mapped_reg(nds32, CR0, &value_cr0);
- nds32_get_mapped_reg(nds32, CR3, &value_cr3);
- nds32_get_mapped_reg(nds32, CR4, &value_cr4);
-
- /* config cpu version */
- cpu_version->performance_extension = value_cr0 & 0x1;
- cpu_version->_16bit_extension = (value_cr0 >> 1) & 0x1;
- cpu_version->performance_extension_2 = (value_cr0 >> 2) & 0x1;
- cpu_version->cop_fpu_extension = (value_cr0 >> 3) & 0x1;
- cpu_version->string_extension = (value_cr0 >> 4) & 0x1;
- cpu_version->revision = (value_cr0 >> 16) & 0xFF;
- cpu_version->cpu_id_family = (value_cr0 >> 24) & 0xF;
- cpu_version->cpu_id_version = (value_cr0 >> 28) & 0xF;
-
- /* config MMU */
- mmu_config->memory_protection = value_cr3 & 0x3;
- mmu_config->memory_protection_version = (value_cr3 >> 2) & 0x1F;
- mmu_config->fully_associative_tlb = (value_cr3 >> 7) & 0x1;
- if (mmu_config->fully_associative_tlb) {
- mmu_config->tlb_size = (value_cr3 >> 8) & 0x7F;
- } else {
- mmu_config->tlb_ways = (value_cr3 >> 8) & 0x7;
- mmu_config->tlb_sets = (value_cr3 >> 11) & 0x7;
- }
- mmu_config->_8k_page_support = (value_cr3 >> 15) & 0x1;
- mmu_config->extra_page_size_support = (value_cr3 >> 16) & 0xFF;
- mmu_config->tlb_lock = (value_cr3 >> 24) & 0x1;
- mmu_config->hardware_page_table_walker = (value_cr3 >> 25) & 0x1;
- mmu_config->default_endian = (value_cr3 >> 26) & 0x1;
- mmu_config->partition_num = (value_cr3 >> 27) & 0x1;
- mmu_config->invisible_tlb = (value_cr3 >> 28) & 0x1;
- mmu_config->vlpt = (value_cr3 >> 29) & 0x1;
- mmu_config->ntme = (value_cr3 >> 30) & 0x1;
- mmu_config->drde = (value_cr3 >> 31) & 0x1;
-
- /* config misc */
- misc_config->edm = value_cr4 & 0x1;
- misc_config->local_memory_dma = (value_cr4 >> 1) & 0x1;
- misc_config->performance_monitor = (value_cr4 >> 2) & 0x1;
- misc_config->high_speed_memory_port = (value_cr4 >> 3) & 0x1;
- misc_config->debug_tracer = (value_cr4 >> 4) & 0x1;
- misc_config->div_instruction = (value_cr4 >> 5) & 0x1;
- misc_config->mac_instruction = (value_cr4 >> 6) & 0x1;
- misc_config->audio_isa = (value_cr4 >> 7) & 0x3;
- misc_config->l2_cache = (value_cr4 >> 9) & 0x1;
- misc_config->reduce_register = (value_cr4 >> 10) & 0x1;
- misc_config->addr_24 = (value_cr4 >> 11) & 0x1;
- misc_config->interruption_level = (value_cr4 >> 12) & 0x1;
- misc_config->baseline_instruction = (value_cr4 >> 13) & 0x7;
- misc_config->no_dx_register = (value_cr4 >> 16) & 0x1;
- misc_config->implement_dependant_register = (value_cr4 >> 17) & 0x1;
- misc_config->implement_dependant_sr_encoding = (value_cr4 >> 18) & 0x1;
- misc_config->ifc = (value_cr4 >> 19) & 0x1;
- misc_config->mcu = (value_cr4 >> 20) & 0x1;
- misc_config->shadow = (value_cr4 >> 21) & 0x7;
- misc_config->ex9 = (value_cr4 >> 24) & 0x1;
-
- nds32_init_memory_config(nds32);
-}
-
-static int nds32_init_option_registers(struct nds32 *nds32)
-{
- struct reg_cache *reg_cache = nds32->core_cache;
- struct nds32_cpu_version *cpu_version = &(nds32->cpu_version);
- struct nds32_mmu_config *mmu_config = &(nds32->mmu_config);
- struct nds32_misc_config *misc_config = &(nds32->misc_config);
- struct nds32_memory *memory_config = &(nds32->memory);
-
- bool no_cr5;
- bool mr10_exist;
- bool no_racr0;
-
- if (((cpu_version->cpu_id_family == 0xC) || (cpu_version->cpu_id_family == 0xD)) &&
- ((cpu_version->revision & 0xFC) == 0)) {
- no_cr5 = true;
- mr10_exist = true;
- no_racr0 = true;
- } else {
- no_cr5 = false;
- mr10_exist = false;
- no_racr0 = false;
- }
-
- if (misc_config->reduce_register == false) {
- ((struct nds32_reg *)reg_cache->reg_list[R11].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R12].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R13].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R14].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R16].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R17].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R18].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R19].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R20].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R21].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R22].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R23].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R24].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R25].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R26].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[R27].arch_info)->enable = true;
- }
-
- if (misc_config->no_dx_register == false) {
- ((struct nds32_reg *)reg_cache->reg_list[D0LO].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[D0HI].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[D1LO].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[D1HI].arch_info)->enable = true;
- }
-
- if (misc_config->ex9)
- ((struct nds32_reg *)reg_cache->reg_list[ITB].arch_info)->enable = true;
-
- if (no_cr5 == false)
- ((struct nds32_reg *)reg_cache->reg_list[CR5].arch_info)->enable = true;
-
- if (cpu_version->cop_fpu_extension) {
- ((struct nds32_reg *)reg_cache->reg_list[CR6].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[FPCSR].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[FPCFG].arch_info)->enable = true;
- }
-
- if (mmu_config->memory_protection == 1) {
- /* Secure MPU has no IPC, IPSW, P_ITYPE */
- ((struct nds32_reg *)reg_cache->reg_list[IR1].arch_info)->enable = false;
- ((struct nds32_reg *)reg_cache->reg_list[IR9].arch_info)->enable = false;
- }
-
- if (nds32->privilege_level != 0)
- ((struct nds32_reg *)reg_cache->reg_list[IR3].arch_info)->enable = false;
-
- if (misc_config->mcu == true)
- ((struct nds32_reg *)reg_cache->reg_list[IR4].arch_info)->enable = false;
-
- if (misc_config->interruption_level == false) {
- ((struct nds32_reg *)reg_cache->reg_list[IR2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR5].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR10].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR12].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR13].arch_info)->enable = true;
-
- /* Secure MPU has no IPC, IPSW, P_ITYPE */
- if (mmu_config->memory_protection != 1)
- ((struct nds32_reg *)reg_cache->reg_list[IR7].arch_info)->enable = true;
- }
-
- if ((cpu_version->cpu_id_family == 0x9) ||
- (cpu_version->cpu_id_family == 0xA) ||
- (cpu_version->cpu_id_family == 0xC) ||
- (cpu_version->cpu_id_family == 0xD))
- ((struct nds32_reg *)reg_cache->reg_list[IR8].arch_info)->enable = true;
-
- if (misc_config->shadow == 1) {
- ((struct nds32_reg *)reg_cache->reg_list[IR16].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR17].arch_info)->enable = true;
- }
-
- if (misc_config->ifc)
- ((struct nds32_reg *)reg_cache->reg_list[IFC_LP].arch_info)->enable = true;
-
- if (nds32->privilege_level != 0)
- ((struct nds32_reg *)reg_cache->reg_list[MR0].arch_info)->enable = false;
-
- if (mmu_config->memory_protection == 1) {
- if (mmu_config->memory_protection_version == 24)
- ((struct nds32_reg *)reg_cache->reg_list[MR4].arch_info)->enable = true;
-
- if (nds32->privilege_level == 0) {
- if ((mmu_config->memory_protection_version == 16) ||
- (mmu_config->memory_protection_version == 24)) {
- ((struct nds32_reg *)reg_cache->reg_list[MR11].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[SECUR0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR20].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR22].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR24].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR30].arch_info)->enable = true;
-
- if (misc_config->shadow == 1) {
- ((struct nds32_reg *)reg_cache->reg_list[IR21].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR23].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR25].arch_info)->enable = true;
- }
- }
- }
- } else if (mmu_config->memory_protection == 2) {
- ((struct nds32_reg *)reg_cache->reg_list[MR1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[MR4].arch_info)->enable = true;
-
- if ((cpu_version->cpu_id_family != 0xA) && (cpu_version->cpu_id_family != 0xC) &&
- (cpu_version->cpu_id_family != 0xD))
- ((struct nds32_reg *)reg_cache->reg_list[MR5].arch_info)->enable = true;
- }
-
- if (mmu_config->memory_protection > 0) {
- ((struct nds32_reg *)reg_cache->reg_list[MR2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[MR3].arch_info)->enable = true;
- }
-
- if (memory_config->ilm_base != 0)
- if (nds32->privilege_level == 0)
- ((struct nds32_reg *)reg_cache->reg_list[MR6].arch_info)->enable = true;
-
- if (memory_config->dlm_base != 0)
- if (nds32->privilege_level == 0)
- ((struct nds32_reg *)reg_cache->reg_list[MR7].arch_info)->enable = true;
-
- if ((memory_config->icache.line_size != 0) && (memory_config->dcache.line_size != 0))
- ((struct nds32_reg *)reg_cache->reg_list[MR8].arch_info)->enable = true;
-
- if (misc_config->high_speed_memory_port)
- ((struct nds32_reg *)reg_cache->reg_list[MR9].arch_info)->enable = true;
-
- if (mr10_exist)
- ((struct nds32_reg *)reg_cache->reg_list[MR10].arch_info)->enable = true;
-
- if (misc_config->edm) {
- int dr_reg_n = nds32->edm.breakpoint_num * 5;
-
- for (int i = 0 ; i < dr_reg_n ; i++)
- ((struct nds32_reg *)reg_cache->reg_list[DR0 + i].arch_info)->enable = true;
-
- ((struct nds32_reg *)reg_cache->reg_list[DR41].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DR43].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DR44].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DR45].arch_info)->enable = true;
- }
-
- if (misc_config->debug_tracer) {
- ((struct nds32_reg *)reg_cache->reg_list[DR46].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DR47].arch_info)->enable = true;
- }
-
- if (misc_config->performance_monitor) {
- ((struct nds32_reg *)reg_cache->reg_list[PFR0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[PFR1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[PFR2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[PFR3].arch_info)->enable = true;
- }
-
- if (misc_config->local_memory_dma) {
- ((struct nds32_reg *)reg_cache->reg_list[DMAR0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR3].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR4].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR5].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR6].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR7].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR8].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR9].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[DMAR10].arch_info)->enable = true;
- }
-
- if ((misc_config->local_memory_dma || misc_config->performance_monitor) &&
- (no_racr0 == false))
- ((struct nds32_reg *)reg_cache->reg_list[RACR].arch_info)->enable = true;
-
- if (cpu_version->cop_fpu_extension || (misc_config->audio_isa != 0))
- ((struct nds32_reg *)reg_cache->reg_list[FUCPR].arch_info)->enable = true;
-
- if (misc_config->audio_isa != 0) {
- if (misc_config->audio_isa > 1) {
- ((struct nds32_reg *)reg_cache->reg_list[D0L24].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[D1L24].arch_info)->enable = true;
- }
-
- ((struct nds32_reg *)reg_cache->reg_list[I0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[I1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[I2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[I3].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[I4].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[I5].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[I6].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[I7].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[M1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[M2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[M3].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[M5].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[M6].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[M7].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[MOD].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[LBE].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[LE].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[LC].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[ADM_VBASE].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[SHFT_CTL0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[SHFT_CTL1].arch_info)->enable = true;
-
- uint32_t value_mod;
- uint32_t fucpr_backup;
- /* enable fpu and get configuration */
- nds32_get_mapped_reg(nds32, FUCPR, &fucpr_backup);
- if ((fucpr_backup & 0x80000000) == 0)
- nds32_set_mapped_reg(nds32, FUCPR, fucpr_backup | 0x80000000);
- nds32_get_mapped_reg(nds32, MOD, &value_mod);
- /* restore origin fucpr value */
- if ((fucpr_backup & 0x80000000) == 0)
- nds32_set_mapped_reg(nds32, FUCPR, fucpr_backup);
-
- if ((value_mod >> 6) & 0x1) {
- ((struct nds32_reg *)reg_cache->reg_list[CB_CTL].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CBB0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CBB1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CBB2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CBB3].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CBE0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CBE1].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CBE2].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[CBE3].arch_info)->enable = true;
- }
- }
-
- if ((cpu_version->cpu_id_family == 0x9) ||
- (cpu_version->cpu_id_family == 0xA) ||
- (cpu_version->cpu_id_family == 0xC)) {
-
- ((struct nds32_reg *)reg_cache->reg_list[IDR0].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IDR1].arch_info)->enable = true;
-
- if ((cpu_version->cpu_id_family == 0xC) && (cpu_version->revision == 0x0C))
- ((struct nds32_reg *)reg_cache->reg_list[IDR0].arch_info)->enable = false;
- }
-
- uint32_t ir3_value;
- uint32_t ivb_prog_pri_lvl;
- uint32_t ivb_ivic_ver;
-
- nds32_get_mapped_reg(nds32, IR3, &ir3_value);
- ivb_prog_pri_lvl = ir3_value & 0x1;
- ivb_ivic_ver = (ir3_value >> 11) & 0x3;
-
- if ((ivb_prog_pri_lvl == 1) || (ivb_ivic_ver >= 1)) {
- ((struct nds32_reg *)reg_cache->reg_list[IR18].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR19].arch_info)->enable = true;
- }
-
- if (ivb_ivic_ver >= 1) {
- ((struct nds32_reg *)reg_cache->reg_list[IR26].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR27].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR28].arch_info)->enable = true;
- ((struct nds32_reg *)reg_cache->reg_list[IR29].arch_info)->enable = true;
- }
-
- return ERROR_OK;
-}
-
-int nds32_init_register_table(struct nds32 *nds32)
-{
- nds32_init_must_have_registers(nds32);
-
- return ERROR_OK;
-}
-
-int nds32_add_software_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
-{
- uint32_t data;
- uint32_t check_data;
- uint32_t break_insn;
-
- /* check the breakpoint size */
- target->type->read_buffer(target, breakpoint->address, 4, (uint8_t *)&data);
-
- /* backup origin instruction
- * instruction is big-endian */
- if (*(char *)&data & 0x80) { /* 16-bits instruction */
- breakpoint->length = 2;
- break_insn = NDS32_BREAK_16;
- } else { /* 32-bits instruction */
- breakpoint->length = 4;
- break_insn = NDS32_BREAK_32;
- }
-
- free(breakpoint->orig_instr);
-
- breakpoint->orig_instr = malloc(breakpoint->length);
- memcpy(breakpoint->orig_instr, &data, breakpoint->length);
-
- /* self-modified code */
- target->type->write_buffer(target, breakpoint->address, breakpoint->length, (const uint8_t *)&break_insn);
- /* write_back & invalidate dcache & invalidate icache */
- nds32_cache_sync(target, breakpoint->address, breakpoint->length);
-
- /* read back to check */
- target->type->read_buffer(target, breakpoint->address, breakpoint->length, (uint8_t *)&check_data);
- if (memcmp(&check_data, &break_insn, breakpoint->length) == 0)
- return ERROR_OK;
-
- return ERROR_FAIL;
-}
-
-int nds32_remove_software_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
-{
- uint32_t check_data;
- uint32_t break_insn;
-
- if (breakpoint->length == 2)
- break_insn = NDS32_BREAK_16;
- else if (breakpoint->length == 4)
- break_insn = NDS32_BREAK_32;
- else
- return ERROR_FAIL;
-
- target->type->read_buffer(target, breakpoint->address, breakpoint->length,
- (uint8_t *)&check_data);
-
- /* break instruction is modified */
- if (memcmp(&check_data, &break_insn, breakpoint->length) != 0)
- return ERROR_FAIL;
-
- /* self-modified code */
- target->type->write_buffer(target, breakpoint->address, breakpoint->length,
- breakpoint->orig_instr);
-
- /* write_back & invalidate dcache & invalidate icache */
- nds32_cache_sync(target, breakpoint->address, breakpoint->length);
-
- return ERROR_OK;
-}
-
-/**
- * Restore the processor context on an Andes target. The full processor
- * context is analyzed to see if any of the registers are dirty on this end, but
- * have a valid new value. If this is the case, the processor is changed to the
- * appropriate mode and the new register values are written out to the
- * processor. If there happens to be a dirty register with an invalid value, an
- * error will be logged.
- *
- * @param target Pointer to the Andes target to have its context restored
- * @return Error status if the target is not halted.
- */
-int nds32_restore_context(struct target *target)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct reg_cache *reg_cache = nds32->core_cache;
- struct reg *reg;
- struct nds32_reg *reg_arch_info;
- unsigned int i;
-
- LOG_DEBUG("-");
-
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- /* check if there are dirty registers */
- for (i = 0; i < reg_cache->num_regs; i++) {
- reg = &(reg_cache->reg_list[i]);
- if (reg->dirty == true) {
- if (reg->valid == true) {
-
- LOG_DEBUG("examining dirty reg: %s", reg->name);
- LOG_DEBUG("writing register %d with value 0x%8.8" PRIx32,
- i, buf_get_u32(reg->value, 0, 32));
-
- reg_arch_info = reg->arch_info;
- if (reg_arch_info->num >= FD0 && reg_arch_info->num <= FD31) {
- uint64_t val = buf_get_u64(reg_arch_info->value, 0, 64);
- aice_write_reg_64(aice, reg_arch_info->num, val);
- } else {
- uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32);
- aice_write_register(aice, reg_arch_info->num, val);
- }
-
- reg->valid = true;
- reg->dirty = false;
- }
- }
- }
-
- return ERROR_OK;
-}
-
-int nds32_edm_config(struct nds32 *nds32)
-{
- struct target *target = nds32->target;
- struct aice_port_s *aice = target_to_aice(target);
- uint32_t edm_cfg;
- uint32_t edm_ctl;
-
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
-
- nds32->edm.version = (edm_cfg >> 16) & 0xFFFF;
- LOG_INFO("EDM version 0x%04x", nds32->edm.version);
-
- nds32->edm.breakpoint_num = (edm_cfg & 0x7) + 1;
-
- if ((nds32->edm.version & 0x1000) || (nds32->edm.version >= 0x60))
- nds32->edm.access_control = true;
- else
- nds32->edm.access_control = false;
-
- if ((edm_cfg >> 4) & 0x1)
- nds32->edm.direct_access_local_memory = true;
- else
- nds32->edm.direct_access_local_memory = false;
-
- if (nds32->edm.version <= 0x20)
- nds32->edm.direct_access_local_memory = false;
-
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl);
- if (edm_ctl & (0x1 << 29))
- nds32->edm.support_max_stop = true;
- else
- nds32->edm.support_max_stop = false;
-
- /* set passcode for secure MCU */
- nds32_login(nds32);
-
- return ERROR_OK;
-}
-
-int nds32_config(struct nds32 *nds32)
-{
- nds32_init_config(nds32);
-
- /* init optional system registers according to config registers */
- nds32_init_option_registers(nds32);
-
- /* get max interrupt level */
- if (nds32->misc_config.interruption_level)
- nds32->max_interrupt_level = 2;
- else
- nds32->max_interrupt_level = 3;
-
- /* get ILM/DLM size from MR6/MR7 */
- uint32_t value_mr6, value_mr7;
- uint32_t size_index;
- nds32_get_mapped_reg(nds32, MR6, &value_mr6);
- size_index = (value_mr6 >> 1) & 0xF;
- nds32->memory.ilm_size = nds32_lm_size_table[size_index];
-
- nds32_get_mapped_reg(nds32, MR7, &value_mr7);
- size_index = (value_mr7 >> 1) & 0xF;
- nds32->memory.dlm_size = nds32_lm_size_table[size_index];
-
- return ERROR_OK;
-}
-
-int nds32_init_arch_info(struct target *target, struct nds32 *nds32)
-{
- target->arch_info = nds32;
- nds32->target = target;
-
- nds32->common_magic = NDS32_COMMON_MAGIC;
- nds32->init_arch_info_after_halted = false;
- nds32->auto_convert_hw_bp = true;
- nds32->global_stop = false;
- nds32->soft_reset_halt = false;
- nds32->edm_passcode = NULL;
- nds32->privilege_level = 0;
- nds32->boot_time = 1500;
- nds32->reset_halt_as_examine = false;
- nds32->keep_target_edm_ctl = false;
- nds32->word_access_mem = false;
- nds32->virtual_hosting = true;
- nds32->hit_syscall = false;
- nds32->active_syscall_id = NDS32_SYSCALL_UNDEFINED;
- nds32->virtual_hosting_errno = 0;
- nds32->virtual_hosting_ctrl_c = false;
- nds32->attached = false;
-
- nds32->syscall_break.asid = 0;
- nds32->syscall_break.length = 4;
- nds32->syscall_break.is_set = false;
- nds32->syscall_break.orig_instr = NULL;
- nds32->syscall_break.next = NULL;
- nds32->syscall_break.unique_id = 0x515CAll + target->target_number;
- nds32->syscall_break.linked_brp = 0;
-
- nds32_reg_init();
-
- if (nds32_reg_cache_init(target, nds32) == ERROR_FAIL)
- return ERROR_FAIL;
-
- if (nds32_init_register_table(nds32) != ERROR_OK)
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-int nds32_virtual_to_physical(struct target *target, target_addr_t address, target_addr_t *physical)
-{
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (nds32->memory.address_translation == false) {
- *physical = address;
- return ERROR_OK;
- }
-
- if (nds32_probe_tlb(nds32, address, physical) == ERROR_OK)
- return ERROR_OK;
-
- if (nds32_walk_page_table(nds32, address, physical) == ERROR_OK)
- return ERROR_OK;
-
- return ERROR_FAIL;
-}
-
-int nds32_cache_sync(struct target *target, target_addr_t address, uint32_t length)
-{
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_cache *dcache = &(nds32->memory.dcache);
- struct nds32_cache *icache = &(nds32->memory.icache);
- uint32_t dcache_line_size = nds32_line_size_table[dcache->line_size];
- uint32_t icache_line_size = nds32_line_size_table[icache->line_size];
- uint32_t cur_address;
- int result;
- uint32_t start_line, end_line;
- uint32_t cur_line;
-
- if ((dcache->line_size != 0) && (dcache->enable == true)) {
- /* address / dcache_line_size */
- start_line = address >> (dcache->line_size + 2);
- /* (address + length - 1) / dcache_line_size */
- end_line = (address + length - 1) >> (dcache->line_size + 2);
-
- for (cur_address = address, cur_line = start_line;
- cur_line <= end_line;
- cur_address += dcache_line_size, cur_line++) {
- /* D$ write back */
- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_VA_WB, cur_address);
- if (result != ERROR_OK)
- return result;
-
- /* D$ invalidate */
- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_VA_INVAL, cur_address);
- if (result != ERROR_OK)
- return result;
- }
- }
-
- if ((icache->line_size != 0) && (icache->enable == true)) {
- /* address / icache_line_size */
- start_line = address >> (icache->line_size + 2);
- /* (address + length - 1) / icache_line_size */
- end_line = (address + length - 1) >> (icache->line_size + 2);
-
- for (cur_address = address, cur_line = start_line;
- cur_line <= end_line;
- cur_address += icache_line_size, cur_line++) {
- /* Because PSW.IT is turned off under debug exception, address MUST
- * be physical address. L1I_VA_INVALIDATE uses PSW.IT to decide
- * address translation or not. */
- target_addr_t physical_addr;
- if (target->type->virt2phys(target, cur_address, &physical_addr) == ERROR_FAIL)
- return ERROR_FAIL;
-
- /* I$ invalidate */
- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_VA_INVAL, physical_addr);
- if (result != ERROR_OK)
- return result;
- }
- }
-
- return ERROR_OK;
-}
-
-uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address)
-{
- if (!current)
- nds32_set_mapped_reg(nds32, PC, address);
- else
- nds32_get_mapped_reg(nds32, PC, &address);
-
- return address;
-}
-
-int nds32_step(struct target *target, int current,
- target_addr_t address, int handle_breakpoints)
-{
- LOG_DEBUG("target->state: %s",
- target_state_name(target));
-
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- struct nds32 *nds32 = target_to_nds32(target);
-
- address = nds32_nextpc(nds32, current, address);
-
- LOG_DEBUG("STEP PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
-
- /** set DSSIM */
- uint32_t ir14_value;
- nds32_get_mapped_reg(nds32, IR14, &ir14_value);
- if (nds32->step_isr_enable)
- ir14_value |= (0x1 << 31);
- else
- ir14_value &= ~(0x1 << 31);
- nds32_set_mapped_reg(nds32, IR14, ir14_value);
-
- /* check hit_syscall before leave_debug_state() because
- * leave_debug_state() may clear hit_syscall flag */
- bool no_step = false;
- if (nds32->hit_syscall)
- /* step after hit_syscall should be ignored because
- * leave_debug_state will step implicitly to skip the
- * syscall */
- no_step = true;
-
- /********* TODO: maybe create another function to handle this part */
- CHECK_RETVAL(nds32->leave_debug_state(nds32, true));
- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
-
- if (no_step == false) {
- struct aice_port_s *aice = target_to_aice(target);
- if (aice_step(aice) != ERROR_OK)
- return ERROR_FAIL;
- }
-
- /* save state */
- CHECK_RETVAL(nds32->enter_debug_state(nds32, true));
- /********* TODO: maybe create another function to handle this part */
-
- /* restore DSSIM */
- if (nds32->step_isr_enable) {
- nds32_get_mapped_reg(nds32, IR14, &ir14_value);
- ir14_value &= ~(0x1 << 31);
- nds32_set_mapped_reg(nds32, IR14, ir14_value);
- }
-
- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));
-
- return ERROR_OK;
-}
-
-static int nds32_step_without_watchpoint(struct nds32 *nds32)
-{
- struct target *target = nds32->target;
-
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- /** set DSSIM */
- uint32_t ir14_value;
- nds32_get_mapped_reg(nds32, IR14, &ir14_value);
- if (nds32->step_isr_enable)
- ir14_value |= (0x1 << 31);
- else
- ir14_value &= ~(0x1 << 31);
- nds32_set_mapped_reg(nds32, IR14, ir14_value);
-
- /********* TODO: maybe create another function to handle this part */
- CHECK_RETVAL(nds32->leave_debug_state(nds32, false));
-
- struct aice_port_s *aice = target_to_aice(target);
-
- if (aice_step(aice) != ERROR_OK)
- return ERROR_FAIL;
-
- /* save state */
- CHECK_RETVAL(nds32->enter_debug_state(nds32, false));
- /********* TODO: maybe create another function to handle this part */
-
- /* restore DSSIM */
- if (nds32->step_isr_enable) {
- nds32_get_mapped_reg(nds32, IR14, &ir14_value);
- ir14_value &= ~(0x1 << 31);
- nds32_set_mapped_reg(nds32, IR14, ir14_value);
- }
-
- return ERROR_OK;
-}
-
-int nds32_target_state(struct nds32 *nds32, enum target_state *state)
-{
- struct aice_port_s *aice = target_to_aice(nds32->target);
- enum aice_target_state_s nds32_state;
-
- if (aice_state(aice, &nds32_state) != ERROR_OK)
- return ERROR_FAIL;
-
- switch (nds32_state) {
- case AICE_DISCONNECT:
- LOG_INFO("USB is disconnected");
- return ERROR_FAIL;
- case AICE_TARGET_DETACH:
- LOG_INFO("Target is disconnected");
- return ERROR_FAIL;
- case AICE_TARGET_UNKNOWN:
- *state = TARGET_UNKNOWN;
- break;
- case AICE_TARGET_RUNNING:
- *state = TARGET_RUNNING;
- break;
- case AICE_TARGET_HALTED:
- *state = TARGET_HALTED;
- break;
- case AICE_TARGET_RESET:
- *state = TARGET_RESET;
- break;
- case AICE_TARGET_DEBUG_RUNNING:
- *state = TARGET_DEBUG_RUNNING;
- break;
- default:
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-int nds32_examine_debug_reason(struct nds32 *nds32)
-{
- uint32_t reason;
- struct target *target = nds32->target;
-
- if (nds32->hit_syscall == true) {
- LOG_DEBUG("Hit syscall breakpoint");
- target->debug_reason = DBG_REASON_BREAKPOINT;
- return ERROR_OK;
- }
-
- nds32->get_debug_reason(nds32, &reason);
-
- LOG_DEBUG("nds32 examines debug reason: %s", nds32_debug_type_name[reason]);
-
- /* Examine debug reason */
- switch (reason) {
- case NDS32_DEBUG_BREAK:
- case NDS32_DEBUG_BREAK_16:
- case NDS32_DEBUG_INST_BREAK:
- {
- uint32_t value_pc;
- uint32_t opcode;
- struct nds32_instruction instruction;
-
- nds32_get_mapped_reg(nds32, PC, &value_pc);
-
- if (nds32_read_opcode(nds32, value_pc, &opcode) != ERROR_OK)
- return ERROR_FAIL;
- if (nds32_evaluate_opcode(nds32, opcode, value_pc, &instruction) != ERROR_OK)
- return ERROR_FAIL;
-
- /* hit 'break 0x7FFF' */
- if ((instruction.info.opc_6 == 0x32) &&
- (instruction.info.sub_opc == 0xA) &&
- (instruction.info.imm == 0x7FFF)) {
- target->debug_reason = DBG_REASON_EXIT;
- } else
- target->debug_reason = DBG_REASON_BREAKPOINT;
- }
- break;
- case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE:
- case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_PRECISE:
- case NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP: /* GLOBAL_STOP is precise exception */
- {
- int result;
-
- result = nds32->get_watched_address(nds32,
- &(nds32->watched_address), reason);
- /* do single step(without watchpoints) to skip the "watched" instruction */
- nds32_step_without_watchpoint(nds32);
-
- /* before single_step, save exception address */
- if (result != ERROR_OK)
- return ERROR_FAIL;
-
- target->debug_reason = DBG_REASON_WATCHPOINT;
- }
- break;
- case NDS32_DEBUG_DEBUG_INTERRUPT:
- target->debug_reason = DBG_REASON_DBGRQ;
- break;
- case NDS32_DEBUG_HARDWARE_SINGLE_STEP:
- target->debug_reason = DBG_REASON_SINGLESTEP;
- break;
- case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_IMPRECISE:
- case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE:
- case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE:
- if (nds32->get_watched_address(nds32, &(nds32->watched_address), reason) != ERROR_OK)
- return ERROR_FAIL;
-
- target->debug_reason = DBG_REASON_WATCHPOINT;
- break;
- default:
- target->debug_reason = DBG_REASON_UNDEFINED;
- break;
- }
-
- return ERROR_OK;
-}
-
-int nds32_login(struct nds32 *nds32)
-{
- struct target *target = nds32->target;
- struct aice_port_s *aice = target_to_aice(target);
- uint32_t passcode_length;
- char command_sequence[129];
- char command_str[33];
- char code_str[9];
- uint32_t copy_length;
- uint32_t code;
- uint32_t i;
-
- LOG_DEBUG("nds32_login");
-
- if (nds32->edm_passcode) {
- /* convert EDM passcode to command sequences */
- passcode_length = strlen(nds32->edm_passcode);
- command_sequence[0] = '\0';
- for (i = 0; i < passcode_length; i += 8) {
- if (passcode_length - i < 8)
- copy_length = passcode_length - i;
- else
- copy_length = 8;
-
- strncpy(code_str, nds32->edm_passcode + i, copy_length);
- code_str[copy_length] = '\0';
- code = strtoul(code_str, NULL, 16);
-
- sprintf(command_str, "write_misc gen_port0 0x%" PRIx32 ";", code);
- strcat(command_sequence, command_str);
- }
-
- if (aice_program_edm(aice, command_sequence) != ERROR_OK)
- return ERROR_FAIL;
-
- /* get current privilege level */
- uint32_t value_edmsw;
- aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &value_edmsw);
- nds32->privilege_level = (value_edmsw >> 16) & 0x3;
- LOG_INFO("Current privilege level: %d", nds32->privilege_level);
- }
-
- if (nds32_edm_ops_num > 0) {
- const char *reg_name;
- for (i = 0 ; i < nds32_edm_ops_num ; i++) {
- code = nds32_edm_ops[i].value;
- if (nds32_edm_ops[i].reg_no == 6)
- reg_name = "gen_port0";
- else if (nds32_edm_ops[i].reg_no == 7)
- reg_name = "gen_port1";
- else
- return ERROR_FAIL;
-
- sprintf(command_str, "write_misc %s 0x%" PRIx32 ";", reg_name, code);
- if (aice_program_edm(aice, command_str) != ERROR_OK)
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
-}
-
-int nds32_halt(struct target *target)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
- enum target_state state;
-
- LOG_DEBUG("target->state: %s",
- target_state_name(target));
-
- if (target->state == TARGET_HALTED) {
- LOG_DEBUG("target was already halted");
- return ERROR_OK;
- }
-
- if (nds32_target_state(nds32, &state) != ERROR_OK)
- return ERROR_FAIL;
-
- if (state != TARGET_HALTED)
- /* TODO: if state == TARGET_HALTED, check ETYPE is DBGI or not */
- if (aice_halt(aice) != ERROR_OK)
- return ERROR_FAIL;
-
- CHECK_RETVAL(nds32->enter_debug_state(nds32, true));
-
- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));
-
- return ERROR_OK;
-}
-
-/* poll current target status */
-int nds32_poll(struct target *target)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- enum target_state state;
-
- if (nds32_target_state(nds32, &state) != ERROR_OK)
- return ERROR_FAIL;
-
- if (state == TARGET_HALTED) {
- if (target->state != TARGET_HALTED) {
- /* if false_hit, continue free_run */
- if (nds32->enter_debug_state(nds32, true) != ERROR_OK) {
- struct aice_port_s *aice = target_to_aice(target);
- aice_run(aice);
- return ERROR_OK;
- }
-
- LOG_DEBUG("Change target state to TARGET_HALTED.");
-
- target_call_event_callbacks(target, TARGET_EVENT_HALTED);
- }
- } else if (state == TARGET_RESET) {
- if (target->state == TARGET_HALTED) {
- /* similar to assert srst */
- register_cache_invalidate(nds32->core_cache);
- target->state = TARGET_RESET;
-
- /* TODO: deassert srst */
- } else if (target->state == TARGET_RUNNING) {
- /* reset as running */
- LOG_WARNING("<-- TARGET WARNING! The debug target has been reset. -->");
- }
- } else {
- if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) {
- LOG_DEBUG("Change target state to TARGET_RUNNING.");
- target->state = TARGET_RUNNING;
- target->debug_reason = DBG_REASON_NOTHALTED;
- }
- }
-
- return ERROR_OK;
-}
-
-int nds32_resume(struct target *target, int current,
- target_addr_t address, int handle_breakpoints, int debug_execution)
-{
- LOG_DEBUG("current %d address %08" TARGET_PRIxADDR
- " handle_breakpoints %d"
- " debug_execution %d",
- current, address, handle_breakpoints, debug_execution);
-
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- address = nds32_nextpc(nds32, current, address);
-
- LOG_DEBUG("RESUME PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
-
- if (!debug_execution)
- target_free_all_working_areas(target);
-
- /* Disable HSS to avoid users misuse HSS */
- if (nds32_reach_max_interrupt_level(nds32) == false) {
- uint32_t value_ir0;
- nds32_get_mapped_reg(nds32, IR0, &value_ir0);
- value_ir0 &= ~(0x1 << 11);
- nds32_set_mapped_reg(nds32, IR0, value_ir0);
- }
-
- CHECK_RETVAL(nds32->leave_debug_state(nds32, true));
- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
-
- if (nds32->virtual_hosting_ctrl_c == false) {
- struct aice_port_s *aice = target_to_aice(target);
- aice_run(aice);
- } else
- nds32->virtual_hosting_ctrl_c = false;
-
- target->debug_reason = DBG_REASON_NOTHALTED;
- if (!debug_execution)
- target->state = TARGET_RUNNING;
- else
- target->state = TARGET_DEBUG_RUNNING;
-
- LOG_DEBUG("target->state: %s",
- target_state_name(target));
-
- return ERROR_OK;
-}
-
-static int nds32_soft_reset_halt(struct target *target)
-{
- /* TODO: test it */
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
-
- aice_assert_srst(aice, AICE_SRST);
-
- /* halt core and set pc to 0x0 */
- int retval = target_halt(target);
- if (retval != ERROR_OK)
- return retval;
-
- /* start fetching from IVB */
- uint32_t value_ir3;
- nds32_get_mapped_reg(nds32, IR3, &value_ir3);
- nds32_set_mapped_reg(nds32, PC, value_ir3 & 0xFFFF0000);
-
- return ERROR_OK;
-}
-
-int nds32_assert_reset(struct target *target)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_cpu_version *cpu_version = &(nds32->cpu_version);
-
- /* TODO: apply hw reset signal in not examined state */
- if (!(target_was_examined(target))) {
- LOG_WARNING("Reset is not asserted because the target is not examined.");
- LOG_WARNING("Use a reset button or power cycle the target.");
- return ERROR_TARGET_NOT_EXAMINED;
- }
-
- if (target->reset_halt) {
- if ((nds32->soft_reset_halt)
- || (nds32->edm.version < 0x51)
- || ((nds32->edm.version == 0x51)
- && (cpu_version->revision == 0x1C)
- && (cpu_version->cpu_id_family == 0xC)
- && (cpu_version->cpu_id_version == 0x0)))
- nds32_soft_reset_halt(target);
- else
- aice_assert_srst(aice, AICE_RESET_HOLD);
- } else {
- aice_assert_srst(aice, AICE_SRST);
- alive_sleep(nds32->boot_time);
- }
-
- /* set passcode for secure MCU after core reset */
- nds32_login(nds32);
-
- /* registers are now invalid */
- register_cache_invalidate(nds32->core_cache);
-
- target->state = TARGET_RESET;
-
- return ERROR_OK;
-}
-
-static int nds32_gdb_attach(struct nds32 *nds32)
-{
- LOG_DEBUG("nds32_gdb_attach, target coreid: %" PRId32, nds32->target->coreid);
-
- if (nds32->attached == false) {
-
- if (nds32->keep_target_edm_ctl) {
- /* backup target EDM_CTL */
- struct aice_port_s *aice = target_to_aice(nds32->target);
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &nds32->backup_edm_ctl);
- }
-
- target_halt(nds32->target);
-
- nds32->attached = true;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_gdb_detach(struct nds32 *nds32)
-{
- LOG_DEBUG("nds32_gdb_detach");
- bool backup_virtual_hosting_setting;
-
- if (nds32->attached) {
-
- backup_virtual_hosting_setting = nds32->virtual_hosting;
- /* turn off virtual hosting before resume as gdb-detach */
- nds32->virtual_hosting = false;
- target_resume(nds32->target, 1, 0, 0, 0);
- nds32->virtual_hosting = backup_virtual_hosting_setting;
-
- if (nds32->keep_target_edm_ctl) {
- /* restore target EDM_CTL */
- struct aice_port_s *aice = target_to_aice(nds32->target);
- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, nds32->backup_edm_ctl);
- }
-
- nds32->attached = false;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_callback_event_handler(struct target *target,
- enum target_event event, void *priv)
-{
- int retval = ERROR_OK;
- int target_number = *(int *)priv;
-
- if (target_number != target->target_number)
- return ERROR_OK;
-
- struct nds32 *nds32 = target_to_nds32(target);
-
- switch (event) {
- case TARGET_EVENT_GDB_ATTACH:
- retval = nds32_gdb_attach(nds32);
- break;
- case TARGET_EVENT_GDB_DETACH:
- retval = nds32_gdb_detach(nds32);
- break;
- default:
- break;
- }
-
- return retval;
-}
-
-int nds32_init(struct nds32 *nds32)
-{
- /* Initialize anything we can set up without talking to the target */
- nds32->memory.access_channel = NDS_MEMORY_ACC_CPU;
-
- /* register event callback */
- target_register_event_callback(nds32_callback_event_handler,
- &(nds32->target->target_number));
-
- return ERROR_OK;
-}
-
-int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info)
-{
- /* fill syscall parameters to file-I/O info */
- if (!fileio_info) {
- LOG_ERROR("Target has not initial file-I/O data structure");
- return ERROR_FAIL;
- }
-
- struct nds32 *nds32 = target_to_nds32(target);
- uint32_t value_ir6;
- uint32_t syscall_id;
-
- if (nds32->hit_syscall == false)
- return ERROR_FAIL;
-
- nds32_get_mapped_reg(nds32, IR6, &value_ir6);
- syscall_id = (value_ir6 >> 16) & 0x7FFF;
- nds32->active_syscall_id = syscall_id;
-
- LOG_DEBUG("hit syscall ID: 0x%" PRIx32, syscall_id);
-
- /* free previous identifier storage */
- free(fileio_info->identifier);
- fileio_info->identifier = NULL;
-
- uint32_t reg_r0, reg_r1, reg_r2;
- nds32_get_mapped_reg(nds32, R0, &reg_r0);
- nds32_get_mapped_reg(nds32, R1, &reg_r1);
- nds32_get_mapped_reg(nds32, R2, &reg_r2);
-
- switch (syscall_id) {
- case NDS32_SYSCALL_EXIT:
- fileio_info->identifier = malloc(5);
- sprintf(fileio_info->identifier, "exit");
- fileio_info->param_1 = reg_r0;
- break;
- case NDS32_SYSCALL_OPEN:
- {
- uint8_t filename[256];
- fileio_info->identifier = malloc(5);
- sprintf(fileio_info->identifier, "open");
- fileio_info->param_1 = reg_r0;
- /* reserve fileio_info->param_2 for length of path */
- fileio_info->param_3 = reg_r1;
- fileio_info->param_4 = reg_r2;
-
- target->type->read_buffer(target, reg_r0, 256, filename);
- fileio_info->param_2 = strlen((char *)filename);
- }
- break;
- case NDS32_SYSCALL_CLOSE:
- fileio_info->identifier = malloc(6);
- sprintf(fileio_info->identifier, "close");
- fileio_info->param_1 = reg_r0;
- break;
- case NDS32_SYSCALL_READ:
- fileio_info->identifier = malloc(5);
- sprintf(fileio_info->identifier, "read");
- fileio_info->param_1 = reg_r0;
- fileio_info->param_2 = reg_r1;
- fileio_info->param_3 = reg_r2;
- break;
- case NDS32_SYSCALL_WRITE:
- fileio_info->identifier = malloc(6);
- sprintf(fileio_info->identifier, "write");
- fileio_info->param_1 = reg_r0;
- fileio_info->param_2 = reg_r1;
- fileio_info->param_3 = reg_r2;
- break;
- case NDS32_SYSCALL_LSEEK:
- fileio_info->identifier = malloc(6);
- sprintf(fileio_info->identifier, "lseek");
- fileio_info->param_1 = reg_r0;
- fileio_info->param_2 = reg_r1;
- fileio_info->param_3 = reg_r2;
- break;
- case NDS32_SYSCALL_UNLINK:
- {
- uint8_t filename[256];
- fileio_info->identifier = malloc(7);
- sprintf(fileio_info->identifier, "unlink");
- fileio_info->param_1 = reg_r0;
- /* reserve fileio_info->param_2 for length of path */
-
- target->type->read_buffer(target, reg_r0, 256, filename);
- fileio_info->param_2 = strlen((char *)filename);
- }
- break;
- case NDS32_SYSCALL_RENAME:
- {
- uint8_t filename[256];
- fileio_info->identifier = malloc(7);
- sprintf(fileio_info->identifier, "rename");
- fileio_info->param_1 = reg_r0;
- /* reserve fileio_info->param_2 for length of old path */
- fileio_info->param_3 = reg_r1;
- /* reserve fileio_info->param_4 for length of new path */
-
- target->type->read_buffer(target, reg_r0, 256, filename);
- fileio_info->param_2 = strlen((char *)filename);
-
- target->type->read_buffer(target, reg_r1, 256, filename);
- fileio_info->param_4 = strlen((char *)filename);
- }
- break;
- case NDS32_SYSCALL_FSTAT:
- fileio_info->identifier = malloc(6);
- sprintf(fileio_info->identifier, "fstat");
- fileio_info->param_1 = reg_r0;
- fileio_info->param_2 = reg_r1;
- break;
- case NDS32_SYSCALL_STAT:
- {
- uint8_t filename[256];
- fileio_info->identifier = malloc(5);
- sprintf(fileio_info->identifier, "stat");
- fileio_info->param_1 = reg_r0;
- /* reserve fileio_info->param_2 for length of old path */
- fileio_info->param_3 = reg_r1;
-
- target->type->read_buffer(target, reg_r0, 256, filename);
- fileio_info->param_2 = strlen((char *)filename) + 1;
- }
- break;
- case NDS32_SYSCALL_GETTIMEOFDAY:
- fileio_info->identifier = malloc(13);
- sprintf(fileio_info->identifier, "gettimeofday");
- fileio_info->param_1 = reg_r0;
- fileio_info->param_2 = reg_r1;
- break;
- case NDS32_SYSCALL_ISATTY:
- fileio_info->identifier = malloc(7);
- sprintf(fileio_info->identifier, "isatty");
- fileio_info->param_1 = reg_r0;
- break;
- case NDS32_SYSCALL_SYSTEM:
- {
- uint8_t command[256];
- fileio_info->identifier = malloc(7);
- sprintf(fileio_info->identifier, "system");
- fileio_info->param_1 = reg_r0;
- /* reserve fileio_info->param_2 for length of old path */
-
- target->type->read_buffer(target, reg_r0, 256, command);
- fileio_info->param_2 = strlen((char *)command);
- }
- break;
- case NDS32_SYSCALL_ERRNO:
- fileio_info->identifier = malloc(6);
- sprintf(fileio_info->identifier, "errno");
- nds32_set_mapped_reg(nds32, R0, nds32->virtual_hosting_errno);
- break;
- default:
- fileio_info->identifier = malloc(8);
- sprintf(fileio_info->identifier, "unknown");
- break;
- }
-
- return ERROR_OK;
-}
-
-int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c)
-{
- LOG_DEBUG("syscall return code: 0x%x, errno: 0x%x , ctrl_c: %s",
- retcode, fileio_errno, ctrl_c ? "true" : "false");
-
- struct nds32 *nds32 = target_to_nds32(target);
-
- nds32_set_mapped_reg(nds32, R0, (uint32_t)retcode);
-
- nds32->virtual_hosting_errno = fileio_errno;
- nds32->virtual_hosting_ctrl_c = ctrl_c;
- nds32->active_syscall_id = NDS32_SYSCALL_UNDEFINED;
-
- return ERROR_OK;
-}
-
-int nds32_profiling(struct target *target, uint32_t *samples,
- uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
-{
- /* sample $PC every 10 milliseconds */
- uint32_t iteration = seconds * 100;
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32 *nds32 = target_to_nds32(target);
-
- /* REVISIT: can nds32 profile without halting? */
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted (profiling)", target->cmd_name);
- return ERROR_TARGET_NOT_HALTED;
- }
-
- if (max_num_samples < iteration)
- iteration = max_num_samples;
-
- int pc_regnum = nds32->register_map(nds32, PC);
- aice_profiling(aice, 10, iteration, pc_regnum, samples, num_samples);
-
- register_cache_invalidate(nds32->core_cache);
-
- return ERROR_OK;
-}
-
-int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address,
- uint32_t size, const uint8_t *buffer)
-{
- if ((nds32->active_syscall_id == NDS32_SYSCALL_FSTAT) ||
- (nds32->active_syscall_id == NDS32_SYSCALL_STAT)) {
- /* If doing GDB file-I/O, target should convert 'struct stat'
- * from gdb-format to target-format */
- uint8_t stat_buffer[NDS32_STRUCT_STAT_SIZE];
- /* st_dev 2 */
- stat_buffer[0] = buffer[3];
- stat_buffer[1] = buffer[2];
- /* st_ino 2 */
- stat_buffer[2] = buffer[7];
- stat_buffer[3] = buffer[6];
- /* st_mode 4 */
- stat_buffer[4] = buffer[11];
- stat_buffer[5] = buffer[10];
- stat_buffer[6] = buffer[9];
- stat_buffer[7] = buffer[8];
- /* st_nlink 2 */
- stat_buffer[8] = buffer[15];
- stat_buffer[9] = buffer[16];
- /* st_uid 2 */
- stat_buffer[10] = buffer[19];
- stat_buffer[11] = buffer[18];
- /* st_gid 2 */
- stat_buffer[12] = buffer[23];
- stat_buffer[13] = buffer[22];
- /* st_rdev 2 */
- stat_buffer[14] = buffer[27];
- stat_buffer[15] = buffer[26];
- /* st_size 4 */
- stat_buffer[16] = buffer[35];
- stat_buffer[17] = buffer[34];
- stat_buffer[18] = buffer[33];
- stat_buffer[19] = buffer[32];
- /* st_atime 4 */
- stat_buffer[20] = buffer[55];
- stat_buffer[21] = buffer[54];
- stat_buffer[22] = buffer[53];
- stat_buffer[23] = buffer[52];
- /* st_spare1 4 */
- stat_buffer[24] = 0;
- stat_buffer[25] = 0;
- stat_buffer[26] = 0;
- stat_buffer[27] = 0;
- /* st_mtime 4 */
- stat_buffer[28] = buffer[59];
- stat_buffer[29] = buffer[58];
- stat_buffer[30] = buffer[57];
- stat_buffer[31] = buffer[56];
- /* st_spare2 4 */
- stat_buffer[32] = 0;
- stat_buffer[33] = 0;
- stat_buffer[34] = 0;
- stat_buffer[35] = 0;
- /* st_ctime 4 */
- stat_buffer[36] = buffer[63];
- stat_buffer[37] = buffer[62];
- stat_buffer[38] = buffer[61];
- stat_buffer[39] = buffer[60];
- /* st_spare3 4 */
- stat_buffer[40] = 0;
- stat_buffer[41] = 0;
- stat_buffer[42] = 0;
- stat_buffer[43] = 0;
- /* st_blksize 4 */
- stat_buffer[44] = buffer[43];
- stat_buffer[45] = buffer[42];
- stat_buffer[46] = buffer[41];
- stat_buffer[47] = buffer[40];
- /* st_blocks 4 */
- stat_buffer[48] = buffer[51];
- stat_buffer[49] = buffer[50];
- stat_buffer[50] = buffer[49];
- stat_buffer[51] = buffer[48];
- /* st_spare4 8 */
- stat_buffer[52] = 0;
- stat_buffer[53] = 0;
- stat_buffer[54] = 0;
- stat_buffer[55] = 0;
- stat_buffer[56] = 0;
- stat_buffer[57] = 0;
- stat_buffer[58] = 0;
- stat_buffer[59] = 0;
-
- return nds32_write_buffer(nds32->target, address, NDS32_STRUCT_STAT_SIZE, stat_buffer);
- } else if (nds32->active_syscall_id == NDS32_SYSCALL_GETTIMEOFDAY) {
- /* If doing GDB file-I/O, target should convert 'struct timeval'
- * from gdb-format to target-format */
- uint8_t timeval_buffer[NDS32_STRUCT_TIMEVAL_SIZE];
- timeval_buffer[0] = buffer[3];
- timeval_buffer[1] = buffer[2];
- timeval_buffer[2] = buffer[1];
- timeval_buffer[3] = buffer[0];
- timeval_buffer[4] = buffer[11];
- timeval_buffer[5] = buffer[10];
- timeval_buffer[6] = buffer[9];
- timeval_buffer[7] = buffer[8];
-
- return nds32_write_buffer(nds32->target, address, NDS32_STRUCT_TIMEVAL_SIZE, timeval_buffer);
- }
-
- return nds32_write_buffer(nds32->target, address, size, buffer);
-}
-
-int nds32_reset_halt(struct nds32 *nds32)
-{
- LOG_INFO("reset halt as init");
-
- struct aice_port_s *aice = target_to_aice(nds32->target);
- aice_assert_srst(aice, AICE_RESET_HOLD);
-
- return ERROR_OK;
-}
diff --git a/src/target/nds32.h b/src/target/nds32.h
deleted file mode 100644
index d0b680a..0000000
--- a/src/target/nds32.h
+++ /dev/null
@@ -1,447 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_H
-#define OPENOCD_TARGET_NDS32_H
-
-#include <jtag/jtag.h>
-#include "target.h"
-#include "target_type.h"
-#include "register.h"
-#include "breakpoints.h"
-#include "nds32_reg.h"
-#include "nds32_insn.h"
-#include "nds32_edm.h"
-
-#define NDS32_EDM_OPERATION_MAX_NUM 64
-
-#define CHECK_RETVAL(action) \
- do { \
- int __retval = (action); \
- if (__retval != ERROR_OK) { \
- LOG_DEBUG("error while calling \"%s\"", \
- # action); \
- return __retval; \
- } \
- } while (0)
-
-/**
- * @file
- * Holds the interface to Andes cores.
- */
-
-extern const char *nds32_debug_type_name[11];
-
-enum nds32_debug_reason {
- NDS32_DEBUG_BREAK = 0,
- NDS32_DEBUG_BREAK_16,
- NDS32_DEBUG_INST_BREAK,
- NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE,
- NDS32_DEBUG_DATA_VALUE_WATCHPOINT_PRECISE,
- NDS32_DEBUG_DATA_VALUE_WATCHPOINT_IMPRECISE,
- NDS32_DEBUG_DEBUG_INTERRUPT,
- NDS32_DEBUG_HARDWARE_SINGLE_STEP,
- NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE,
- NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE,
- NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP,
-};
-
-#define NDS32_STRUCT_STAT_SIZE 60
-#define NDS32_STRUCT_TIMEVAL_SIZE 8
-
-enum nds32_syscall_id {
- NDS32_SYSCALL_UNDEFINED = 0,
- NDS32_SYSCALL_EXIT = 1,
- NDS32_SYSCALL_OPEN = 2,
- NDS32_SYSCALL_CLOSE = 3,
- NDS32_SYSCALL_READ = 4,
- NDS32_SYSCALL_WRITE = 5,
- NDS32_SYSCALL_LSEEK = 6,
- NDS32_SYSCALL_UNLINK = 7,
- NDS32_SYSCALL_RENAME = 3001,
- NDS32_SYSCALL_FSTAT = 10,
- NDS32_SYSCALL_STAT = 15,
- NDS32_SYSCALL_GETTIMEOFDAY = 19,
- NDS32_SYSCALL_ISATTY = 3002,
- NDS32_SYSCALL_SYSTEM = 3003,
- NDS32_SYSCALL_ERRNO = 6001,
-};
-
-#define NDS32_COMMON_MAGIC 0xADE5ADE5U
-
-struct nds32_edm {
-
- /** EDM_CFG.VER, indicate the EDM version */
- int version;
-
- /** The number of hardware breakpoints */
- int breakpoint_num;
-
- /** EDM_CFG.DALM, indicate if direct local memory access
- * feature is supported or not */
- bool direct_access_local_memory;
-
- /** Support ACC_CTL register */
- bool access_control;
-
- /** */
- bool support_max_stop;
-};
-
-struct nds32_cache {
-
- /** enable cache or not */
- bool enable;
-
- /** cache sets per way */
- int set;
-
- /** cache ways */
- int way;
-
- /** cache line size */
- int line_size;
-
- /** cache locking support */
- bool lock_support;
-};
-
-struct nds32_memory {
-
- /** ICache */
- struct nds32_cache icache;
-
- /** DCache */
- struct nds32_cache dcache;
-
- /** On-chip instruction local memory base */
- int ilm_base;
-
- /** On-chip instruction local memory size */
- int ilm_size;
-
- /** ILM base register alignment version */
- int ilm_align_ver;
-
- /** DLM is enabled or not */
- bool ilm_enable;
-
- /** DLM start address */
- int ilm_start;
-
- /** DLM end address */
- int ilm_end;
-
- /** On-chip data local memory base */
- int dlm_base;
-
- /** On-chip data local memory size */
- int dlm_size;
-
- /** DLM base register alignment version */
- int dlm_align_ver;
-
- /** DLM is enabled or not */
- bool dlm_enable;
-
- /** DLM start address */
- int dlm_start;
-
- /** DLM end address */
- int dlm_end;
-
- /** Memory access method */
- enum nds_memory_access access_channel;
-
- /** Memory access mode */
- enum nds_memory_select mode;
-
- /** Address translation */
- bool address_translation;
-};
-
-struct nds32_cpu_version {
- bool performance_extension;
- bool _16bit_extension;
- bool performance_extension_2;
- bool cop_fpu_extension;
- bool string_extension;
-
- int revision;
- int cpu_id_family;
- int cpu_id_version;
-};
-
-struct nds32_mmu_config {
- int memory_protection;
- int memory_protection_version;
- bool fully_associative_tlb;
- int tlb_size;
- int tlb_ways;
- int tlb_sets;
- bool _8k_page_support;
- int extra_page_size_support;
- bool tlb_lock;
- bool hardware_page_table_walker;
- bool default_endian;
- int partition_num;
- bool invisible_tlb;
- bool vlpt;
- bool ntme;
- bool drde;
- int default_min_page_size;
- bool multiple_page_size_in_use;
-};
-
-struct nds32_misc_config {
- bool edm;
- bool local_memory_dma;
- bool performance_monitor;
- bool high_speed_memory_port;
- bool debug_tracer;
- bool div_instruction;
- bool mac_instruction;
- int audio_isa;
- bool l2_cache;
- bool reduce_register;
- bool addr_24;
- bool interruption_level;
- int baseline_instruction;
- bool no_dx_register;
- bool implement_dependant_register;
- bool implement_dependant_sr_encoding;
- bool ifc;
- bool mcu;
- bool ex9;
- int shadow;
-};
-
-/**
- * Represents a generic Andes core.
- */
-struct nds32 {
- unsigned int common_magic;
-
- struct reg_cache *core_cache;
-
- /** Handle for the debug module. */
- struct nds32_edm edm;
-
- /** Memory information */
- struct nds32_memory memory;
-
- /** cpu version */
- struct nds32_cpu_version cpu_version;
-
- /** MMU configuration */
- struct nds32_mmu_config mmu_config;
-
- /** Misc configuration */
- struct nds32_misc_config misc_config;
-
- /** Retrieve all core registers, for display. */
- int (*full_context)(struct nds32 *nds32);
-
- /** Register mappings */
- int (*register_map)(struct nds32 *nds32, int reg_no);
-
- /** Get debug exception virtual address */
- int (*get_debug_reason)(struct nds32 *nds32, uint32_t *reason);
-
- /** Restore target registers may be modified in debug state */
- int (*leave_debug_state)(struct nds32 *nds32, bool enable_watchpoint);
-
- /** Backup target registers may be modified in debug state */
- int (*enter_debug_state)(struct nds32 *nds32, bool enable_watchpoint);
-
- /** Get address hit watchpoint */
- int (*get_watched_address)(struct nds32 *nds32, uint32_t *address, uint32_t reason);
-
- /** maximum interrupt level */
- uint32_t max_interrupt_level;
-
- /** current interrupt level */
- uint32_t current_interrupt_level;
-
- uint32_t watched_address;
-
- /** Flag reporting whether virtual hosting is active. */
- bool virtual_hosting;
-
- /** Flag reporting whether continue/step hits syscall or not */
- bool hit_syscall;
-
- /** Value to be returned by virtual hosting SYS_ERRNO request. */
- int virtual_hosting_errno;
-
- /** Flag reporting whether syscall is aborted */
- bool virtual_hosting_ctrl_c;
-
- /** Record syscall ID for other operations to do special processing for target */
- int active_syscall_id;
-
- struct breakpoint syscall_break;
-
- /** Flag reporting whether global stop is active. */
- bool global_stop;
-
- /** Flag reporting whether to use soft-reset-halt or not as issuing reset-halt. */
- bool soft_reset_halt;
-
- /** reset-halt as target examine */
- bool reset_halt_as_examine;
-
- /** backup/restore target EDM_CTL value. As debugging target debug
- * handler, it should be true. */
- bool keep_target_edm_ctl;
-
- /* Value of $EDM_CTL before target enters debug mode */
- uint32_t backup_edm_ctl;
-
- /** always use word-aligned address to access memory */
- bool word_access_mem;
-
- /** EDM passcode for debugging secure MCU */
- char *edm_passcode;
-
- /** current privilege_level if using secure MCU. value 0 is the highest level. */
- int privilege_level;
-
- /** Period to wait after SRST. */
- uint32_t boot_time;
-
- /** Flag to indicate HSS steps into ISR or not */
- bool step_isr_enable;
-
- /** Flag to indicate register table is ready or not */
- bool init_arch_info_after_halted;
-
- /** Flag to indicate audio-extension is enabled or not */
- bool audio_enable;
-
- /** Flag to indicate fpu-extension is enabled or not */
- bool fpu_enable;
-
- /* Andes Core has mixed endian model. Instruction is always big-endian.
- * Data may be big or little endian. Device registers may have different
- * endian from data and instruction. */
- /** Endian of data memory */
- enum target_endianness data_endian;
-
- /** Endian of device registers */
- enum target_endianness device_reg_endian;
-
- /** Flag to indicate if auto convert software breakpoints to
- * hardware breakpoints or not in ROM */
- bool auto_convert_hw_bp;
-
- /* Flag to indicate the target is attached by debugger or not */
- bool attached;
-
- /** Backpointer to the target. */
- struct target *target;
-
- void *arch_info;
-};
-
-struct nds32_reg {
- int32_t num;
- uint8_t value[8];
- struct target *target;
- struct nds32 *nds32;
- bool enable;
-};
-
-struct nds32_edm_operation {
- uint32_t reg_no;
- uint32_t value;
-};
-
-extern int nds32_config(struct nds32 *nds32);
-extern int nds32_init_arch_info(struct target *target, struct nds32 *nds32);
-extern int nds32_full_context(struct nds32 *nds32);
-extern int nds32_arch_state(struct target *target);
-extern int nds32_add_software_breakpoint(struct target *target,
- struct breakpoint *breakpoint);
-extern int nds32_remove_software_breakpoint(struct target *target,
- struct breakpoint *breakpoint);
-
-extern int nds32_get_gdb_reg_list(struct target *target,
- struct reg **reg_list[], int *reg_list_size,
- enum target_register_class reg_class);
-
-extern int nds32_write_buffer(struct target *target, uint32_t address,
- uint32_t size, const uint8_t *buffer);
-extern int nds32_read_buffer(struct target *target, uint32_t address,
- uint32_t size, uint8_t *buffer);
-extern int nds32_read_memory(struct target *target, uint32_t address,
- uint32_t size, uint32_t count, uint8_t *buffer);
-extern int nds32_write_memory(struct target *target, uint32_t address,
- uint32_t size, uint32_t count, const uint8_t *buffer);
-
-extern int nds32_init_register_table(struct nds32 *nds32);
-extern int nds32_init_memory_info(struct nds32 *nds32);
-extern int nds32_restore_context(struct target *target);
-extern int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value);
-extern int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value);
-
-extern int nds32_edm_config(struct nds32 *nds32);
-extern int nds32_cache_sync(struct target *target, target_addr_t address, uint32_t length);
-extern int nds32_mmu(struct target *target, int *enabled);
-extern int nds32_virtual_to_physical(struct target *target, target_addr_t address,
- target_addr_t *physical);
-extern int nds32_read_phys_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, uint8_t *buffer);
-extern int nds32_write_phys_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, const uint8_t *buffer);
-extern uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address);
-extern int nds32_examine_debug_reason(struct nds32 *nds32);
-extern int nds32_step(struct target *target, int current,
- target_addr_t address, int handle_breakpoints);
-extern int nds32_target_state(struct nds32 *nds32, enum target_state *state);
-extern int nds32_halt(struct target *target);
-extern int nds32_poll(struct target *target);
-extern int nds32_resume(struct target *target, int current,
- target_addr_t address, int handle_breakpoints, int debug_execution);
-extern int nds32_assert_reset(struct target *target);
-extern int nds32_init(struct nds32 *nds32);
-extern int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info);
-extern int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address,
- uint32_t size, const uint8_t *buffer);
-extern int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c);
-extern int nds32_reset_halt(struct nds32 *nds32);
-extern int nds32_login(struct nds32 *nds32);
-extern int nds32_profiling(struct target *target, uint32_t *samples,
- uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);
-
-/** Convert target handle to generic Andes target state handle. */
-static inline struct nds32 *target_to_nds32(struct target *target)
-{
- assert(target);
- return target->arch_info;
-}
-
-/** */
-static inline struct aice_port_s *target_to_aice(struct target *target)
-{
- assert(target);
- return target->tap->priv;
-}
-
-static inline bool is_nds32(struct nds32 *nds32)
-{
- assert(nds32);
- return nds32->common_magic == NDS32_COMMON_MAGIC;
-}
-
-static inline bool nds32_reach_max_interrupt_level(struct nds32 *nds32)
-{
- assert(nds32);
- return nds32->max_interrupt_level == nds32->current_interrupt_level;
-}
-
-#endif /* OPENOCD_TARGET_NDS32_H */
diff --git a/src/target/nds32_aice.c b/src/target/nds32_aice.c
deleted file mode 100644
index 8dc4d77..0000000
--- a/src/target/nds32_aice.c
+++ /dev/null
@@ -1,147 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes technology. *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <helper/log.h>
-#include "nds32_aice.h"
-
-int aice_read_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t *val)
-{
- if (!aice->port->api->read_reg_64) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->read_reg_64(aice->coreid, num, val);
-}
-
-int aice_write_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t val)
-{
- if (!aice->port->api->write_reg_64) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->write_reg_64(aice->coreid, num, val);
-}
-
-int aice_read_tlb(struct aice_port_s *aice, target_addr_t virtual_address,
- target_addr_t *physical_address)
-{
- if (!aice->port->api->read_tlb) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->read_tlb(aice->coreid, virtual_address, physical_address);
-}
-
-int aice_cache_ctl(struct aice_port_s *aice, uint32_t subtype, uint32_t address)
-{
- if (!aice->port->api->cache_ctl) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->cache_ctl(aice->coreid, subtype, address);
-}
-
-int aice_set_retry_times(struct aice_port_s *aice, uint32_t a_retry_times)
-{
- if (!aice->port->api->set_retry_times) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->set_retry_times(a_retry_times);
-}
-
-int aice_program_edm(struct aice_port_s *aice, char *command_sequence)
-{
- if (!aice->port->api->program_edm) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->program_edm(aice->coreid, command_sequence);
-}
-
-int aice_set_command_mode(struct aice_port_s *aice,
- enum aice_command_mode command_mode)
-{
- if (!aice->port->api->set_command_mode) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->set_command_mode(command_mode);
-}
-
-int aice_execute(struct aice_port_s *aice, uint32_t *instructions,
- uint32_t instruction_num)
-{
- if (!aice->port->api->execute) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->execute(aice->coreid, instructions, instruction_num);
-}
-
-int aice_set_custom_srst_script(struct aice_port_s *aice, const char *script)
-{
- if (!aice->port->api->set_custom_srst_script) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->set_custom_srst_script(script);
-}
-
-int aice_set_custom_trst_script(struct aice_port_s *aice, const char *script)
-{
- if (!aice->port->api->set_custom_trst_script) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->set_custom_trst_script(script);
-}
-
-int aice_set_custom_restart_script(struct aice_port_s *aice, const char *script)
-{
- if (!aice->port->api->set_custom_restart_script) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->set_custom_restart_script(script);
-}
-
-int aice_set_count_to_check_dbger(struct aice_port_s *aice, uint32_t count_to_check)
-{
- if (!aice->port->api->set_count_to_check_dbger) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->set_count_to_check_dbger(count_to_check);
-}
-
-int aice_profiling(struct aice_port_s *aice, uint32_t interval, uint32_t iteration,
- uint32_t reg_no, uint32_t *samples, uint32_t *num_samples)
-{
- if (!aice->port->api->profiling) {
- LOG_WARNING("Not implemented: %s", __func__);
- return ERROR_FAIL;
- }
-
- return aice->port->api->profiling(aice->coreid, interval, iteration,
- reg_no, samples, num_samples);
-}
diff --git a/src/target/nds32_aice.h b/src/target/nds32_aice.h
deleted file mode 100644
index 2a6c879..0000000
--- a/src/target/nds32_aice.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes technology. *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_AICE_H
-#define OPENOCD_TARGET_NDS32_AICE_H
-
-#include <jtag/aice/aice_port.h>
-
-int aice_read_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t *val);
-int aice_write_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t val);
-int aice_read_tlb(struct aice_port_s *aice, target_addr_t virtual_address,
- target_addr_t *physical_address);
-int aice_cache_ctl(struct aice_port_s *aice, uint32_t subtype, uint32_t address);
-int aice_set_retry_times(struct aice_port_s *aice, uint32_t a_retry_times);
-int aice_program_edm(struct aice_port_s *aice, char *command_sequence);
-int aice_set_command_mode(struct aice_port_s *aice,
- enum aice_command_mode command_mode);
-int aice_execute(struct aice_port_s *aice, uint32_t *instructions,
- uint32_t instruction_num);
-int aice_set_custom_srst_script(struct aice_port_s *aice, const char *script);
-int aice_set_custom_trst_script(struct aice_port_s *aice, const char *script);
-int aice_set_custom_restart_script(struct aice_port_s *aice, const char *script);
-int aice_set_count_to_check_dbger(struct aice_port_s *aice, uint32_t count_to_check);
-int aice_profiling(struct aice_port_s *aice, uint32_t interval, uint32_t iteration,
- uint32_t reg_no, uint32_t *samples, uint32_t *num_samples);
-
-static inline int aice_open(struct aice_port_s *aice, struct aice_port_param_s *param)
-{
- return aice->port->api->open(param);
-}
-
-static inline int aice_close(struct aice_port_s *aice)
-{
- return aice->port->api->close();
-}
-
-static inline int aice_reset(struct aice_port_s *aice)
-{
- return aice->port->api->reset();
-}
-
-static inline int aice_assert_srst(struct aice_port_s *aice,
- enum aice_srst_type_s srst)
-{
- return aice->port->api->assert_srst(aice->coreid, srst);
-}
-
-static inline int aice_run(struct aice_port_s *aice)
-{
- return aice->port->api->run(aice->coreid);
-}
-
-static inline int aice_halt(struct aice_port_s *aice)
-{
- return aice->port->api->halt(aice->coreid);
-}
-
-static inline int aice_step(struct aice_port_s *aice)
-{
- return aice->port->api->step(aice->coreid);
-}
-
-static inline int aice_read_register(struct aice_port_s *aice, uint32_t num,
- uint32_t *val)
-{
- return aice->port->api->read_reg(aice->coreid, num, val);
-}
-
-static inline int aice_write_register(struct aice_port_s *aice, uint32_t num,
- uint32_t val)
-{
- return aice->port->api->write_reg(aice->coreid, num, val);
-}
-
-static inline int aice_read_debug_reg(struct aice_port_s *aice, uint32_t addr,
- uint32_t *val)
-{
- return aice->port->api->read_debug_reg(aice->coreid, addr, val);
-}
-
-static inline int aice_write_debug_reg(struct aice_port_s *aice, uint32_t addr,
- const uint32_t val)
-{
- return aice->port->api->write_debug_reg(aice->coreid, addr, val);
-}
-
-static inline int aice_read_mem_unit(struct aice_port_s *aice, uint32_t addr,
- uint32_t size, uint32_t count, uint8_t *buffer)
-{
- return aice->port->api->read_mem_unit(aice->coreid, addr, size, count, buffer);
-}
-
-static inline int aice_write_mem_unit(struct aice_port_s *aice, uint32_t addr,
- uint32_t size, uint32_t count, const uint8_t *buffer)
-{
- return aice->port->api->write_mem_unit(aice->coreid, addr, size, count, buffer);
-}
-
-static inline int aice_read_mem_bulk(struct aice_port_s *aice, uint32_t addr,
- uint32_t length, uint8_t *buffer)
-{
- return aice->port->api->read_mem_bulk(aice->coreid, addr, length, buffer);
-}
-
-static inline int aice_write_mem_bulk(struct aice_port_s *aice, uint32_t addr,
- uint32_t length, const uint8_t *buffer)
-{
- return aice->port->api->write_mem_bulk(aice->coreid, addr, length, buffer);
-}
-
-static inline int aice_idcode(struct aice_port_s *aice, uint32_t *idcode,
- uint8_t *num_of_idcode)
-{
- return aice->port->api->idcode(idcode, num_of_idcode);
-}
-
-static inline int aice_state(struct aice_port_s *aice,
- enum aice_target_state_s *state)
-{
- return aice->port->api->state(aice->coreid, state);
-}
-
-static inline int aice_set_jtag_clock(struct aice_port_s *aice, uint32_t a_clock)
-{
- return aice->port->api->set_jtag_clock(a_clock);
-}
-
-static inline int aice_memory_access(struct aice_port_s *aice,
- enum nds_memory_access a_access)
-{
- return aice->port->api->memory_access(aice->coreid, a_access);
-}
-
-static inline int aice_memory_mode(struct aice_port_s *aice,
- enum nds_memory_select mem_select)
-{
- return aice->port->api->memory_mode(aice->coreid, mem_select);
-}
-
-static inline int aice_set_data_endian(struct aice_port_s *aice,
- enum aice_target_endian target_data_endian)
-{
- return aice->port->api->set_data_endian(aice->coreid, target_data_endian);
-}
-
-#endif /* OPENOCD_TARGET_NDS32_AICE_H */
diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c
deleted file mode 100644
index 37f7648..0000000
--- a/src/target/nds32_cmd.c
+++ /dev/null
@@ -1,1123 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <helper/command.h>
-#include "nds32.h"
-#include "nds32_aice.h"
-#include "nds32_disassembler.h"
-
-extern struct nds32_edm_operation nds32_edm_ops[NDS32_EDM_OPERATION_MAX_NUM];
-extern uint32_t nds32_edm_ops_num;
-
-static const char *const nds_memory_access_name[] = {
- "BUS",
- "CPU",
-};
-
-static const char *const nds_memory_select_name[] = {
- "AUTO",
- "MEM",
- "ILM",
- "DLM",
-};
-
-COMMAND_HANDLER(handle_nds32_dssim_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "on") == 0)
- nds32->step_isr_enable = true;
- if (strcmp(CMD_ARGV[0], "off") == 0)
- nds32->step_isr_enable = false;
- }
-
- command_print(CMD, "%s: $INT_MASK.DSSIM: %d", target_name(target),
- nds32->step_isr_enable);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_memory_access_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "bus") == 0)
- memory->access_channel = NDS_MEMORY_ACC_BUS;
- else if (strcmp(CMD_ARGV[0], "cpu") == 0)
- memory->access_channel = NDS_MEMORY_ACC_CPU;
- else /* default access channel is NDS_MEMORY_ACC_CPU */
- memory->access_channel = NDS_MEMORY_ACC_CPU;
-
- LOG_DEBUG("memory access channel is changed to %s",
- nds_memory_access_name[memory->access_channel]);
-
- aice_memory_access(aice, memory->access_channel);
- } else {
- command_print(CMD, "%s: memory access channel: %s",
- target_name(target),
- nds_memory_access_name[memory->access_channel]);
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_memory_mode_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
-
- if (nds32->edm.access_control == false) {
- command_print(CMD, "%s does not support ACC_CTL. "
- "Set memory mode to MEMORY", target_name(target));
- nds32->memory.mode = NDS_MEMORY_SELECT_MEM;
- } else if (nds32->edm.direct_access_local_memory == false) {
- command_print(CMD, "%s does not support direct access "
- "local memory. Set memory mode to MEMORY",
- target_name(target));
- nds32->memory.mode = NDS_MEMORY_SELECT_MEM;
-
- /* set to ACC_CTL */
- aice_memory_mode(aice, nds32->memory.mode);
- } else {
- if (strcmp(CMD_ARGV[0], "auto") == 0) {
- nds32->memory.mode = NDS_MEMORY_SELECT_AUTO;
- } else if (strcmp(CMD_ARGV[0], "mem") == 0) {
- nds32->memory.mode = NDS_MEMORY_SELECT_MEM;
- } else if (strcmp(CMD_ARGV[0], "ilm") == 0) {
- if (nds32->memory.ilm_base == 0)
- command_print(CMD, "%s does not support ILM",
- target_name(target));
- else
- nds32->memory.mode = NDS_MEMORY_SELECT_ILM;
- } else if (strcmp(CMD_ARGV[0], "dlm") == 0) {
- if (nds32->memory.dlm_base == 0)
- command_print(CMD, "%s does not support DLM",
- target_name(target));
- else
- nds32->memory.mode = NDS_MEMORY_SELECT_DLM;
- }
-
- /* set to ACC_CTL */
- aice_memory_mode(aice, nds32->memory.mode);
- }
- }
-
- command_print(CMD, "%s: memory mode: %s",
- target_name(target),
- nds_memory_select_name[nds32->memory.mode]);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_cache_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_cache *icache = &(nds32->memory.icache);
- struct nds32_cache *dcache = &(nds32->memory.dcache);
- int result;
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
-
- if (strcmp(CMD_ARGV[0], "invalidate") == 0) {
- if ((dcache->line_size != 0) && (dcache->enable == true)) {
- /* D$ write back */
- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0);
- if (result != ERROR_OK) {
- command_print(CMD, "%s: Write back data cache...failed",
- target_name(target));
- return result;
- }
-
- command_print(CMD, "%s: Write back data cache...done",
- target_name(target));
-
- /* D$ invalidate */
- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0);
- if (result != ERROR_OK) {
- command_print(CMD, "%s: Invalidate data cache...failed",
- target_name(target));
- return result;
- }
-
- command_print(CMD, "%s: Invalidate data cache...done",
- target_name(target));
- } else {
- if (dcache->line_size == 0)
- command_print(CMD, "%s: No data cache",
- target_name(target));
- else
- command_print(CMD, "%s: Data cache disabled",
- target_name(target));
- }
-
- if ((icache->line_size != 0) && (icache->enable == true)) {
- /* I$ invalidate */
- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0);
- if (result != ERROR_OK) {
- command_print(CMD, "%s: Invalidate instruction cache...failed",
- target_name(target));
- return result;
- }
-
- command_print(CMD, "%s: Invalidate instruction cache...done",
- target_name(target));
- } else {
- if (icache->line_size == 0)
- command_print(CMD, "%s: No instruction cache",
- target_name(target));
- else
- command_print(CMD, "%s: Instruction cache disabled",
- target_name(target));
- }
- } else
- command_print(CMD, "No valid parameter");
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_icache_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_cache *icache = &(nds32->memory.icache);
- int result;
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
-
- if (icache->line_size == 0) {
- command_print(CMD, "%s: No instruction cache",
- target_name(target));
- return ERROR_OK;
- }
-
- if (strcmp(CMD_ARGV[0], "invalidate") == 0) {
- if (icache->enable == true) {
- /* I$ invalidate */
- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0);
- if (result != ERROR_OK) {
- command_print(CMD, "%s: Invalidate instruction cache...failed",
- target_name(target));
- return result;
- }
-
- command_print(CMD, "%s: Invalidate instruction cache...done",
- target_name(target));
- } else {
- command_print(CMD, "%s: Instruction cache disabled",
- target_name(target));
- }
- } else if (strcmp(CMD_ARGV[0], "enable") == 0) {
- uint32_t value;
- nds32_get_mapped_reg(nds32, IR8, &value);
- nds32_set_mapped_reg(nds32, IR8, value | 0x1);
- } else if (strcmp(CMD_ARGV[0], "disable") == 0) {
- uint32_t value;
- nds32_get_mapped_reg(nds32, IR8, &value);
- nds32_set_mapped_reg(nds32, IR8, value & ~0x1);
- } else if (strcmp(CMD_ARGV[0], "dump") == 0) {
- /* TODO: dump cache content */
- } else {
- command_print(CMD, "%s: No valid parameter", target_name(target));
- }
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_dcache_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_cache *dcache = &(nds32->memory.dcache);
- int result;
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
-
- if (dcache->line_size == 0) {
- command_print(CMD, "%s: No data cache", target_name(target));
- return ERROR_OK;
- }
-
- if (strcmp(CMD_ARGV[0], "invalidate") == 0) {
- if (dcache->enable == true) {
- /* D$ write back */
- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0);
- if (result != ERROR_OK) {
- command_print(CMD, "%s: Write back data cache...failed",
- target_name(target));
- return result;
- }
-
- command_print(CMD, "%s: Write back data cache...done",
- target_name(target));
-
- /* D$ invalidate */
- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0);
- if (result != ERROR_OK) {
- command_print(CMD, "%s: Invalidate data cache...failed",
- target_name(target));
- return result;
- }
-
- command_print(CMD, "%s: Invalidate data cache...done",
- target_name(target));
- } else {
- command_print(CMD, "%s: Data cache disabled",
- target_name(target));
- }
- } else if (strcmp(CMD_ARGV[0], "enable") == 0) {
- uint32_t value;
- nds32_get_mapped_reg(nds32, IR8, &value);
- nds32_set_mapped_reg(nds32, IR8, value | 0x2);
- } else if (strcmp(CMD_ARGV[0], "disable") == 0) {
- uint32_t value;
- nds32_get_mapped_reg(nds32, IR8, &value);
- nds32_set_mapped_reg(nds32, IR8, value & ~0x2);
- } else if (strcmp(CMD_ARGV[0], "dump") == 0) {
- /* TODO: dump cache content */
- } else {
- command_print(CMD, "%s: No valid parameter", target_name(target));
- }
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_auto_break_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "on") == 0)
- nds32->auto_convert_hw_bp = true;
- if (strcmp(CMD_ARGV[0], "off") == 0)
- nds32->auto_convert_hw_bp = false;
- }
-
- if (nds32->auto_convert_hw_bp)
- command_print(CMD, "%s: convert sw break to hw break on ROM: on",
- target_name(target));
- else
- command_print(CMD, "%s: convert sw break to hw break on ROM: off",
- target_name(target));
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_virtual_hosting_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "on") == 0)
- nds32->virtual_hosting = true;
- if (strcmp(CMD_ARGV[0], "off") == 0)
- nds32->virtual_hosting = false;
- }
-
- if (nds32->virtual_hosting)
- command_print(CMD, "%s: virtual hosting: on", target_name(target));
- else
- command_print(CMD, "%s: virtual hosting: off", target_name(target));
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_global_stop_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "on") == 0)
- nds32->global_stop = true;
- if (strcmp(CMD_ARGV[0], "off") == 0)
- nds32->global_stop = false;
- }
-
- if (nds32->global_stop)
- LOG_INFO("%s: global stop: on", target_name(target));
- else
- LOG_INFO("%s: global stop: off", target_name(target));
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_soft_reset_halt_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "on") == 0)
- nds32->soft_reset_halt = true;
- if (strcmp(CMD_ARGV[0], "off") == 0)
- nds32->soft_reset_halt = false;
- }
-
- if (nds32->soft_reset_halt)
- LOG_INFO("%s: soft-reset-halt: on", target_name(target));
- else
- LOG_INFO("%s: soft-reset-halt: off", target_name(target));
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_boot_time_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0)
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], nds32->boot_time);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_login_edm_passcode_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- nds32->edm_passcode = strdup(CMD_ARGV[0]);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_login_edm_operation_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 1) {
-
- uint32_t misc_reg_no;
- uint32_t data;
-
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], misc_reg_no);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], data);
-
- if (nds32_edm_ops_num >= NDS32_EDM_OPERATION_MAX_NUM)
- return ERROR_FAIL;
-
- /* Just save the operation. Execute it in nds32_login() */
- nds32_edm_ops[nds32_edm_ops_num].reg_no = misc_reg_no;
- nds32_edm_ops[nds32_edm_ops_num].value = data;
- nds32_edm_ops_num++;
- } else
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_reset_halt_as_init_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "on") == 0)
- nds32->reset_halt_as_examine = true;
- if (strcmp(CMD_ARGV[0], "off") == 0)
- nds32->reset_halt_as_examine = false;
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_keep_target_edm_ctl_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "on") == 0)
- nds32->keep_target_edm_ctl = true;
- if (strcmp(CMD_ARGV[0], "off") == 0)
- nds32->keep_target_edm_ctl = false;
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_decode_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 1) {
-
- uint32_t addr;
- uint32_t insn_count;
- uint32_t opcode;
- uint32_t read_addr;
- uint32_t i;
- struct nds32_instruction instruction;
-
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], insn_count);
-
- read_addr = addr;
- i = 0;
- while (i < insn_count) {
- if (nds32_read_opcode(nds32, read_addr, &opcode) != ERROR_OK)
- return ERROR_FAIL;
- if (nds32_evaluate_opcode(nds32, opcode, read_addr, &instruction) != ERROR_OK)
- return ERROR_FAIL;
-
- command_print(CMD, "%s", instruction.text);
-
- read_addr += instruction.instruction_size;
- i++;
- }
- } else if (CMD_ARGC == 1) {
-
- uint32_t addr;
- uint32_t opcode;
- struct nds32_instruction instruction;
-
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
-
- if (nds32_read_opcode(nds32, addr, &opcode) != ERROR_OK)
- return ERROR_FAIL;
- if (nds32_evaluate_opcode(nds32, opcode, addr, &instruction) != ERROR_OK)
- return ERROR_FAIL;
-
- command_print(CMD, "%s", instruction.text);
- } else
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_word_access_mem_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "on") == 0)
- nds32->word_access_mem = true;
- if (strcmp(CMD_ARGV[0], "off") == 0)
- nds32->word_access_mem = false;
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_query_target_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- command_print(CMD, "OCD");
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_query_endian_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- uint32_t value_psw;
- nds32_get_mapped_reg(nds32, IR0, &value_psw);
-
- if (value_psw & 0x20)
- command_print(CMD, "%s: BE", target_name(target));
- else
- command_print(CMD, "%s: LE", target_name(target));
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_nds32_query_cpuid_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct nds32 *nds32 = target_to_nds32(target);
-
- if (!is_nds32(nds32)) {
- command_print(CMD, "current target isn't an Andes core");
- return ERROR_FAIL;
- }
-
- command_print(CMD, "CPUID: %s", target_name(target));
-
- return ERROR_OK;
-}
-
-static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
-
- struct jim_getopt_info goi;
- jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
-
- if (goi.argc < 3) {
- Jim_SetResultFormatted(goi.interp,
- "usage: %s <address> <count> <data>", cmd_name);
- return JIM_ERR;
- }
-
- int e;
- jim_wide address;
- e = jim_getopt_wide(&goi, &address);
- if (e != JIM_OK)
- return e;
-
- jim_wide count;
- e = jim_getopt_wide(&goi, &count);
- if (e != JIM_OK)
- return e;
-
- uint32_t *data = malloc(count * sizeof(uint32_t));
- if (!data)
- return JIM_ERR;
-
- jim_wide i;
- for (i = 0; i < count; i++) {
- jim_wide tmp;
- e = jim_getopt_wide(&goi, &tmp);
- if (e != JIM_OK) {
- free(data);
- return e;
- }
- data[i] = (uint32_t)tmp;
- }
-
- /* all args must be consumed */
- if (goi.argc != 0) {
- free(data);
- return JIM_ERR;
- }
-
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx);
- struct target *target = get_current_target(cmd_ctx);
- int result;
-
- result = target_write_buffer(target, address, count * 4, (const uint8_t *)data);
-
- free(data);
-
- return result;
-}
-
-static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
-
- struct jim_getopt_info goi;
- jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
-
- if (goi.argc < 3) {
- Jim_SetResultFormatted(goi.interp,
- "usage: %s # of pairs [<address> <data>]+", cmd_name);
- return JIM_ERR;
- }
-
- int e;
- jim_wide num_of_pairs;
- e = jim_getopt_wide(&goi, &num_of_pairs);
- if (e != JIM_OK)
- return e;
-
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx);
- struct target *target = get_current_target(cmd_ctx);
- struct aice_port_s *aice = target_to_aice(target);
- int result;
- uint32_t address;
- uint32_t data;
- jim_wide i;
-
- aice_set_command_mode(aice, AICE_COMMAND_MODE_PACK);
- for (i = 0; i < num_of_pairs; i++) {
- jim_wide tmp;
- e = jim_getopt_wide(&goi, &tmp);
- if (e != JIM_OK)
- break;
- address = (uint32_t)tmp;
-
- e = jim_getopt_wide(&goi, &tmp);
- if (e != JIM_OK)
- break;
- data = (uint32_t)tmp;
-
- result = target_write_buffer(target, address, 4, (const uint8_t *)&data);
- if (result != ERROR_OK)
- break;
- }
- aice_set_command_mode(aice, AICE_COMMAND_MODE_NORMAL);
-
- /* all args must be consumed */
- if (goi.argc != 0)
- return JIM_ERR;
-
- return ERROR_OK;
-}
-
-static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
-
- struct jim_getopt_info goi;
- jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
-
- if (goi.argc < 2) {
- Jim_SetResultFormatted(goi.interp,
- "usage: %s <address> <count>", cmd_name);
- return JIM_ERR;
- }
-
- int e;
- jim_wide address;
- e = jim_getopt_wide(&goi, &address);
- if (e != JIM_OK)
- return e;
-
- jim_wide count;
- e = jim_getopt_wide(&goi, &count);
- if (e != JIM_OK)
- return e;
-
- /* all args must be consumed */
- if (goi.argc != 0)
- return JIM_ERR;
-
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx);
- struct target *target = get_current_target(cmd_ctx);
- uint32_t *data = malloc(count * sizeof(uint32_t));
- int result;
- result = target_read_buffer(target, address, count * 4, (uint8_t *)data);
- char data_str[12];
-
- jim_wide i;
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- for (i = 0; i < count; i++) {
- sprintf(data_str, "0x%08" PRIx32 " ", data[i]);
- Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL);
- }
-
- free(data);
-
- return result;
-}
-
-static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
-
- struct jim_getopt_info goi;
- jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
-
- if (goi.argc < 1) {
- Jim_SetResultFormatted(goi.interp,
- "usage: %s <edm_sr_name>", cmd_name);
- return JIM_ERR;
- }
-
- int e;
- const char *edm_sr_name;
- int edm_sr_name_len;
- e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len);
- if (e != JIM_OK)
- return e;
-
- /* all args must be consumed */
- if (goi.argc != 0)
- return JIM_ERR;
-
- uint32_t edm_sr_number;
- uint32_t edm_sr_value;
- if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0)
- edm_sr_number = NDS_EDM_SR_EDM_DTR;
- else if (strncmp(edm_sr_name, "edmsw", edm_sr_name_len) == 0)
- edm_sr_number = NDS_EDM_SR_EDMSW;
- else
- return ERROR_FAIL;
-
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx);
- struct target *target = get_current_target(cmd_ctx);
- struct aice_port_s *aice = target_to_aice(target);
- char data_str[11];
-
- aice_read_debug_reg(aice, edm_sr_number, &edm_sr_value);
-
- sprintf(data_str, "0x%08" PRIx32, edm_sr_value);
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL);
-
- return ERROR_OK;
-}
-
-static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
-
- struct jim_getopt_info goi;
- jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
-
- if (goi.argc < 2) {
- Jim_SetResultFormatted(goi.interp,
- "usage: %s <edm_sr_name> <value>", cmd_name);
- return JIM_ERR;
- }
-
- int e;
- const char *edm_sr_name;
- int edm_sr_name_len;
- e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len);
- if (e != JIM_OK)
- return e;
-
- jim_wide value;
- e = jim_getopt_wide(&goi, &value);
- if (e != JIM_OK)
- return e;
-
- /* all args must be consumed */
- if (goi.argc != 0)
- return JIM_ERR;
-
- uint32_t edm_sr_number;
- if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0)
- edm_sr_number = NDS_EDM_SR_EDM_DTR;
- else
- return ERROR_FAIL;
-
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx);
- struct target *target = get_current_target(cmd_ctx);
- struct aice_port_s *aice = target_to_aice(target);
-
- aice_write_debug_reg(aice, edm_sr_number, value);
-
- return ERROR_OK;
-}
-
-static const struct command_registration nds32_query_command_handlers[] = {
- {
- .name = "target",
- .handler = handle_nds32_query_target_command,
- .mode = COMMAND_EXEC,
- .usage = "",
- .help = "reply 'OCD' for gdb to identify server-side is OpenOCD",
- },
- {
- .name = "endian",
- .handler = handle_nds32_query_endian_command,
- .mode = COMMAND_EXEC,
- .usage = "",
- .help = "query target endian",
- },
- {
- .name = "cpuid",
- .handler = handle_nds32_query_cpuid_command,
- .mode = COMMAND_EXEC,
- .usage = "",
- .help = "query CPU ID",
- },
-
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration nds32_exec_command_handlers[] = {
- {
- .name = "dssim",
- .handler = handle_nds32_dssim_command,
- .mode = COMMAND_EXEC,
- .usage = "['on'|'off']",
- .help = "display/change $INT_MASK.DSSIM status",
- },
- {
- .name = "mem_access",
- .handler = handle_nds32_memory_access_command,
- .mode = COMMAND_EXEC,
- .usage = "['bus'|'cpu']",
- .help = "display/change memory access channel",
- },
- {
- .name = "mem_mode",
- .handler = handle_nds32_memory_mode_command,
- .mode = COMMAND_EXEC,
- .usage = "['auto'|'mem'|'ilm'|'dlm']",
- .help = "display/change memory mode",
- },
- {
- .name = "cache",
- .handler = handle_nds32_cache_command,
- .mode = COMMAND_EXEC,
- .usage = "['invalidate']",
- .help = "cache control",
- },
- {
- .name = "icache",
- .handler = handle_nds32_icache_command,
- .mode = COMMAND_EXEC,
- .usage = "['invalidate'|'enable'|'disable'|'dump']",
- .help = "icache control",
- },
- {
- .name = "dcache",
- .handler = handle_nds32_dcache_command,
- .mode = COMMAND_EXEC,
- .usage = "['invalidate'|'enable'|'disable'|'dump']",
- .help = "dcache control",
- },
- {
- .name = "auto_break",
- .handler = handle_nds32_auto_break_command,
- .mode = COMMAND_EXEC,
- .usage = "['on'|'off']",
- .help = "convert software breakpoints to hardware breakpoints if needed",
- },
- {
- .name = "virtual_hosting",
- .handler = handle_nds32_virtual_hosting_command,
- .mode = COMMAND_ANY,
- .usage = "['on'|'off']",
- .help = "turn on/off virtual hosting",
- },
- {
- .name = "global_stop",
- .handler = handle_nds32_global_stop_command,
- .mode = COMMAND_ANY,
- .usage = "['on'|'off']",
- .help = "turn on/off global stop. After turning on, every load/store "
- "instructions will be stopped to check memory access.",
- },
- {
- .name = "soft_reset_halt",
- .handler = handle_nds32_soft_reset_halt_command,
- .mode = COMMAND_ANY,
- .usage = "['on'|'off']",
- .help = "as issuing rest-halt, to use soft-reset-halt or not."
- "the feature is for backward-compatible.",
- },
- {
- .name = "boot_time",
- .handler = handle_nds32_boot_time_command,
- .mode = COMMAND_CONFIG,
- .usage = "milliseconds",
- .help = "set the period to wait after srst.",
- },
- {
- .name = "login_edm_passcode",
- .handler = handle_nds32_login_edm_passcode_command,
- .mode = COMMAND_CONFIG,
- .usage = "passcode",
- .help = "set EDM passcode for secure MCU debugging.",
- },
- {
- .name = "login_edm_operation",
- .handler = handle_nds32_login_edm_operation_command,
- .mode = COMMAND_CONFIG,
- .usage = "misc_reg_no value",
- .help = "add EDM operations for secure MCU debugging.",
- },
- {
- .name = "reset_halt_as_init",
- .handler = handle_nds32_reset_halt_as_init_command,
- .mode = COMMAND_CONFIG,
- .usage = "['on'|'off']",
- .help = "reset halt as openocd init.",
- },
- {
- .name = "keep_target_edm_ctl",
- .handler = handle_nds32_keep_target_edm_ctl_command,
- .mode = COMMAND_CONFIG,
- .usage = "['on'|'off']",
- .help = "Backup/Restore target EDM_CTL register.",
- },
- {
- .name = "decode",
- .handler = handle_nds32_decode_command,
- .mode = COMMAND_EXEC,
- .usage = "address icount",
- .help = "decode instruction.",
- },
- {
- .name = "word_access_mem",
- .handler = handle_nds32_word_access_mem_command,
- .mode = COMMAND_ANY,
- .usage = "['on'|'off']",
- .help = "Always use word-aligned address to access memory.",
- },
- {
- .name = "bulk_write",
- .jim_handler = jim_nds32_bulk_write,
- .mode = COMMAND_EXEC,
- .help = "Write multiple 32-bit words to target memory",
- .usage = "address count data",
- },
- {
- .name = "multi_write",
- .jim_handler = jim_nds32_multi_write,
- .mode = COMMAND_EXEC,
- .help = "Write multiple addresses/words to target memory",
- .usage = "num_of_pairs [address data]+",
- },
- {
- .name = "bulk_read",
- .jim_handler = jim_nds32_bulk_read,
- .mode = COMMAND_EXEC,
- .help = "Read multiple 32-bit words from target memory",
- .usage = "address count",
- },
- {
- .name = "read_edmsr",
- .jim_handler = jim_nds32_read_edm_sr,
- .mode = COMMAND_EXEC,
- .help = "Read EDM system register",
- .usage = "['edmsw'|'edm_dtr']",
- },
- {
- .name = "write_edmsr",
- .jim_handler = jim_nds32_write_edm_sr,
- .mode = COMMAND_EXEC,
- .help = "Write EDM system register",
- .usage = "['edm_dtr'] value",
- },
- {
- .name = "query",
- .mode = COMMAND_EXEC,
- .help = "Andes query command group",
- .usage = "",
- .chain = nds32_query_command_handlers,
- },
-
- COMMAND_REGISTRATION_DONE
-};
-
-const struct command_registration nds32_command_handlers[] = {
- {
- .name = "nds",
- .mode = COMMAND_ANY,
- .help = "Andes command group",
- .usage = "",
- .chain = nds32_exec_command_handlers,
- },
- COMMAND_REGISTRATION_DONE
-};
diff --git a/src/target/nds32_cmd.h b/src/target/nds32_cmd.h
deleted file mode 100644
index 1593243..0000000
--- a/src/target/nds32_cmd.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_CMD_H
-#define OPENOCD_TARGET_NDS32_CMD_H
-
-#include <helper/command.h>
-
-extern const struct command_registration nds32_command_handlers[];
-
-#endif /* OPENOCD_TARGET_NDS32_CMD_H */
diff --git a/src/target/nds32_disassembler.c b/src/target/nds32_disassembler.c
deleted file mode 100644
index eebbfe1..0000000
--- a/src/target/nds32_disassembler.c
+++ /dev/null
@@ -1,3847 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <helper/log.h>
-#include <target/target.h>
-#include "nds32_disassembler.h"
-
-static const int enable4_bits[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
-
-int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value)
-{
- struct target *target = nds32->target;
- uint8_t value_buf[4];
-
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- int retval = target_read_buffer(target, address, 4, value_buf);
-
- if (retval == ERROR_OK) {
- /* instructions are always big-endian */
- *value = be_to_h_u32(value_buf);
-
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
- address,
- *value);
- } else {
- *value = 0x0;
- LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
- address);
- }
-
- return retval;
-}
-
-static int nds32_parse_type_0(uint32_t opcode, int32_t *imm)
-{
- *imm = opcode & 0x1FFFFFF;
-
- return ERROR_OK;
-}
-
-static int nds32_parse_type_1(uint32_t opcode, uint8_t *rt, int32_t *imm)
-{
- *rt = (opcode >> 20) & 0x1F;
- *imm = opcode & 0xFFFFF;
-
- return ERROR_OK;
-}
-
-static int nds32_parse_type_2(uint32_t opcode, uint8_t *rt, uint8_t *ra, int32_t *imm)
-{
- *rt = (opcode >> 20) & 0x1F;
- *ra = (opcode >> 15) & 0x1F;
- *imm = opcode & 0x7FFF;
-
- return ERROR_OK;
-}
-
-static int nds32_parse_type_3(uint32_t opcode, uint8_t *rt, uint8_t *ra,
- uint8_t *rb, int32_t *imm)
-{
- *rt = (opcode >> 20) & 0x1F;
- *ra = (opcode >> 15) & 0x1F;
- *rb = (opcode >> 10) & 0x1F;
- *imm = opcode & 0x3FF;
-
- return ERROR_OK;
-}
-
-static int nds32_parse_type_4(uint32_t opcode, uint8_t *rt, uint8_t *ra,
- uint8_t *rb, uint8_t *rd, uint8_t *sub_opc)
-{
- *rt = (opcode >> 20) & 0x1F;
- *ra = (opcode >> 15) & 0x1F;
- *rb = (opcode >> 10) & 0x1F;
- *rd = (opcode >> 5) & 0x1F;
- *sub_opc = opcode & 0x1F;
-
- return ERROR_OK;
-}
-
-/* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */
-static int nds32_parse_group_0_insn(struct nds32 *nds32, uint32_t opcode,
- uint32_t address,
- struct nds32_instruction *instruction)
-{
- uint8_t opc_6;
-
- opc_6 = instruction->info.opc_6;
-
- switch (opc_6 & 0x7) {
- case 0: /* LBI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLBI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 1: /* LHI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLHI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 2: /* LWI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLWI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 4: /* LBI.bi */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLBI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 5: /* LHI.bi */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLHI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 6: /* LWI.bi */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLWI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32 "",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_group_1_insn(struct nds32 *nds32, uint32_t opcode,
- uint32_t address, struct nds32_instruction *instruction)
-{
- uint8_t opc_6;
-
- opc_6 = instruction->info.opc_6;
-
- switch (opc_6 & 0x7) {
- case 0: /* SBI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSBI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 1: /* SHI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSHI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 2: /* SWI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSWI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 4: /* SBI.bi */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSBI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 5: /* SHI.bi */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSHI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 6: /* SWI.bi */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSWI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_group_2_insn(struct nds32 *nds32, uint32_t opcode,
- uint32_t address, struct nds32_instruction *instruction)
-{
- uint8_t opc_6;
-
- opc_6 = instruction->info.opc_6;
-
- switch (opc_6 & 0x7) {
- case 0: /* LBSI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLBSI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 1: /* LHSI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLHSI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 3: { /* DPREFI */
- uint8_t sub_type;
- nds32_parse_type_2(opcode, &sub_type, &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->info.sub_opc = sub_type & 0xF;
- instruction->type = NDS32_INSN_MISC;
- if (sub_type & 0x10) { /* DPREFI.d */
- /* sign-extend */
- instruction->info.imm = (instruction->info.imm << 17) >> 14;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tDPREFI.d\t%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.sub_opc,
- instruction->info.ra, instruction->info.imm);
- } else { /* DPREFI.w */
- /* sign-extend */
- instruction->info.imm = (instruction->info.imm << 17) >> 15;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tDPREFI.w\t%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]",
- address,
- opcode, instruction->info.sub_opc,
- instruction->info.ra, instruction->info.imm);
- }
- }
- break;
- case 4: /* LBSI.bi */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLBSI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 5: /* LHSI.bi */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLHSI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 6: /* LBGP */
- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- if ((instruction->info.imm >> 19) & 0x1) { /* LBSI.gp */
- instruction->info.imm = (instruction->info.imm << 13) >> 13;
- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLBSI.gp\t$r%" PRIu8 ",[#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- } else { /* LBI.gp */
- instruction->info.imm = (instruction->info.imm << 13) >> 13;
- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLBI.gp\t$r%" PRIu8 ",[#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- }
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_mem(struct nds32 *nds32, uint32_t opcode, uint32_t address,
- struct nds32_instruction *instruction)
-{
- uint32_t sub_opcode = opcode & 0x3F;
- uint32_t val_ra, val_rb;
- switch (sub_opcode >> 3) {
- case 0:
- switch (sub_opcode & 0x7) {
- case 0: /* LB */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLB\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 1: /* LH */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLH\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 2: /* LW */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 4: /* LB.bi */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLB.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")",
- address,
- opcode, instruction->info.rt,
- instruction->info.ra, instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 5: /* LH.bi */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLH.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 6: /* LW.bi */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLW.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- }
- break;
- case 1:
- switch (sub_opcode & 0x7) {
- case 0: /* SB */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSB\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt,
- instruction->info.ra, instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 1: /* SH */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSH\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 2: /* SW */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt,
- instruction->info.ra, instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 4: /* SB.bi */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSB.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 5: /* SH.bi */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSH.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 6: /* SW.bi */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSW.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- }
- break;
- case 2:
- switch (sub_opcode & 0x7) {
- case 0: /* LBS */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLBS\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt,
- instruction->info.ra, instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 1: /* LHS */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLHS\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 3: /* DPREF */
- nds32_parse_type_3(opcode, &(instruction->info.sub_opc),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tDPREF\t#%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<#%" PRId32 ")]",
- address,
- opcode, instruction->info.sub_opc,
- instruction->info.ra, instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 4: /* LBS.bi */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLBS.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 5: /* LHS.bi */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLHS.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- }
- break;
- case 3:
- switch (sub_opcode & 0x7) {
- case 0: /* LLW */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLLW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 1: /* SCW */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSCW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- }
- break;
- case 4:
- switch (sub_opcode & 0x7) {
- case 0: /* LBUP */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLBUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 2: /* LWUP */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLWUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- }
- break;
- case 5:
- switch (sub_opcode & 0x7) {
- case 0: /* SBUP */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSBUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- case 2: /* SWUP */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra);
- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb);
- instruction->access_start = val_ra +
- (val_rb << ((instruction->info.imm >> 8) & 0x3));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSWUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- (instruction->info.imm >> 8) & 0x3);
- break;
- }
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_calculate_lsmw_access_range(struct nds32 *nds32,
- struct nds32_instruction *instruction)
-{
- uint8_t ba;
- uint8_t id;
- uint8_t enable4;
-
- enable4 = (instruction->info.imm >> 6) & 0xF;
- ba = (instruction->info.imm >> 4) & 0x1;
- id = (instruction->info.imm >> 3) & 0x1;
-
- if (ba) {
- nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start));
- if (id) { /* decrease */
- /* access_end is the (last_element+1), so no need to minus 4 */
- /* instruction->access_end -= 4; */
- instruction->access_end = instruction->access_start;
- } else { /* increase */
- instruction->access_start += 4;
- }
- } else {
- nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start));
- instruction->access_end = instruction->access_start - 4;
- }
-
- if (id) { /* decrease */
- instruction->access_start = instruction->access_end -
- 4 * (instruction->info.rd - instruction->info.rb + 1);
- instruction->access_start -= (4 * enable4_bits[enable4]);
- } else { /* increase */
- instruction->access_end = instruction->access_start +
- 4 * (instruction->info.rd - instruction->info.rb + 1);
- instruction->access_end += (4 * enable4_bits[enable4]);
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_lsmw(struct nds32 *nds32, uint32_t opcode, uint32_t address,
- struct nds32_instruction *instruction)
-{
- if (opcode & 0x20) { /* SMW, SMWA, SMWZB */
- switch (opcode & 0x3) {
- /* TODO */
- case 0: /* SMW */
- /* use rd as re */
- nds32_parse_type_3(opcode, &(instruction->info.rb),
- &(instruction->info.ra),
- &(instruction->info.rd), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_calculate_lsmw_access_range(nds32, instruction);
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSMW\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rb, instruction->info.ra,
- instruction->info.rd,
- (instruction->info.imm >> 6) & 0xF);
- break;
- case 1: /* SMWA */
- nds32_parse_type_3(opcode, &(instruction->info.rb),
- &(instruction->info.ra),
- &(instruction->info.rd), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_calculate_lsmw_access_range(nds32, instruction);
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSMWA\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rb, instruction->info.ra,
- instruction->info.rd,
- (instruction->info.imm >> 6) & 0xF);
- break;
- case 2: /* SMWZB */
- nds32_parse_type_3(opcode, &(instruction->info.rb),
- &(instruction->info.ra),
- &(instruction->info.rd), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- /* TODO: calculate access_start/access_end */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSMWZB\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rb, instruction->info.ra,
- instruction->info.rd,
- (instruction->info.imm >> 6) & 0xF);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
- } else { /* LMW, LMWA, LMWZB */
- switch (opcode & 0x3) {
- case 0: /* LMW */
- nds32_parse_type_3(opcode, &(instruction->info.rb),
- &(instruction->info.ra),
- &(instruction->info.rd), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_calculate_lsmw_access_range(nds32, instruction);
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLMW\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rb, instruction->info.ra,
- instruction->info.rd,
- (instruction->info.imm >> 6) & 0xF);
- break;
- case 1: /* LMWA */
- nds32_parse_type_3(opcode, &(instruction->info.rb),
- &(instruction->info.ra),
- &(instruction->info.rd), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_calculate_lsmw_access_range(nds32, instruction);
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLMWA\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rb, instruction->info.ra,
- instruction->info.rd,
- (instruction->info.imm >> 6) & 0xF);
- break;
- case 2: /* LMWZB */
- nds32_parse_type_3(opcode, &(instruction->info.rb),
- &(instruction->info.ra),
- &(instruction->info.rd), &(instruction->info.imm));
- instruction->type = NDS32_INSN_LOAD_STORE;
- /* TODO: calculate access_start/access_end */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLMWZB\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rb, instruction->info.ra,
- instruction->info.rd,
- (instruction->info.imm >> 6) & 0xF);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_hwgp(struct nds32 *nds32, uint32_t opcode, uint32_t address,
- struct nds32_instruction *instruction)
-{
- switch ((opcode >> 18) & 0x3) {
- case 0: /* LHI.gp */
- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLHI.gp\t$r%" PRIu8 ",[#%" PRId32"]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 1: /* LHSI.gp */
- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLHSI.gp\t$r%" PRIu8 ",[#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 2: /* SHI.gp */
- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSHI.gp\t$r%" PRIu8 ",[#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 3:
- instruction->type = NDS32_INSN_LOAD_STORE;
- if ((opcode >> 17) & 0x1) { /* SWI.gp */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- /* sign-extend */
- instruction->info.imm = (instruction->info.imm << 15) >> 13;
- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSWI.gp\t$r%" PRIu8 ",[#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- } else { /* LWI.gp */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- /* sign-extend */
- instruction->info.imm = (instruction->info.imm << 15) >> 13;
- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tLWI.gp\t$r%" PRIu8 ",[#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- }
-
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_sbgp(struct nds32 *nds32, uint32_t opcode, uint32_t address,
- struct nds32_instruction *instruction)
-{
- switch ((opcode >> 19) & 0x1) {
- case 0: /* SBI.gp */
- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSBI.gp\t$r%" PRIu8 ",[#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 1: /* ADDI.gp */
- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tADDI.gp\t$r%" PRIu8 ",#%" PRId32 "",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_group_3_insn(struct nds32 *nds32, uint32_t opcode, uint32_t address,
- struct nds32_instruction *instruction)
-{
- uint8_t opc_6;
-
- opc_6 = instruction->info.opc_6;
-
- switch (opc_6 & 0x7) {
- case 4: /* MEM */
- nds32_parse_mem(nds32, opcode, address, instruction);
- break;
- case 5: /* LSMW */
- nds32_parse_lsmw(nds32, opcode, address, instruction);
- break;
- case 6: /* HWGP */
- nds32_parse_hwgp(nds32, opcode, address, instruction);
- break;
- case 7: /* SBGP */
- nds32_parse_sbgp(nds32, opcode, address, instruction);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_alu_1(uint32_t opcode, uint32_t address,
- struct nds32_instruction *instruction)
-{
- switch (opcode & 0x1F) {
- case 0: /* ADD */
- nds32_parse_type_3(opcode, &(instruction->info.rt), &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tADD_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tADD\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 1: /* SUB */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSUB_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSUB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 "",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 2: /* AND */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tAND_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tAND\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 "",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 3: /* XOR */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tXOR_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tXOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 4: /* OR */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tOR_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 5: /* NOR */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tNOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 6: /* SLT */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSLT\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 7: /* SLTS */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSLTS\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 8: { /* SLLI */
- uint8_t imm;
- int32_t sub_op;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &sub_op);
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSLLI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 9: { /* SRLI */
- uint8_t imm;
- int32_t sub_op;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &sub_op);
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSRLI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 10: { /* SRAI */
- uint8_t imm;
- int32_t sub_op;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &sub_op);
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSRAI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 11: { /* ROTRI */
- uint8_t imm;
- int32_t sub_op;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &sub_op);
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tROTRI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 12: { /* SLL */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSLL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 13: { /* SRL */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSRL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 14: { /* SRA */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSRA\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 15: { /* ROTR */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tROTR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 16: { /* SEB */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSEB\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- }
- break;
- case 17: { /* SEH */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSEH\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- }
- break;
- case 18: /* BITC */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBITC\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 19: { /* ZEH */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tZEH\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- }
- break;
- case 20: { /* WSBH */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tWSBH\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- }
- break;
- case 21: /* OR_SRLI */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tOR_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 22: { /* DIVSR */
- nds32_parse_type_4(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.rd),
- &(instruction->info.sub_opc));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tDIVSR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.rd);
- }
- break;
- case 23: { /* DIVR */
- nds32_parse_type_4(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.rd),
- &(instruction->info.sub_opc));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tDIVR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.rd);
- }
- break;
- case 24: { /* SVA */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSVA\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 25: { /* SVS */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSVS\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 26: { /* CMOVZ */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tCMOVZ\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 27: { /* CMOVN */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tCMOVN\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 28: /* ADD_SRLI */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tADD_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tADD\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 29: /* SUB_SRLI */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSUB_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSUB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 30: /* AND_SRLI */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tAND_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tAND\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 31: /* XOR_SRLI */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F;
- if (instruction->info.imm)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tXOR_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb,
- instruction->info.imm);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tXOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_alu_2(uint32_t opcode, uint32_t address,
- struct nds32_instruction *instruction)
-{
- switch (opcode & 0x3F) {
- case 0: /* MAX */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMAX\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 1: /* MIN */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMIN\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 2: /* AVE */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tAVE\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 3: /* ABS */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tAVE\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 4: { /* CLIPS */
- uint8_t imm;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &(instruction->info.imm));
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tCLIPS\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 5: { /* CLIP */
- uint8_t imm;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &(instruction->info.imm));
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tCLIP\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 6: /* CLO */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tCLO\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 7: /* CLZ */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tCLZ\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 8: { /* BSET */
- uint8_t imm;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &(instruction->info.imm));
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBSET\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 9: { /* BCLR */
- uint8_t imm;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &(instruction->info.imm));
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBCLR\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 10: { /* BTGL */
- uint8_t imm;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &(instruction->info.imm));
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBTGL\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 11: { /* BTST */
- uint8_t imm;
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &imm, &(instruction->info.imm));
- instruction->info.imm = imm;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBTST\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- case 12: /* BSE */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBSE\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 13: /* BSP */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBSP\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 14: /* FFB */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tFFB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 15: /* FFMISM */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tFFMISM\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 23: /* FFZMISM */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tFFZMISM\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 32: /* MFUSR */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_RESOURCE_ACCESS;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMFUSR\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt,
- (instruction->info.imm >> 10) & 0x3FF);
- break;
- case 33: /* MTUSR */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_RESOURCE_ACCESS;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMTUSR\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt,
- (instruction->info.imm >> 10) & 0x3FF);
- break;
- case 36: /* MUL */
- nds32_parse_type_3(opcode, &(instruction->info.rt),
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMUL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- break;
- case 40: { /* MULTS64 */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val,
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMULTS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 41: { /* MULT64 */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val,
- &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMULT64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 42: { /* MADDS64 */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMADDS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 43: { /* MADD64 */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMADD64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 44: { /* MSUBS64 */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMSUBS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 45: { /* MSUB64 */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMSUB64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 46: { /* DIVS */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tDIVS\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 47: { /* DIV */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tDIV\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 49: { /* MULT32 */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMULT32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 51: { /* MADD32 */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMADD32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 53: { /* MSUB32 */
- uint8_t dt_val;
- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra),
- &(instruction->info.rb), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMSUB32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra,
- instruction->info.rb);
- }
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_group_4_insn(struct nds32 *nds32, uint32_t opcode,
- uint32_t address, struct nds32_instruction *instruction)
-{
- uint8_t opc_6;
-
- opc_6 = instruction->info.opc_6;
-
- switch (opc_6 & 0x7) {
- case 0: /* ALU_1 */
- nds32_parse_alu_1(opcode, address, instruction);
- break;
- case 1: /* ALU_2 */
- nds32_parse_alu_2(opcode, address, instruction);
- break;
- case 2: /* MOVI */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- /* sign-extend */
- instruction->info.imm = (instruction->info.imm << 12) >> 12;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMOVI\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 3: /* SETHI */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSETHI\t$r%" PRIu8 ",0x%8.8" PRIx32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 4: /* JI */
- nds32_parse_type_0(opcode, &(instruction->info.imm));
- /* sign-extend */
- instruction->info.imm = (instruction->info.imm << 8) >> 8;
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- if ((instruction->info.imm >> 24) & 0x1) { /* JAL */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tJAL\t#%" PRId32,
- address,
- opcode, instruction->info.imm);
- } else { /* J */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tJ\t#%" PRId32,
- address,
- opcode, instruction->info.imm);
- }
- break;
- case 5: { /* JREG */
- int32_t imm;
- nds32_parse_type_0(opcode, &imm);
- instruction->info.rb = (imm >> 10) & 0x1F;
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- switch (imm & 0x1F) {
- /* TODO */
- case 0: /* JR */
- if (imm & 0x20) { /* RET */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tRET\t$r%" PRIu8,
- address,
- opcode, instruction->info.rb);
- } else { /* JR */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tJR\t$r%" PRIu8,
- address,
- opcode, instruction->info.rb);
- }
- break;
- case 1: /* JRAL */
- instruction->info.rt = (imm >> 20) & 0x1F;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tJRAL\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.rb);
- break;
- case 2: /* JRNEZ */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tJRNEZ\t$r%" PRIu8,
- address,
- opcode, instruction->info.rb);
- break;
- case 3: /* JRALNEZ */
- instruction->info.rt = (imm >> 20) & 0x1F;
- if (instruction->info.rt == R30)
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tJRALNEZ\t$r%" PRIu8,
- address,
- opcode, instruction->info.rb);
- else
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tJRALNEZ\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode,
- instruction->info.rt,
- instruction->info.rb);
- break;
- }
- }
- break;
- case 6: { /* BR1 */
- int32_t imm;
-
- nds32_parse_type_0(opcode, &imm);
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- if ((imm >> 14) & 0x1) { /* BNE */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- /* sign-extend */
- instruction->info.imm = (instruction->info.imm << 18) >> 18;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBNE\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- } else { /* BEQ */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- /* sign-extend */
- instruction->info.imm = (instruction->info.imm << 18) >> 18;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBEQ\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt,
- instruction->info.ra,
- instruction->info.imm);
- }
- }
- break;
- case 7: { /* BR2 */
- int32_t imm;
-
- nds32_parse_type_0(opcode, &imm);
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- switch ((imm >> 16) & 0xF) {
- case 2: /* BEQZ */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 16) >> 16;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBEQZ\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 3: /* BNEZ */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 16) >> 16;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBNEZ\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 4: /* BGEZ */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 16) >> 16;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBGEZ\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 5: /* BLTZ */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 16) >> 16;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBLTZ\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 6: /* BGTZ */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 16) >> 16;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBGTZ\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 7: /* BLEZ */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 16) >> 16;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBLEZ\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 12: /* BGEZAL */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 16) >> 16;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBGEZAL\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 13: /* BLTZAL */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 16) >> 16;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBLTZAL\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- }
- }
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_group_5_insn(struct nds32 *nds32, uint32_t opcode,
- uint32_t address, struct nds32_instruction *instruction)
-{
- uint8_t opc_6;
-
- opc_6 = instruction->info.opc_6;
-
- switch (opc_6 & 0x7) {
- case 0: /* ADDI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tADDI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 1: /* SUBRI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSUBRI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 2: /* ANDI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tANDI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 3: /* XORI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tXORI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 4: /* ORI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tORI\t$r%" PRIu8 ",$r%" PRIu8 ",0x%8.8" PRIx32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 6: /* SLTI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSLTI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 7: /* SLTSI */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSLTSI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_group_6_insn(struct nds32 *nds32, uint32_t opcode,
- uint32_t address, struct nds32_instruction *instruction)
-{
- uint8_t opc_6;
-
- opc_6 = instruction->info.opc_6;
-
- switch (opc_6 & 0x7) {
- case 2: { /* MISC */
- int32_t imm;
- uint8_t sub_opc;
-
- nds32_parse_type_0(opcode, &imm);
-
- sub_opc = imm & 0x1F;
- switch (sub_opc) {
- case 0: /* STANDBY */
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSTANDBY\t#%" PRIu32,
- address,
- opcode, (opcode >> 5) & 0x3);
- break;
- case 1: /* CCTL */
- /* TODO */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCCTL",
- address,
- opcode);
- break;
- case 2: /* MFSR */
- nds32_parse_type_1(opcode, &(instruction->info.rt),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_RESOURCE_ACCESS;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMFSR\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt,
- (instruction->info.imm >> 10) & 0x3FF);
- break;
- case 3: /* MTSR */
- nds32_parse_type_1(opcode, &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_RESOURCE_ACCESS;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMTSR\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.ra,
- (instruction->info.imm >> 10) & 0x3FF);
- break;
- case 4: /* IRET */
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tIRET",
- address,
- opcode);
- break;
- case 5: /* TRAP */
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tTRAP\t#%" PRId32,
- address,
- opcode, (imm >> 5) & 0x7FFF);
- break;
- case 6: /* TEQZ */
- nds32_parse_type_1(opcode, &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tTEQZ\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.ra,
- (instruction->info.imm >> 5) & 0x7FFF);
- break;
- case 7: /* TNEZ */
- nds32_parse_type_1(opcode, &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tTNEZ\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.ra,
- (instruction->info.imm >> 5) & 0x7FFF);
- break;
- case 8: /* DSB */
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB",
- address,
- opcode);
- break;
- case 9: /* ISB */
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tISB",
- address,
- opcode);
- break;
- case 10: /* BREAK */
- instruction->type = NDS32_INSN_MISC;
- instruction->info.sub_opc = imm & 0x1F;
- instruction->info.imm = (imm >> 5) & 0x7FFF;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tBREAK\t#%" PRId32,
- address,
- opcode, instruction->info.imm);
- break;
- case 11: /* SYSCALL */
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tSYSCALL\t#%" PRId32,
- address,
- opcode, (imm >> 5) & 0x7FFF);
- break;
- case 12: /* MSYNC */
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tMSYNC\t#%" PRId32,
- address,
- opcode, (imm >> 5) & 0x7);
- break;
- case 13: /* ISYNC */
- nds32_parse_type_1(opcode, &(instruction->info.ra),
- &(instruction->info.imm));
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
- "\tISYNC\t$r%" PRIu8,
- address,
- opcode, instruction->info.ra);
- break;
- case 14: /* TLBOP */
- /* TODO */
- nds32_parse_type_2(opcode, &(instruction->info.rt),
- &(instruction->info.ra), &(instruction->info.imm));
- instruction->type = NDS32_INSN_RESOURCE_ACCESS;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tTLBOP",
- address,
- opcode);
- break;
- }
-
- break;
- }
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static uint32_t field_mask[9] = {
- 0x0,
- 0x1,
- 0x3,
- 0x7,
- 0xF,
- 0x1F,
- 0x3F,
- 0x7F,
- 0xFF,
-};
-
-static uint8_t nds32_extract_field_8u(uint16_t opcode, uint32_t start, uint32_t length)
-{
- if (length > 0 && length < 9)
- return (opcode >> start) & field_mask[length];
-
- return 0;
-}
-
-static int nds32_parse_group_0_insn_16(struct nds32 *nds32, uint16_t opcode,
- uint32_t address, struct nds32_instruction *instruction)
-{
- switch ((opcode >> 10) & 0x7) {
- case 0: /* MOV55 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5);
- instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tMOV55\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 1: /* MOVI55 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
- instruction->info.imm = (instruction->info.imm << 27) >> 27;
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tMOVI55\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 2: /* ADD45, SUB45 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_DATA_PROC;
- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD45 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tADD45\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.rb);
- } else { /* SUB45 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSUB45\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.rb);
- }
-
- break;
- case 3: /* ADDI45, SUBI45 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_DATA_PROC;
- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI45 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tADDI45\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- } else { /* SUBI45 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSUBI45\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- }
- break;
- case 4: /* SRAI45, SRLI45 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_DATA_PROC;
- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SRAI45 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSRAI45\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- } else { /* SRLI45 */
- if ((instruction->info.rt == 0) && (instruction->info.imm == 0)) {
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 "\t\tNOP",
- address,
- opcode);
- } else {
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSRLI45\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- }
- }
- break;
- case 5:
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->type = NDS32_INSN_DATA_PROC;
- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SLLI333 */
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSLLI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- } else {
- instruction->info.sub_opc = nds32_extract_field_8u(opcode, 0, 3);
- switch (instruction->info.sub_opc) {
- case 0: /* ZEB33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tZEB33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 1: /* ZEH33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tZEH33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 2: /* SEB33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSEB33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 3: /* SEH33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSEH33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 4: /* XLSB33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tXLSB33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 5: /* XLLB33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tXLLB33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 6: /* BMSKI33 */
- instruction->info.ra = 0;
- instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3);
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tBMSKI33\t$r%" PRIu8 ",$r%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 7: /* FEXTI33 */
- instruction->info.ra = 0;
- instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3);
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tFEXTI33\t$r%" PRIu8 ",$r%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16
- "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
- }
- break;
- case 6: /* ADD333, SUB333 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 3);
- instruction->type = NDS32_INSN_DATA_PROC;
- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD333 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tADD333\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- } else { /* SUB333 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSUB333\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.rb);
- }
- break;
- case 7: /* ADDI333, SUBI333 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
- instruction->type = NDS32_INSN_DATA_PROC;
- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI333 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tADDI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- } else { /* SUBI333 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSUBI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- }
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_group_1_insn_16(struct nds32 *nds32, uint16_t opcode,
- uint32_t address, struct nds32_instruction *instruction)
-{
- switch ((opcode >> 9) & 0xF) {
- case 0: /* LWI333 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2;
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tLWI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 1: /* LWI333.BI */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tLWI333.BI\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm << 2);
- break;
- case 2: /* LHI333 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1;
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tLHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 3: /* LBI333 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tLBI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 4: /* SWI333 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2;
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSWI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 5: /* SWI333.BI */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2;
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSWI333.BI\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 6: /* SHI333 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1;
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 2;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 7: /* SBI333 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3);
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 1;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]",
- address,
- opcode, instruction->info.rt, instruction->info.ra,
- instruction->info.imm);
- break;
- case 8: /* ADDRI36.SP */
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 6) << 2;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tADDRI36.SP\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 9: /* LWI45.FE */
- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
- instruction->info.imm -= 32;
- instruction->info.imm <<= 2;
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, R8, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tLWI45.FE\t$r%" PRIu8 ",[#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 10: /* LWI450 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tLWI450\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 11: /* SWI450 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, instruction->info.ra,
- &(instruction->access_start));
- instruction->access_end = instruction->access_start + 4;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSWI450\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 12:
- case 13:
- case 14:
- case 15: /* LWI37, SWI37 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2;
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, R28, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 4;
- if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tLWI37\t$r%" PRIu8 ",[fp+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- } else { /* SWI37 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSWI37\t$r%" PRIu8 ",[fp+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- }
- break;
- default: /* ERROR */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_group_2_insn_16(struct nds32 *nds32, uint16_t opcode,
- uint32_t address, struct nds32_instruction *instruction)
-{
- switch ((opcode >> 11) & 0x3) {
- case 0: /* BEQZ38 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
- instruction->info.imm = (instruction->info.imm << 24) >> 24;
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tBEQZ38\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 1: /* BNEZ38 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
- instruction->info.imm = (instruction->info.imm << 24) >> 24;
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tBNEZ38\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 2: /* BEQS38,J8 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
- instruction->info.imm = (instruction->info.imm << 24) >> 24;
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- if (instruction->info.rt == 5) { /* J8 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tJ8\t#%" PRId32,
- address,
- opcode, instruction->info.imm);
- } else { /* BEQS38 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tBEQS38\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- }
- break;
- case 3: /* BNES38, JR5, RET5, JRAL5 */
- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
- instruction->info.imm = (instruction->info.imm << 24) >> 24;
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- if (instruction->info.rt == 5) {
- instruction->info.imm = 0;
- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5);
- switch (nds32_extract_field_8u(opcode, 5, 3)) {
- case 0: /* JR5 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tJR5\t$r%" PRIu8,
- address,
- opcode, instruction->info.rb);
- break;
- case 1: /* JRAL5 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tJRAL5\t$r%" PRIu8,
- address,
- opcode, instruction->info.rb);
- break;
- case 2: /* EX9.IT */
- instruction->info.rb = 0;
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
- /* TODO: implement real instruction semantics */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tEX9.IT\t#%" PRId32,
- address,
- opcode, instruction->info.imm);
- break;
- case 4: /* RET5 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tRET5\t$r%" PRIu8,
- address,
- opcode, instruction->info.rb);
- break;
- case 5: /* ADD5.PC */
- instruction->info.rt = 0;
- instruction->info.rt = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tADD5.PC\t$r%" PRIu8,
- address,
- opcode, instruction->info.rt);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16
- "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
- } else { /* BNES38 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tBNES38\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- }
- break;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_parse_group_3_insn_16(struct nds32 *nds32, uint16_t opcode,
- uint32_t address, struct nds32_instruction *instruction)
-{
- switch ((opcode >> 11) & 0x3) {
- case 0:
- switch ((opcode >> 9) & 0x3) {
- case 0: /* SLTS45 */
- instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSLTS45\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.ra, instruction->info.rb);
- break;
- case 1: /* SLT45 */
- instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSLT45\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.ra, instruction->info.rb);
- break;
- case 2: /* SLTSI45 */
- instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSLTSI45\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.ra, instruction->info.imm);
- break;
- case 3: /* SLTI45 */
- instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5);
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSLTI45\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.ra, instruction->info.imm);
- break;
- }
- break;
- case 1:
- switch ((opcode >> 9) & 0x3) {
- case 0:
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8);
- instruction->info.imm = (instruction->info.imm << 24) >> 24;
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- if (nds32_extract_field_8u(opcode, 8, 1) == 0) { /* BEQZS8 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tBEQZS8\t#%" PRId32,
- address,
- opcode, instruction->info.imm);
- } else { /* BNEZS8 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tBNEZS8\t#%" PRId32,
- address,
- opcode, instruction->info.imm);
- }
- break;
- case 1: /* BREAK16 */
- if (((opcode >> 5) & 0xF) == 0) {
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tBREAK16\t#%" PRId16,
- address,
- opcode, (int16_t)(opcode & 0x1F));
- } else { /* EX9.IT */
- instruction->type = NDS32_INSN_MISC;
- /* TODO: implement real instruction semantics */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tEX9.IT\t#%" PRId16,
- address,
- opcode, (int16_t)(opcode & 0x1FF));
- }
- break;
- case 2: /* ADDI10S */
- case 3:
- instruction->info.imm = opcode & 0x3FF;
- instruction->info.imm = (instruction->info.imm << 22) >> 22;
- instruction->type = NDS32_INSN_DATA_PROC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tADDI10.SP\t#%" PRId32,
- address,
- opcode, instruction->info.imm);
- break;
- }
- break;
- case 2:
- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3);
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2;
- instruction->type = NDS32_INSN_LOAD_STORE;
- nds32_get_mapped_reg(nds32, R31, &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end = instruction->access_start + 4;
- if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37.SP */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tLWI37.SP\t$r%" PRIu8 ",[+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- } else { /* SWI37.SP */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tSWI37.SP\t$r%" PRIu8 ",[+#%" PRId32 "]",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- }
- break;
- case 3:
- switch ((opcode >> 9) & 0x3) {
- case 0: /* IFCALL9 */
- instruction->info.imm = opcode & 0x1FF;
- instruction->type = NDS32_INSN_JUMP_BRANCH;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tIFCALL9\t#%" PRId32 "",
- address,
- opcode, instruction->info.imm);
- break;
- case 1: /* MOVPI45 */
- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5) + 16;
- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4);
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tMOVPI45\t$r%" PRIu8 ",#%" PRId32 "",
- address,
- opcode, instruction->info.rt, instruction->info.imm);
- break;
- case 2: /* PUSH25, POP25, MOVD44 */
- switch ((opcode >> 7) & 0x3) {
- case 0: /* PUSH25 */
- {
- uint8_t re;
- uint8_t gpr_count;
-
- instruction->type = NDS32_INSN_LOAD_STORE;
- instruction->info.imm =
- nds32_extract_field_8u(opcode, 0, 5) << 3;
- re = nds32_extract_field_8u(opcode, 5, 2);
-
- if (re == 0)
- re = 6;
- else if (re == 1)
- re = 8;
- else if (re == 2)
- re = 10;
- else if (re == 3)
- re = 14;
-
- instruction->info.rd = re;
- /* GPRs list: R6 ~ Re and fp, gp, lp */
- gpr_count = 3 + (re - 5);
-
- nds32_get_mapped_reg(nds32, R31,
- &(instruction->access_end));
- instruction->access_start =
- instruction->access_end - (gpr_count * 4);
-
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tPUSH25\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rd,
- instruction->info.imm);
- }
- break;
- case 1: /* POP25 */
- {
- uint8_t re;
- uint8_t gpr_count;
-
- instruction->type = NDS32_INSN_LOAD_STORE;
- instruction->info.imm =
- nds32_extract_field_8u(opcode, 0, 5) << 3;
- re = nds32_extract_field_8u(opcode, 5, 2);
-
- if (re == 0)
- re = 6;
- else if (re == 1)
- re = 8;
- else if (re == 2)
- re = 10;
- else if (re == 3)
- re = 14;
-
- instruction->info.rd = re;
- /* GPRs list: R6 ~ Re and fp, gp, lp */
- gpr_count = 3 + (re - 5);
-
- nds32_get_mapped_reg(nds32, R31,
- &(instruction->access_start));
- instruction->access_start += instruction->info.imm;
- instruction->access_end =
- instruction->access_start + (gpr_count * 4);
-
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tPOP25\t$r%" PRIu8 ",#%" PRId32,
- address,
- opcode, instruction->info.rd,
- instruction->info.imm);
- }
- break;
- case 2: /* MOVD44 */
- case 3:
- instruction->info.ra =
- nds32_extract_field_8u(opcode, 0, 4) * 2;
- instruction->info.rt =
- nds32_extract_field_8u(opcode, 4, 4) * 2;
- instruction->type = NDS32_INSN_MISC;
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tMOVD44\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- }
- break;
- case 3: /* NEG33, NOT33, MUL33, XOR33, AND33, OR33 */
- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3);
- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3);
- instruction->type = NDS32_INSN_DATA_PROC;
- switch (opcode & 0x7) {
- case 2: /* NEG33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tNEG33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 3: /* NOT33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tNOT33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 4: /* MUL33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tMUL33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 5: /* XOR33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tXOR33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 6: /* AND33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tAND33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- case 7: /* OR33 */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16
- "\t\tOR33\t$r%" PRIu8 ",$r%" PRIu8,
- address,
- opcode, instruction->info.rt, instruction->info.ra);
- break;
- }
- break;
- }
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address,
- struct nds32_instruction *instruction)
-{
- int retval = ERROR_OK;
-
- /* clear fields, to avoid confusion */
- memset(instruction, 0, sizeof(struct nds32_instruction));
-
- if (opcode >> 31) {
- /* 16 bits instruction */
- instruction->instruction_size = 2;
- opcode = (opcode >> 16) & 0xFFFF;
- instruction->opcode = opcode;
-
- switch ((opcode >> 13) & 0x3) {
- case 0:
- retval = nds32_parse_group_0_insn_16(nds32, opcode, address, instruction);
- break;
- case 1:
- retval = nds32_parse_group_1_insn_16(nds32, opcode, address, instruction);
- break;
- case 2:
- retval = nds32_parse_group_2_insn_16(nds32, opcode, address, instruction);
- break;
- case 3:
- retval = nds32_parse_group_3_insn_16(nds32, opcode, address, instruction);
- break;
- default:
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
- } else {
- /* 32 bits instruction */
- instruction->instruction_size = 4;
- instruction->opcode = opcode;
-
- uint8_t opc_6;
- opc_6 = opcode >> 25;
- instruction->info.opc_6 = opc_6;
-
- switch ((opc_6 >> 3) & 0x7) {
- case 0: /* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */
- retval = nds32_parse_group_0_insn(nds32, opcode, address, instruction);
- break;
- case 1: /* SBI, SHI, SWI, SBI.bi, SHI.bi, SWI.bi */
- retval = nds32_parse_group_1_insn(nds32, opcode, address, instruction);
- break;
- case 2: /* LBSI, LHSI, DPREFI, LBSI.bi, LHSI.bi, LBGP */
- retval = nds32_parse_group_2_insn(nds32, opcode, address, instruction);
- break;
- case 3: /* MEM, LSMW, HWGP, SBGP */
- retval = nds32_parse_group_3_insn(nds32, opcode, address, instruction);
- break;
- case 4: /* ALU_1, ALU_2, MOVI, SETHI, JI, JREG, BR1, BR2 */
- retval = nds32_parse_group_4_insn(nds32, opcode, address, instruction);
- break;
- case 5: /* ADDI, SUBRI, ANDI, XORI, ORI, SLTI, SLTSI */
- retval = nds32_parse_group_5_insn(nds32, opcode, address, instruction);
- break;
- case 6: /* MISC */
- retval = nds32_parse_group_6_insn(nds32, opcode, address, instruction);
- break;
- default: /* ERROR */
- snprintf(instruction->text,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
- address,
- opcode);
- return ERROR_FAIL;
- }
- }
-
- return retval;
-}
diff --git a/src/target/nds32_disassembler.h b/src/target/nds32_disassembler.h
deleted file mode 100644
index f2c8e85..0000000
--- a/src/target/nds32_disassembler.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_DISASSEMBLER_H
-#define OPENOCD_TARGET_NDS32_DISASSEMBLER_H
-
-#include <target/nds32.h>
-
-enum nds32_instruction_type {
- NDS32_INSN_DATA_PROC = 0,
- NDS32_INSN_LOAD_STORE,
- NDS32_INSN_JUMP_BRANCH,
- NDS32_INSN_RESOURCE_ACCESS,
- NDS32_INSN_MISC,
-};
-
-struct nds32_instruction {
- enum nds32_instruction_type type;
- char text[128];
- uint32_t opcode;
- uint8_t instruction_size;
- uint32_t access_start;
- uint32_t access_end;
-
- struct {
- uint8_t opc_6;
- uint8_t rt;
- uint8_t ra;
- uint8_t rb;
- uint8_t rd;
- uint8_t sub_opc;
- int32_t imm;
- } info;
-
-};
-
-int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value);
-int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address,
- struct nds32_instruction *instruction);
-
-#endif /* OPENOCD_TARGET_NDS32_DISASSEMBLER_H */
diff --git a/src/target/nds32_edm.h b/src/target/nds32_edm.h
deleted file mode 100644
index 3213604..0000000
--- a/src/target/nds32_edm.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_EDM_H
-#define OPENOCD_TARGET_NDS32_EDM_H
-
-#include "helper/types.h"
-
-/**
- * @file
- * This is the interface to the Embedded Debug Module for Andes cores.
- */
-
-/* EDM misc registers */
-enum nds_edm_misc_reg {
- NDS_EDM_MISC_DIMIR = 0x0,
- NDS_EDM_MISC_SBAR,
- NDS_EDM_MISC_EDM_CMDR,
- NDS_EDM_MISC_DBGER,
- NDS_EDM_MISC_ACC_CTL,
- NDS_EDM_MISC_EDM_PROBE,
- NDS_EDM_MISC_GEN_PORT0,
- NDS_EDM_MISC_GEN_PORT1,
-};
-
-/* EDM system registers */
-enum nds_edm_system_reg {
- NDS_EDM_SR_BPC0 = 0x00,
- NDS_EDM_SR_BPC1,
- NDS_EDM_SR_BPC2,
- NDS_EDM_SR_BPC3,
- NDS_EDM_SR_BPC4,
- NDS_EDM_SR_BPC5,
- NDS_EDM_SR_BPC6,
- NDS_EDM_SR_BPC7,
- NDS_EDM_SR_BPA0 = 0x08,
- NDS_EDM_SR_BPA1,
- NDS_EDM_SR_BPA2,
- NDS_EDM_SR_BPA3,
- NDS_EDM_SR_BPA4,
- NDS_EDM_SR_BPA5,
- NDS_EDM_SR_BPA6,
- NDS_EDM_SR_BPA7,
- NDS_EDM_SR_BPAM0 = 0x10,
- NDS_EDM_SR_BPAM1,
- NDS_EDM_SR_BPAM2,
- NDS_EDM_SR_BPAM3,
- NDS_EDM_SR_BPAM4,
- NDS_EDM_SR_BPAM5,
- NDS_EDM_SR_BPAM6,
- NDS_EDM_SR_BPAM7,
- NDS_EDM_SR_BPV0 = 0x18,
- NDS_EDM_SR_BPV1,
- NDS_EDM_SR_BPV2,
- NDS_EDM_SR_BPV3,
- NDS_EDM_SR_BPV4,
- NDS_EDM_SR_BPV5,
- NDS_EDM_SR_BPV6,
- NDS_EDM_SR_BPV7,
- NDS_EDM_SR_BPCID0 = 0x20,
- NDS_EDM_SR_BPCID1,
- NDS_EDM_SR_BPCID2,
- NDS_EDM_SR_BPCID3,
- NDS_EDM_SR_BPCID4,
- NDS_EDM_SR_BPCID5,
- NDS_EDM_SR_BPCID6,
- NDS_EDM_SR_BPCID7,
- NDS_EDM_SR_EDM_CFG = 0x28,
- NDS_EDM_SR_EDMSW = 0x30,
- NDS_EDM_SR_EDM_CTL = 0x38,
- NDS_EDM_SR_EDM_DTR = 0x40,
- NDS_EDM_SR_BPMTV = 0x48,
- NDS_EDM_SR_DIMBR = 0x50,
- NDS_EDM_SR_TECR0 = 0x70,
- NDS_EDM_SR_TECR1 = 0x71,
-};
-
-enum nds_memory_access {
- NDS_MEMORY_ACC_BUS = 0,
- NDS_MEMORY_ACC_CPU,
-};
-
-enum nds_memory_select {
- NDS_MEMORY_SELECT_AUTO = 0,
- NDS_MEMORY_SELECT_MEM = 1,
- NDS_MEMORY_SELECT_ILM = 2,
- NDS_MEMORY_SELECT_DLM = 3,
-};
-
-#define NDS_DBGER_DEX (0x1)
-#define NDS_DBGER_DPED (0x2)
-#define NDS_DBGER_CRST (0x4)
-#define NDS_DBGER_AT_MAX (0x8)
-#define NDS_DBGER_ILL_SEC_ACC (0x10)
-#define NDS_DBGER_ALL_SUPRS_EX (0x40000000)
-#define NDS_DBGER_RESACC (0x80000000)
-#define NDS_DBGER_CLEAR_ALL (0x1F)
-
-#define NDS_EDMSW_WDV (1 << 0)
-#define NDS_EDMSW_RDV (1 << 1)
-
-#endif /* OPENOCD_TARGET_NDS32_EDM_H */
diff --git a/src/target/nds32_insn.h b/src/target/nds32_insn.h
deleted file mode 100644
index 25eb9ab..0000000
--- a/src/target/nds32_insn.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_INSN_H
-#define OPENOCD_TARGET_NDS32_INSN_H
-
-#define NOP (0x40000009)
-#define DSB (0x64000008)
-#define ISB (0x64000009)
-#define BEQ_MINUS_12 (0x4C000000 | 0x3FFA)
-#define MTSR_DTR(a) (0x64000003 | (((0x03 << 7) | (0x08 << 3) | (0x00 << 0)) << 10) | (((a) & 0x1F) << 20))
-#define MFSR_DTR(a) (0x64000002 | (((0x03 << 7) | (0x08 << 3) | (0x00 << 0)) << 10) | (((a) & 0x1F) << 20))
-#define SETHI(a, b) (0x46000000 | ((a) << 20) | (b))
-#define ORI(a, b, c) (0x58000000 | ((a) << 20) | ((b) << 15) | (c))
-#define LWI_BI(a, b) (0x0C000001 | (a << 20) | (b << 15))
-#define LHI_BI(a, b) (0x0A000001 | (a << 20) | (b << 15))
-#define LBI_BI(a, b) (0x08000001 | (a << 20) | (b << 15))
-#define SWI_BI(a, b) (0x1C000001 | (a << 20) | (b << 15))
-#define SHI_BI(a, b) (0x1A000001 | (a << 20) | (b << 15))
-#define SBI_BI(a, b) (0x18000001 | (a << 20) | (b << 15))
-#define IRET (0x64000004)
-#define L1D_IX_WB(a) (0x64000021 | ((a) << 15))
-#define L1D_IX_INVAL(a) (0x64000001 | ((a) << 15))
-#define L1D_VA_INVAL(a) (0x64000101 | ((a) << 15))
-#define L1D_VA_WB(a) (0x64000121 | ((a) << 15))
-#define L1D_IX_RTAG(a) (0x64000061 | ((a) << 15))
-#define L1D_IX_RWD(a) (0x64000081 | ((a) << 15))
-#define L1I_IX_INVAL(a) (0x64000201 | ((a) << 15))
-#define L1I_VA_INVAL(a) (0x64000301 | ((a) << 15))
-#define L1I_IX_RTAG(a) (0x64000261 | ((a) << 15))
-#define L1I_IX_RWD(a) (0x64000281 | ((a) << 15))
-#define L1I_VA_FILLCK(a) (0x64000361 | ((a) << 15))
-#define ISYNC(a) (0x6400000d | ((a) << 20))
-#define MSYNC_STORE (0x6400002c)
-#define MSYNC_ALL (0x6400000c)
-#define TLBOP_TARGET_READ(a) (0x6400000e | ((a) << 15))
-#define TLBOP_TARGET_PROBE(a, b) (0x640000AE | ((a) << 20) | ((b) << 15))
-#define MFCPD(a, b, c) (0x6A000041 | (a << 20) | (b << 8) | (c << 4))
-#define MFCPW(a, b, c) (0x6A000001 | (a << 20) | (b << 8) | (c << 4))
-#define MTCPD(a, b, c) (0x6A000049 | (a << 20) | (b << 8) | (c << 4))
-#define MTCPW(a, b, c) (0x6A000009 | (a << 20) | (b << 8) | (c << 4))
-#define MOVI_(a, b) (0x44000000 | (a << 20) | (b & 0xFFFFF))
-#define MFUSR_G0(a, b) (0x42000020 | (a << 20) | (b << 15))
-#define MTUSR_G0(a, b) (0x42000021 | (a << 20) | (b << 15))
-#define MFSR(a, b) (0x64000002 | (b << 10) | (a << 20))
-#define MTSR(a, b) (0x64000003 | (b << 10) | (a << 20))
-#define AMFAR(a, b) (0x60300060 | (a << 15) | b)
-#define AMTAR(a, b) (0x60300040 | (a << 15) | b)
-#define AMFAR2(a, b) (0x60300260 | (a << 15) | b)
-#define AMTAR2(a, b) (0x60300240 | (a << 15) | b)
-#define FMFCSR (0x6A000701)
-#define FMTCSR (0x6A000709)
-#define FMFCFG (0x6A000301)
-#define FMFSR(a, b) (0x6A000001 | ((a) << 20) | ((b) << 15))
-#define FMTSR(a, b) (0x6A000009 | ((a) << 20) | ((b) << 15))
-#define FMFDR(a, b) (0x6A000041 | ((a) << 20) | ((b) << 15))
-#define FMTDR(a, b) (0x6A000049 | ((a) << 20) | ((b) << 15))
-
-/* break instructions */
-#define NDS32_BREAK_16 (0x00EA)
-#define NDS32_BREAK_32 (0x0A000064)
-
-#endif /* OPENOCD_TARGET_NDS32_INSN_H */
diff --git a/src/target/nds32_reg.c b/src/target/nds32_reg.c
deleted file mode 100644
index 1687e69..0000000
--- a/src/target/nds32_reg.c
+++ /dev/null
@@ -1,369 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <helper/log.h>
-#include "nds32_reg.h"
-
-static bool nds32_reg_init_done;
-static struct nds32_reg_s nds32_regs[TOTAL_REG_NUM];
-static const struct nds32_reg_exception_s nds32_ex_reg_values[] = {
- {IR0, 3, 0x3, 2},
- {IR0, 3, 0x3, 3},
- {IR1, 3, 0x3, 2},
- {IR1, 3, 0x3, 3},
- {IR2, 3, 0x3, 2},
- {IR2, 3, 0x3, 3},
- {MR3, 1, 0x7, 0},
- {MR3, 1, 0x7, 4},
- {MR3, 1, 0x7, 6},
- {MR3, 8, 0x7, 3},
- {0, 0, 0, 0},
-};
-
-static inline void nds32_reg_set(uint32_t number, const char *simple_mnemonic,
- const char *symbolic_mnemonic, uint32_t sr_index,
- enum nds32_reg_type_s type, uint8_t size)
-{
- nds32_regs[number].simple_mnemonic = simple_mnemonic;
- nds32_regs[number].symbolic_mnemonic = symbolic_mnemonic;
- nds32_regs[number].sr_index = sr_index;
- nds32_regs[number].type = type;
- nds32_regs[number].size = size;
-}
-
-void nds32_reg_init(void)
-{
- if (nds32_reg_init_done == true)
- return;
-
- nds32_reg_set(R0, "r0", "r0", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R1, "r1", "r1", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R2, "r2", "r2", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R3, "r3", "r3", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R4, "r4", "r4", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R5, "r5", "r5", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R6, "r6", "r6", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R7, "r7", "r7", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R8, "r8", "r8", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R9, "r9", "r9", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R10, "r10", "r10", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R11, "r11", "r11", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R12, "r12", "r12", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R13, "r13", "r13", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R14, "r14", "r14", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R15, "r15", "r15", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R16, "r16", "r16", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R17, "r17", "r17", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R18, "r18", "r18", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R19, "r19", "r19", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R20, "r20", "r20", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R21, "r21", "r21", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R22, "r22", "r22", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R23, "r23", "r23", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R24, "r24", "r24", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R25, "r25", "r25", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R26, "r26", "p0", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R27, "r27", "p1", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R28, "fp", "fp", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R29, "gp", "gp", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R30, "lp", "lp", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(R31, "sp", "sp", 0, NDS32_REG_TYPE_GPR, 32);
- nds32_reg_set(PC, "pc", "pc", 31, NDS32_REG_TYPE_SPR, 32);
-
- nds32_reg_set(D0LO, "d0lo", "d0lo", 0, NDS32_REG_TYPE_SPR, 32);
- nds32_reg_set(D0HI, "d0hi", "d0hi", 1, NDS32_REG_TYPE_SPR, 32);
- nds32_reg_set(D1LO, "d1lo", "d1lo", 2, NDS32_REG_TYPE_SPR, 32);
- nds32_reg_set(D1HI, "d1hi", "d1hi", 3, NDS32_REG_TYPE_SPR, 32);
- nds32_reg_set(ITB, "itb", "itb", 28, NDS32_REG_TYPE_SPR, 32);
- nds32_reg_set(IFC_LP, "ifc_lp", "ifc_lp", 29, NDS32_REG_TYPE_SPR, 32);
-
- nds32_reg_set(CR0, "cr0", "CPU_VER", SRIDX(0, 0, 0), NDS32_REG_TYPE_CR, 32);
- nds32_reg_set(CR1, "cr1", "ICM_CFG", SRIDX(0, 1, 0), NDS32_REG_TYPE_CR, 32);
- nds32_reg_set(CR2, "cr2", "DCM_CFG", SRIDX(0, 2, 0), NDS32_REG_TYPE_CR, 32);
- nds32_reg_set(CR3, "cr3", "MMU_CFG", SRIDX(0, 3, 0), NDS32_REG_TYPE_CR, 32);
- nds32_reg_set(CR4, "cr4", "MSC_CFG", SRIDX(0, 4, 0), NDS32_REG_TYPE_CR, 32);
- nds32_reg_set(CR5, "cr5", "CORE_ID", SRIDX(0, 0, 1), NDS32_REG_TYPE_CR, 32);
- nds32_reg_set(CR6, "cr6", "FUCOP_EXIST", SRIDX(0, 5, 0), NDS32_REG_TYPE_CR, 32);
-
- nds32_reg_set(IR0, "ir0", "PSW", SRIDX(1, 0, 0), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR1, "ir1", "IPSW", SRIDX(1, 0, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR2, "ir2", "P_IPSW", SRIDX(1, 0, 2), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR3, "ir3", "IVB", SRIDX(1, 1, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR4, "ir4", "EVA", SRIDX(1, 2, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR5, "ir5", "P_EVA", SRIDX(1, 2, 2), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR6, "ir6", "ITYPE", SRIDX(1, 3, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR7, "ir7", "P_ITYPE", SRIDX(1, 3, 2), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR8, "ir8", "MERR", SRIDX(1, 4, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR9, "ir9", "IPC", SRIDX(1, 5, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR10, "ir10", "P_IPC", SRIDX(1, 5, 2), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR11, "ir11", "OIPC", SRIDX(1, 5, 3), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR12, "ir12", "P_P0", SRIDX(1, 6, 2), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR13, "ir13", "P_P1", SRIDX(1, 7, 2), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR14, "ir14", "INT_MASK", SRIDX(1, 8, 0), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR15, "ir15", "INT_PEND", SRIDX(1, 9, 0), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR16, "ir16", "", SRIDX(1, 10, 0), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR17, "ir17", "", SRIDX(1, 10, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR18, "ir18", "", SRIDX(1, 11, 0), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR19, "ir19", "", SRIDX(1, 1, 2), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR20, "ir20", "", SRIDX(1, 10, 2), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR21, "ir21", "", SRIDX(1, 10, 3), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR22, "ir22", "", SRIDX(1, 10, 4), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR23, "ir23", "", SRIDX(1, 10, 5), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR24, "ir24", "", SRIDX(1, 10, 6), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR25, "ir25", "", SRIDX(1, 10, 7), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR26, "ir26", "", SRIDX(1, 8, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR27, "ir27", "", SRIDX(1, 9, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR28, "ir28", "", SRIDX(1, 11, 1), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR29, "ir29", "", SRIDX(1, 9, 4), NDS32_REG_TYPE_IR, 32);
- nds32_reg_set(IR30, "ir30", "", SRIDX(1, 1, 3), NDS32_REG_TYPE_IR, 32);
-
- nds32_reg_set(MR0, "mr0", "MMU_CTL", SRIDX(2, 0, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR1, "mr1", "L1_PPTB", SRIDX(2, 1, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR2, "mr2", "TLB_VPN", SRIDX(2, 2, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR3, "mr3", "TLB_DATA", SRIDX(2, 3, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR4, "mr4", "TLB_MISC", SRIDX(2, 4, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR5, "mr5", "VLPT_IDX", SRIDX(2, 5, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR6, "mr6", "ILMB", SRIDX(2, 6, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR7, "mr7", "DLMB", SRIDX(2, 7, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR8, "mr8", "CACHE_CTL", SRIDX(2, 8, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR9, "mr9", "HSMP_SADDR", SRIDX(2, 9, 0), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR10, "mr10", "HSMP_EADDR", SRIDX(2, 9, 1), NDS32_REG_TYPE_MR, 32);
- nds32_reg_set(MR11, "mr11", "", SRIDX(2, 0, 1), NDS32_REG_TYPE_MR, 32);
-
- nds32_reg_set(DR0, "dr0", "BPC0", SRIDX(3, 0, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR1, "dr1", "BPA0", SRIDX(3, 1, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR2, "dr2", "BPAM0", SRIDX(3, 2, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR3, "dr3", "BPV0", SRIDX(3, 3, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR4, "dr4", "BPCID0", SRIDX(3, 4, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR5, "dr5", "BPC1", SRIDX(3, 0, 1), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR6, "dr6", "BPA1", SRIDX(3, 1, 1), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR7, "dr7", "BPAM1", SRIDX(3, 2, 1), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR8, "dr8", "BPV1", SRIDX(3, 3, 1), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR9, "dr9", "BPCID1", SRIDX(3, 4, 1), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR10, "dr10", "BPC2", SRIDX(3, 0, 2), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR11, "dr11", "BPA2", SRIDX(3, 1, 2), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR12, "dr12", "BPAM2", SRIDX(3, 2, 2), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR13, "dr13", "BPV2", SRIDX(3, 3, 2), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR14, "dr14", "BPCID2", SRIDX(3, 4, 2), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR15, "dr15", "BPC3", SRIDX(3, 0, 3), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR16, "dr16", "BPA3", SRIDX(3, 1, 3), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR17, "dr17", "BPAM3", SRIDX(3, 2, 3), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR18, "dr18", "BPV3", SRIDX(3, 3, 3), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR19, "dr19", "BPCID3", SRIDX(3, 4, 3), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR20, "dr20", "BPC4", SRIDX(3, 0, 4), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR21, "dr21", "BPA4", SRIDX(3, 1, 4), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR22, "dr22", "BPAM4", SRIDX(3, 2, 4), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR23, "dr23", "BPV4", SRIDX(3, 3, 4), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR24, "dr24", "BPCID4", SRIDX(3, 4, 4), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR25, "dr25", "BPC5", SRIDX(3, 0, 5), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR26, "dr26", "BPA5", SRIDX(3, 1, 5), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR27, "dr27", "BPAM5", SRIDX(3, 2, 5), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR28, "dr28", "BPV5", SRIDX(3, 3, 5), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR29, "dr29", "BPCID5", SRIDX(3, 4, 5), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR30, "dr30", "BPC6", SRIDX(3, 0, 6), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR31, "dr31", "BPA6", SRIDX(3, 1, 6), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR32, "dr32", "BPAM6", SRIDX(3, 2, 6), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR33, "dr33", "BPV6", SRIDX(3, 3, 6), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR34, "dr34", "BPCID6", SRIDX(3, 4, 6), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR35, "dr35", "BPC7", SRIDX(3, 0, 7), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR36, "dr36", "BPA7", SRIDX(3, 1, 7), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR37, "dr37", "BPAM7", SRIDX(3, 2, 7), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR38, "dr38", "BPV7", SRIDX(3, 3, 7), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR39, "dr39", "BPCID7", SRIDX(3, 4, 7), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR40, "dr40", "EDM_CFG", SRIDX(3, 5, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR41, "dr41", "EDMSW", SRIDX(3, 6, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR42, "dr42", "EDM_CTL", SRIDX(3, 7, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR43, "dr43", "EDM_DTR", SRIDX(3, 8, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR44, "dr44", "BPMTC", SRIDX(3, 9, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR45, "dr45", "DIMBR", SRIDX(3, 10, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR46, "dr46", "TECR0", SRIDX(3, 14, 0), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR47, "dr47", "TECR1", SRIDX(3, 14, 1), NDS32_REG_TYPE_DR, 32);
- nds32_reg_set(DR48, "dr48", "", SRIDX(3, 11, 0), NDS32_REG_TYPE_DR, 32);
-
- nds32_reg_set(PFR0, "pfr0", "PFMC0", SRIDX(4, 0, 0), NDS32_REG_TYPE_PFR, 32);
- nds32_reg_set(PFR1, "pfr1", "PFMC1", SRIDX(4, 0, 1), NDS32_REG_TYPE_PFR, 32);
- nds32_reg_set(PFR2, "pfr2", "PFMC2", SRIDX(4, 0, 2), NDS32_REG_TYPE_PFR, 32);
- nds32_reg_set(PFR3, "pfr3", "PFM_CTL", SRIDX(4, 1, 0), NDS32_REG_TYPE_PFR, 32);
-
- nds32_reg_set(DMAR0, "dmar0", "DMA_CFG", SRIDX(5, 0, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR1, "dmar1", "DMA_GCSW", SRIDX(5, 1, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR2, "dmar2", "DMA_CHNSEL", SRIDX(5, 2, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR3, "dmar3", "DMA_ACT", SRIDX(5, 3, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR4, "dmar4", "DMA_SETUP", SRIDX(5, 4, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR5, "dmar5", "DMA_ISADDR", SRIDX(5, 5, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR6, "dmar6", "DMA_ESADDR", SRIDX(5, 6, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR7, "dmar7", "DMA_TCNT", SRIDX(5, 7, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR8, "dmar8", "DMA_STATUS", SRIDX(5, 8, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR9, "dmar9", "DMA_2DSET", SRIDX(5, 9, 0), NDS32_REG_TYPE_DMAR, 32);
- nds32_reg_set(DMAR10, "dmar10", "DMA_2DSCTL", SRIDX(5, 9, 1), NDS32_REG_TYPE_DMAR, 32);
-
- nds32_reg_set(RACR, "racr", "PRUSR_ACC_CTL", SRIDX(4, 4, 0), NDS32_REG_TYPE_RACR, 32);
- nds32_reg_set(FUCPR, "fucpr", "FUCOP_CTL", SRIDX(4, 5, 0), NDS32_REG_TYPE_RACR, 32);
-
- nds32_reg_set(IDR0, "idr0", "SDZ_CTL", SRIDX(2, 15, 0), NDS32_REG_TYPE_IDR, 32);
- nds32_reg_set(IDR1, "idr1", "MISC_CTL", SRIDX(2, 15, 1), NDS32_REG_TYPE_IDR, 32);
-
- nds32_reg_set(SECUR0, "secur0", "", SRIDX(6, 0, 0), NDS32_REG_TYPE_SECURE, 32);
-
- nds32_reg_set(D0L24, "D0L24", "D0L24", 0x10, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(D1L24, "D1L24", "D1L24", 0x11, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(I0, "I0", "I0", 0x0, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(I1, "I1", "I1", 0x1, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(I2, "I2", "I2", 0x2, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(I3, "I3", "I3", 0x3, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(I4, "I4", "I4", 0x4, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(I5, "I5", "I5", 0x5, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(I6, "I6", "I6", 0x6, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(I7, "I7", "I7", 0x7, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(M1, "M1", "M1", 0x9, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(M2, "M2", "M2", 0xA, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(M3, "M3", "M3", 0xB, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(M5, "M5", "M5", 0xD, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(M6, "M6", "M6", 0xE, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(M7, "M7", "M7", 0xF, NDS32_REG_TYPE_AUMR, 32);
-
- nds32_reg_set(MOD, "MOD", "MOD", 0x8, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(LBE, "LBE", "LBE", 0x18, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(LE, "LE", "LE", 0x19, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(LC, "LC", "LC", 0x1A, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(ADM_VBASE, "ADM_VBASE", "ADM_VBASE", 0x1B, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(SHFT_CTL0, "SHFT_CTL0", "SHFT_CTL0", 0x12, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(SHFT_CTL1, "SHFT_CTL1", "SHFT_CTL1", 0x13, NDS32_REG_TYPE_AUMR, 32);
-
- nds32_reg_set(CB_CTL, "CB_CTL", "CB_CTL", 0x1F, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(CBB0, "CBB0", "CBB0", 0x0, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(CBB1, "CBB1", "CBB1", 0x1, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(CBB2, "CBB2", "CBB2", 0x2, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(CBB3, "CBB3", "CBB3", 0x3, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(CBE0, "CBE0", "CBE0", 0x4, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(CBE1, "CBE1", "CBE1", 0x5, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(CBE2, "CBE2", "CBE2", 0x6, NDS32_REG_TYPE_AUMR, 32);
- nds32_reg_set(CBE3, "CBE3", "CBE3", 0x7, NDS32_REG_TYPE_AUMR, 32);
-
- nds32_reg_set(FPCSR, "fpcsr", "FPCSR", 0x7, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FPCFG, "fpcfg", "FPCFG", 0x7, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS0, "fs0", "FS0", 0, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS1, "fs1", "FS1", 1, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS2, "fs2", "FS2", 2, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS3, "fs3", "FS3", 3, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS4, "fs4", "FS4", 4, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS5, "fs5", "FS5", 5, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS6, "fs6", "FS6", 6, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS7, "fs7", "FS7", 7, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS8, "fs8", "FS8", 8, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS9, "fs9", "FS9", 9, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS10, "fs10", "FS10", 10, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS11, "fs11", "FS11", 11, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS12, "fs12", "FS12", 12, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS13, "fs13", "FS13", 13, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS14, "fs14", "FS14", 14, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS15, "fs15", "FS15", 15, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS16, "fs16", "FS16", 16, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS17, "fs17", "FS17", 17, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS18, "fs18", "FS18", 18, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS19, "fs19", "FS19", 19, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS20, "fs20", "FS20", 20, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS21, "fs21", "FS21", 21, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS22, "fs22", "FS22", 22, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS23, "fs23", "FS23", 23, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS24, "fs24", "FS24", 24, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS25, "fs25", "FS25", 25, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS26, "fs26", "FS26", 26, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS27, "fs27", "FS27", 27, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS28, "fs28", "FS28", 28, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS29, "fs29", "FS29", 29, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS30, "fs30", "FS30", 30, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FS31, "fs31", "FS31", 31, NDS32_REG_TYPE_FPU, 32);
- nds32_reg_set(FD0, "fd0", "FD0", 0, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD1, "fd1", "FD1", 1, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD2, "fd2", "FD2", 2, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD3, "fd3", "FD3", 3, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD4, "fd4", "FD4", 4, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD5, "fd5", "FD5", 5, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD6, "fd6", "FD6", 6, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD7, "fd7", "FD7", 7, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD8, "fd8", "FD8", 8, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD9, "fd9", "FD9", 9, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD10, "fd10", "FD10", 10, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD11, "fd11", "FD11", 11, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD12, "fd12", "FD12", 12, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD13, "fd13", "FD13", 13, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD14, "fd14", "FD14", 14, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD15, "fd15", "FD15", 15, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD16, "fd16", "FD16", 16, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD17, "fd17", "FD17", 17, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD18, "fd18", "FD18", 18, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD19, "fd19", "FD19", 19, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD20, "fd20", "FD20", 20, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD21, "fd21", "FD21", 21, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD22, "fd22", "FD22", 22, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD23, "fd23", "FD23", 23, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD24, "fd24", "FD24", 24, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD25, "fd25", "FD25", 25, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD26, "fd26", "FD26", 26, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD27, "fd27", "FD27", 27, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD28, "fd28", "FD28", 28, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD29, "fd29", "FD29", 29, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD30, "fd30", "FD30", 30, NDS32_REG_TYPE_FPU, 64);
- nds32_reg_set(FD31, "fd31", "FD31", 31, NDS32_REG_TYPE_FPU, 64);
-
- nds32_reg_init_done = true;
-}
-
-uint32_t nds32_reg_sr_index(uint32_t number)
-{
- return nds32_regs[number].sr_index;
-}
-
-enum nds32_reg_type_s nds32_reg_type(uint32_t number)
-{
- return nds32_regs[number].type;
-}
-
-uint8_t nds32_reg_size(uint32_t number)
-{
- return nds32_regs[number].size;
-}
-
-const char *nds32_reg_simple_name(uint32_t number)
-{
- return nds32_regs[number].simple_mnemonic;
-}
-
-const char *nds32_reg_symbolic_name(uint32_t number)
-{
- return nds32_regs[number].symbolic_mnemonic;
-}
-
-bool nds32_reg_exception(uint32_t number, uint32_t value)
-{
- int i;
- const struct nds32_reg_exception_s *ex_reg_value;
- uint32_t field_value;
-
- i = 0;
- while (nds32_ex_reg_values[i].reg_num != 0) {
- ex_reg_value = nds32_ex_reg_values + i;
-
- if (ex_reg_value->reg_num == number) {
- field_value = (value >> ex_reg_value->ex_value_bit_pos) &
- ex_reg_value->ex_value_mask;
- if (field_value == ex_reg_value->ex_value) {
- LOG_WARNING("It will generate exceptions as setting %" PRIu32 " to %s",
- value, nds32_regs[number].simple_mnemonic);
- return true;
- }
- }
-
- i++;
- }
-
- return false;
-}
diff --git a/src/target/nds32_reg.h b/src/target/nds32_reg.h
deleted file mode 100644
index 30cd241..0000000
--- a/src/target/nds32_reg.h
+++ /dev/null
@@ -1,314 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_REG_H
-#define OPENOCD_TARGET_NDS32_REG_H
-
-#define SRIDX(a, b, c) ((a << 7) | (b << 3) | c)
-#define NDS32_REGISTER_DISABLE (0x0)
-
-enum nds32_reg_number_s {
- R0 = 0, /* general registers */
- R1,
- R2,
- R3,
- R4,
- R5,
- R6,
- R7,
- R8,
- R9,
- R10,
- R11,
- R12,
- R13,
- R14,
- R15,
- R16,
- R17,
- R18,
- R19,
- R20,
- R21,
- R22,
- R23,
- R24,
- R25,
- R26,
- R27,
- R28,
- R29,
- R30,
- R31,
- PC,
- D0LO,
- D0HI,
- D1LO,
- D1HI,
- ITB,
- IFC_LP,
- CR0, /* system registers */
- CR1,
- CR2,
- CR3,
- CR4,
- CR5,
- CR6,
- IR0,
- IR1,
- IR2,
- IR3,
- IR4,
- IR5,
- IR6,
- IR7,
- IR8,
- IR9,
- IR10,
- IR11,
- IR12,
- IR13,
- IR14,
- IR15,
- IR16,
- IR17,
- IR18,
- IR19,
- IR20,
- IR21,
- IR22,
- IR23,
- IR24,
- IR25,
- IR26,
- IR27,
- IR28,
- IR29,
- IR30,
- MR0,
- MR1,
- MR2,
- MR3,
- MR4,
- MR5,
- MR6,
- MR7,
- MR8,
- MR9,
- MR10,
- MR11,
- DR0,
- DR1,
- DR2,
- DR3,
- DR4,
- DR5,
- DR6,
- DR7,
- DR8,
- DR9,
- DR10,
- DR11,
- DR12,
- DR13,
- DR14,
- DR15,
- DR16,
- DR17,
- DR18,
- DR19,
- DR20,
- DR21,
- DR22,
- DR23,
- DR24,
- DR25,
- DR26,
- DR27,
- DR28,
- DR29,
- DR30,
- DR31,
- DR32,
- DR33,
- DR34,
- DR35,
- DR36,
- DR37,
- DR38,
- DR39,
- DR40,
- DR41,
- DR42,
- DR43,
- DR44,
- DR45,
- DR46,
- DR47,
- DR48,
- PFR0,
- PFR1,
- PFR2,
- PFR3,
- DMAR0,
- DMAR1,
- DMAR2,
- DMAR3,
- DMAR4,
- DMAR5,
- DMAR6,
- DMAR7,
- DMAR8,
- DMAR9,
- DMAR10,
- RACR,
- FUCPR,
- IDR0,
- IDR1,
- SECUR0,
- D0L24, /* audio registers */
- D1L24,
- I0,
- I1,
- I2,
- I3,
- I4,
- I5,
- I6,
- I7,
- M1,
- M2,
- M3,
- M5,
- M6,
- M7,
- MOD,
- LBE,
- LE,
- LC,
- ADM_VBASE,
- SHFT_CTL0,
- SHFT_CTL1,
- CB_CTL,
- CBB0,
- CBB1,
- CBB2,
- CBB3,
- CBE0,
- CBE1,
- CBE2,
- CBE3,
- FPCSR, /* fpu */
- FPCFG,
- FS0,
- FS1,
- FS2,
- FS3,
- FS4,
- FS5,
- FS6,
- FS7,
- FS8,
- FS9,
- FS10,
- FS11,
- FS12,
- FS13,
- FS14,
- FS15,
- FS16,
- FS17,
- FS18,
- FS19,
- FS20,
- FS21,
- FS22,
- FS23,
- FS24,
- FS25,
- FS26,
- FS27,
- FS28,
- FS29,
- FS30,
- FS31,
- FD0,
- FD1,
- FD2,
- FD3,
- FD4,
- FD5,
- FD6,
- FD7,
- FD8,
- FD9,
- FD10,
- FD11,
- FD12,
- FD13,
- FD14,
- FD15,
- FD16,
- FD17,
- FD18,
- FD19,
- FD20,
- FD21,
- FD22,
- FD23,
- FD24,
- FD25,
- FD26,
- FD27,
- FD28,
- FD29,
- FD30,
- FD31,
-
- TOTAL_REG_NUM,
-};
-
-enum nds32_reg_type_s {
- NDS32_REG_TYPE_GPR = 0,
- NDS32_REG_TYPE_SPR,
- NDS32_REG_TYPE_CR,
- NDS32_REG_TYPE_IR,
- NDS32_REG_TYPE_MR,
- NDS32_REG_TYPE_DR,
- NDS32_REG_TYPE_PFR,
- NDS32_REG_TYPE_DMAR,
- NDS32_REG_TYPE_RACR,
- NDS32_REG_TYPE_IDR,
- NDS32_REG_TYPE_AUMR,
- NDS32_REG_TYPE_SECURE,
- NDS32_REG_TYPE_FPU,
-};
-
-struct nds32_reg_s {
- const char *simple_mnemonic;
- const char *symbolic_mnemonic;
- uint32_t sr_index;
- enum nds32_reg_type_s type;
- uint8_t size;
-};
-
-struct nds32_reg_exception_s {
- uint32_t reg_num;
- uint32_t ex_value_bit_pos;
- uint32_t ex_value_mask;
- uint32_t ex_value;
-};
-
-void nds32_reg_init(void);
-uint32_t nds32_reg_sr_index(uint32_t number);
-enum nds32_reg_type_s nds32_reg_type(uint32_t number);
-uint8_t nds32_reg_size(uint32_t number);
-const char *nds32_reg_simple_name(uint32_t number);
-const char *nds32_reg_symbolic_name(uint32_t number);
-bool nds32_reg_exception(uint32_t number, uint32_t value);
-
-#endif /* OPENOCD_TARGET_NDS32_REG_H */
diff --git a/src/target/nds32_tlb.c b/src/target/nds32_tlb.c
deleted file mode 100644
index a533e59..0000000
--- a/src/target/nds32_tlb.c
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "nds32_aice.h"
-#include "nds32_tlb.h"
-
-int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address,
- target_addr_t *physical_address)
-{
- struct target *target = nds32->target;
- struct aice_port_s *aice = target_to_aice(target);
-
- return aice_read_tlb(aice, virtual_address, physical_address);
-}
-
-static struct page_table_walker_info_s page_table_info[PAGE_SIZE_NUM] = {
- /* 4K page */
- {0xFFC00000, 20, 0x003FF000, 10, 0x00000FFF, 0xFFFFF000, 0xFFFFF000, 0xFFFFF000},
- /* 8K page */
- {0xFF000000, 22, 0x00FFE000, 11, 0x00001FFF, 0xFFFFF000, 0xFFFFE000, 0xFFFFE000},
-};
-
-int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address,
- target_addr_t *physical_address)
-{
- struct target *target = nds32->target;
- uint32_t value_mr1;
- uint32_t load_address;
- uint32_t l1_page_table_entry;
- uint32_t l2_page_table_entry;
- uint32_t page_size_index = nds32->mmu_config.default_min_page_size;
- struct page_table_walker_info_s *page_table_info_p =
- &(page_table_info[page_size_index]);
-
- /* Read L1 Physical Page Table */
- nds32_get_mapped_reg(nds32, MR1, &value_mr1);
- load_address = (value_mr1 & page_table_info_p->l1_base_mask) |
- ((virtual_address & page_table_info_p->l1_offset_mask) >>
- page_table_info_p->l1_offset_shift);
- /* load_address is physical address */
- nds32_read_buffer(target, load_address, 4, (uint8_t *)&l1_page_table_entry);
-
- /* Read L2 Physical Page Table */
- if (l1_page_table_entry & 0x1) /* L1_PTE not present */
- return ERROR_FAIL;
-
- load_address = (l1_page_table_entry & page_table_info_p->l2_base_mask) |
- ((virtual_address & page_table_info_p->l2_offset_mask) >>
- page_table_info_p->l2_offset_shift);
- /* load_address is physical address */
- nds32_read_buffer(target, load_address, 4, (uint8_t *)&l2_page_table_entry);
-
- if ((l2_page_table_entry & 0x1) != 0x1) /* L2_PTE not valid */
- return ERROR_FAIL;
-
- *physical_address = (l2_page_table_entry & page_table_info_p->ppn_mask) |
- (virtual_address & page_table_info_p->va_offset_mask);
-
- return ERROR_OK;
-}
diff --git a/src/target/nds32_tlb.h b/src/target/nds32_tlb.h
deleted file mode 100644
index 1edff29..0000000
--- a/src/target/nds32_tlb.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_TLB_H
-#define OPENOCD_TARGET_NDS32_TLB_H
-
-#include "nds32.h"
-
-enum {
- PAGE_SIZE_4K = 0,
- PAGE_SIZE_8K,
- PAGE_SIZE_NUM,
-};
-
-struct page_table_walker_info_s {
-
- uint32_t l1_offset_mask;
- uint32_t l1_offset_shift;
- uint32_t l2_offset_mask;
- uint32_t l2_offset_shift;
- uint32_t va_offset_mask;
- uint32_t l1_base_mask;
- uint32_t l2_base_mask;
- uint32_t ppn_mask;
-};
-
-extern int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address,
- target_addr_t *physical_address);
-extern int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address,
- target_addr_t *physical_address);
-
-#endif /* OPENOCD_TARGET_NDS32_TLB_H */
diff --git a/src/target/nds32_v2.c b/src/target/nds32_v2.c
deleted file mode 100644
index 2149291..0000000
--- a/src/target/nds32_v2.c
+++ /dev/null
@@ -1,774 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <helper/time_support.h>
-#include <helper/binarybuffer.h>
-#include "breakpoints.h"
-#include "nds32_insn.h"
-#include "nds32_reg.h"
-#include "nds32_edm.h"
-#include "nds32_cmd.h"
-#include "nds32_v2.h"
-#include "nds32_aice.h"
-#include "target_type.h"
-
-static int nds32_v2_register_mapping(struct nds32 *nds32, int reg_no)
-{
- uint32_t max_level = nds32->max_interrupt_level;
- uint32_t cur_level = nds32->current_interrupt_level;
-
- if ((cur_level >= 1) && (cur_level < max_level)) {
- if (reg_no == IR0) {
- LOG_DEBUG("Map PSW to IPSW");
- return IR1;
- } else if (reg_no == PC) {
- LOG_DEBUG("Map PC to IPC");
- return IR9;
- }
- } else if ((cur_level >= 2) && (cur_level < max_level)) {
- if (reg_no == R26) {
- LOG_DEBUG("Mapping P0 to P_P0");
- return IR12;
- } else if (reg_no == R27) {
- LOG_DEBUG("Mapping P1 to P_P1");
- return IR13;
- } else if (reg_no == IR1) {
- LOG_DEBUG("Mapping IPSW to P_IPSW");
- return IR2;
- } else if (reg_no == IR4) {
- LOG_DEBUG("Mapping EVA to P_EVA");
- return IR5;
- } else if (reg_no == IR6) {
- LOG_DEBUG("Mapping ITYPE to P_ITYPE");
- return IR7;
- } else if (reg_no == IR9) {
- LOG_DEBUG("Mapping IPC to P_IPC");
- return IR10;
- }
- } else if (cur_level == max_level) {
- if (reg_no == PC) {
- LOG_DEBUG("Mapping PC to O_IPC");
- return IR11;
- }
- }
-
- return reg_no;
-}
-
-static int nds32_v2_get_debug_reason(struct nds32 *nds32, uint32_t *reason)
-{
- uint32_t val_itype;
- struct aice_port_s *aice = target_to_aice(nds32->target);
-
- aice_read_register(aice, IR6, &val_itype);
-
- *reason = val_itype & 0x0F;
-
- return ERROR_OK;
-}
-
-static int nds32_v2_activate_hardware_breakpoint(struct target *target)
-{
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct breakpoint *bp;
- int32_t hbr_index = 0;
-
- for (bp = target->breakpoints; bp; bp = bp->next) {
- if (bp->type == BKPT_SOFT) {
- /* already set at nds32_v2_add_breakpoint() */
- continue;
- } else if (bp->type == BKPT_HARD) {
- /* set address */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address);
- /* set mask */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0);
- /* set value */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0);
-
- if (nds32_v2->nds32.memory.address_translation)
- /* enable breakpoint (virtual address) */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2);
- else
- /* enable breakpoint (physical address) */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA);
-
- LOG_DEBUG("Add hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
- bp->address);
-
- hbr_index++;
- } else {
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v2_deactivate_hardware_breakpoint(struct target *target)
-{
- struct aice_port_s *aice = target_to_aice(target);
- struct breakpoint *bp;
- int32_t hbr_index = 0;
-
- for (bp = target->breakpoints; bp; bp = bp->next) {
- if (bp->type == BKPT_SOFT)
- continue;
- else if (bp->type == BKPT_HARD)
- /* disable breakpoint */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0);
- else
- return ERROR_FAIL;
-
- LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
- bp->address);
-
- hbr_index++;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v2_activate_hardware_watchpoint(struct target *target)
-{
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
- struct watchpoint *wp;
- int32_t wp_num = nds32_v2->next_hbr_index;
- uint32_t wp_config = 0;
-
- for (wp = target->watchpoints; wp; wp = wp->next) {
-
- wp_num--;
- wp->mask = wp->length - 1;
- if ((wp->address % wp->length) != 0)
- wp->mask = (wp->mask << 1) + 1;
-
- if (wp->rw == WPT_READ)
- wp_config = 0x3;
- else if (wp->rw == WPT_WRITE)
- wp_config = 0x5;
- else if (wp->rw == WPT_ACCESS)
- wp_config = 0x7;
-
- /* set/unset physical address bit of BPCn according to PSW.DT */
- if (nds32_v2->nds32.memory.address_translation == false)
- wp_config |= 0x8;
-
- /* set address */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num,
- wp->address - (wp->address % wp->length));
- /* set mask */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask);
- /* enable watchpoint */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config);
- /* set value */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0);
-
- LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32, wp_num,
- wp->address, wp->mask);
-
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v2_deactivate_hardware_watchpoint(struct target *target)
-{
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
- int32_t wp_num = nds32_v2->next_hbr_index;
- struct watchpoint *wp;
-
- for (wp = target->watchpoints; wp; wp = wp->next) {
- wp_num--;
- /* disable watchpoint */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0);
-
- LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32,
- wp_num, wp->address, wp->mask);
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v2_check_interrupt_stack(struct nds32_v2_common *nds32_v2)
-{
- struct nds32 *nds32 = &(nds32_v2->nds32);
- struct aice_port_s *aice = target_to_aice(nds32->target);
- uint32_t val_ir0;
- uint32_t val_ir1;
- uint32_t val_ir2;
- uint32_t modified_psw;
-
- /* Save interrupt level */
- aice_read_register(aice, IR0, &val_ir0); /* get $IR0 directly */
-
- /* backup $IR0 */
- nds32_v2->backup_ir0 = val_ir0;
-
- nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3;
-
- if (nds32_reach_max_interrupt_level(nds32)) {
- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->",
- nds32->current_interrupt_level);
-
- /* decrease interrupt level */
- modified_psw = val_ir0 - 0x2;
-
- /* disable GIE, IT, DT, HSS */
- modified_psw &= (~0x8C1);
-
- aice_write_register(aice, IR0, modified_psw);
-
- return ERROR_OK;
- }
-
- /* There is a case that single step also trigger another interrupt,
- then HSS bit in psw(ir0) will push to ipsw(ir1).
- Then hit debug interrupt HSS bit in ipsw(ir1) will push to (p_ipsw)ir2
- Therefore, HSS bit in p_ipsw(ir2) also need clear.
-
- Only update $ir2 as current interrupt level is 2, because $ir2 will be random
- value if the target never reaches interrupt level 2. */
- if ((nds32->max_interrupt_level == 3) && (nds32->current_interrupt_level == 2)) {
- aice_read_register(aice, IR2, &val_ir2); /* get $IR2 directly */
- val_ir2 &= ~(0x01 << 11);
- aice_write_register(aice, IR2, val_ir2);
- }
-
- /* get original DT bit and set to current state let debugger has same memory view
- PSW.IT MUST be turned off. Otherwise, DIM could not operate normally. */
- aice_read_register(aice, IR1, &val_ir1);
- modified_psw = val_ir0 | (val_ir1 & 0x80);
- aice_write_register(aice, IR0, modified_psw);
-
- return ERROR_OK;
-}
-
-static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common *nds32_v2)
-{
- struct nds32 *nds32 = &(nds32_v2->nds32);
- struct aice_port_s *aice = target_to_aice(nds32->target);
-
- /* restore origin $IR0 */
- aice_write_register(aice, IR0, nds32_v2->backup_ir0);
-
- return ERROR_OK;
-}
-
-/**
- * Save processor state. This is called after a HALT instruction
- * succeeds, and on other occasions the processor enters debug mode
- * (breakpoint, watchpoint, etc).
- */
-static int nds32_v2_debug_entry(struct nds32 *nds32, bool enable_watchpoint)
-{
- LOG_DEBUG("nds32_v2_debug_entry");
-
- if (nds32->virtual_hosting)
- LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported "
- "under V1/V2 architecture. -->");
-
- enum target_state backup_state = nds32->target->state;
- nds32->target->state = TARGET_HALTED;
-
- if (nds32->init_arch_info_after_halted == false) {
- /* init architecture info according to config registers */
- CHECK_RETVAL(nds32_config(nds32));
-
- nds32->init_arch_info_after_halted = true;
- }
-
- /* REVISIT entire cache should already be invalid !!! */
- register_cache_invalidate(nds32->core_cache);
-
- /* deactivate all hardware breakpoints */
- CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32->target));
-
- if (enable_watchpoint)
- CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32->target));
-
- if (nds32_examine_debug_reason(nds32) != ERROR_OK) {
- nds32->target->state = backup_state;
-
- /* re-activate all hardware breakpoints & watchpoints */
- CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
-
- if (enable_watchpoint) {
- /* activate all watchpoints */
- CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
- }
-
- return ERROR_FAIL;
- }
-
- /* check interrupt level before .full_context(), because
- * get_mapped_reg() in nds32_full_context() needs current_interrupt_level
- * information */
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
- nds32_v2_check_interrupt_stack(nds32_v2);
-
- /* Save registers. */
- nds32_full_context(nds32);
-
- return ERROR_OK;
-}
-
-/* target request support */
-static int nds32_v2_target_request_data(struct target *target,
- uint32_t size, uint8_t *buffer)
-{
- /* AndesCore could use DTR register to communicate with OpenOCD
- * to output messages
- * Target data will be put in buffer
- * The format of DTR is as follow
- * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
- * target_req_cmd has three possible values:
- * TARGET_REQ_TRACEMSG
- * TARGET_REQ_DEBUGMSG
- * TARGET_REQ_DEBUGCHAR
- * if size == 0, target will call target_asciimsg(),
- * else call target_hexmsg()
- */
- LOG_WARNING("Not implemented: %s", __func__);
-
- return ERROR_OK;
-}
-
-/**
- * Restore processor state.
- */
-static int nds32_v2_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint)
-{
- LOG_DEBUG("nds32_v2_leave_debug_state");
-
- struct target *target = nds32->target;
-
- /* activate all hardware breakpoints */
- CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
-
- if (enable_watchpoint) {
- /* activate all watchpoints */
- CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
- }
-
- /* restore interrupt stack */
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
- nds32_v2_restore_interrupt_stack(nds32_v2);
-
- /* restore PSW, PC, and R0 ... after flushing any modified
- * registers.
- */
- CHECK_RETVAL(nds32_restore_context(target));
-
- register_cache_invalidate(nds32->core_cache);
-
- return ERROR_OK;
-}
-
-static int nds32_v2_deassert_reset(struct target *target)
-{
- int retval;
-
- CHECK_RETVAL(nds32_poll(target));
-
- if (target->state != TARGET_HALTED) {
- /* reset only */
- LOG_WARNING("%s: ran after reset and before halt ...",
- target_name(target));
- retval = target_halt(target);
- if (retval != ERROR_OK)
- return retval;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v2_checksum_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *checksum)
-{
- LOG_WARNING("Not implemented: %s", __func__);
-
- return ERROR_FAIL;
-}
-
-static int nds32_v2_add_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
-{
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
- struct nds32 *nds32 = &(nds32_v2->nds32);
- int result;
-
- if (breakpoint->type == BKPT_HARD) {
- /* check hardware resource */
- if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
- "breakpoints/watchpoints! The limit of "
- "combined hardware breakpoints/watchpoints "
- "is %" PRId32 ". -->", nds32_v2->n_hbr);
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
-
- /* update next place to put hardware breakpoint */
- nds32_v2->next_hbr_index++;
-
- /* hardware breakpoint insertion occurs before 'continue' actually */
- return ERROR_OK;
- } else if (breakpoint->type == BKPT_SOFT) {
- result = nds32_add_software_breakpoint(target, breakpoint);
- if (result != ERROR_OK) {
- /* auto convert to hardware breakpoint if failed */
- if (nds32->auto_convert_hw_bp) {
- /* convert to hardware breakpoint */
- breakpoint->type = BKPT_HARD;
-
- return nds32_v2_add_breakpoint(target, breakpoint);
- }
- }
-
- return result;
- } else /* unrecognized breakpoint type */
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int nds32_v2_remove_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
-{
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
-
- if (breakpoint->type == BKPT_HARD) {
- if (nds32_v2->next_hbr_index <= 0)
- return ERROR_FAIL;
-
- /* update next place to put hardware breakpoint */
- nds32_v2->next_hbr_index--;
-
- /* hardware breakpoint removal occurs after 'halted' actually */
- return ERROR_OK;
- } else if (breakpoint->type == BKPT_SOFT) {
- return nds32_remove_software_breakpoint(target, breakpoint);
- } else /* unrecognized breakpoint type */
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int nds32_v2_add_watchpoint(struct target *target,
- struct watchpoint *watchpoint)
-{
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
-
- /* check hardware resource */
- if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
- "breakpoints/watchpoints! The limit of "
- "combined hardware breakpoints/watchpoints is %" PRId32 ". -->", nds32_v2->n_hbr);
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
-
- /* update next place to put hardware watchpoint */
- nds32_v2->next_hbr_index++;
-
- return ERROR_OK;
-}
-
-static int nds32_v2_remove_watchpoint(struct target *target,
- struct watchpoint *watchpoint)
-{
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
-
- if (nds32_v2->next_hbr_index <= 0)
- return ERROR_FAIL;
-
- /* update next place to put hardware breakpoint */
- nds32_v2->next_hbr_index--;
-
- return ERROR_OK;
-}
-
-static int nds32_v2_get_exception_address(struct nds32 *nds32,
- uint32_t *address, uint32_t reason)
-{
- struct aice_port_s *aice = target_to_aice(nds32->target);
-
- aice_read_register(aice, IR4, address); /* read $EVA directly */
-
- /* TODO: hit multiple watchpoints */
-
- return ERROR_OK;
-}
-
-/**
- * find out which watchpoint hits
- * get exception address and compare the address to watchpoints
- */
-static int nds32_v2_hit_watchpoint(struct target *target,
- struct watchpoint **hit_watchpoint)
-{
- uint32_t exception_address;
- struct watchpoint *wp;
- static struct watchpoint scan_all_watchpoint;
- struct nds32 *nds32 = target_to_nds32(target);
-
- scan_all_watchpoint.address = 0;
- scan_all_watchpoint.rw = WPT_WRITE;
- scan_all_watchpoint.next = 0;
- scan_all_watchpoint.unique_id = 0x5CA8;
-
- exception_address = nds32->watched_address;
-
- if (exception_address == 0) {
- /* send watch:0 to tell GDB to do software scan for hitting multiple watchpoints */
- *hit_watchpoint = &scan_all_watchpoint;
- return ERROR_OK;
- }
-
- for (wp = target->watchpoints; wp; wp = wp->next) {
- if (((exception_address ^ wp->address) & (~wp->mask)) == 0) {
- /* TODO: dispel false match */
- *hit_watchpoint = wp;
- return ERROR_OK;
- }
- }
-
- return ERROR_FAIL;
-}
-
-static int nds32_v2_run_algorithm(struct target *target,
- int num_mem_params,
- struct mem_param *mem_params,
- int num_reg_params,
- struct reg_param *reg_params,
- target_addr_t entry_point,
- target_addr_t exit_point,
- int timeout_ms,
- void *arch_info)
-{
- LOG_WARNING("Not implemented: %s", __func__);
-
- return ERROR_FAIL;
-}
-
-static int nds32_v2_target_create(struct target *target, Jim_Interp *interp)
-{
- struct nds32_v2_common *nds32_v2;
-
- nds32_v2 = calloc(1, sizeof(*nds32_v2));
- if (!nds32_v2)
- return ERROR_FAIL;
-
- nds32_v2->nds32.register_map = nds32_v2_register_mapping;
- nds32_v2->nds32.get_debug_reason = nds32_v2_get_debug_reason;
- nds32_v2->nds32.enter_debug_state = nds32_v2_debug_entry;
- nds32_v2->nds32.leave_debug_state = nds32_v2_leave_debug_state;
- nds32_v2->nds32.get_watched_address = nds32_v2_get_exception_address;
-
- nds32_init_arch_info(target, &(nds32_v2->nds32));
-
- return ERROR_OK;
-}
-
-static int nds32_v2_init_target(struct command_context *cmd_ctx,
- struct target *target)
-{
- /* Initialize anything we can set up without talking to the target */
-
- struct nds32 *nds32 = target_to_nds32(target);
-
- nds32_init(nds32);
-
- return ERROR_OK;
-}
-
-/* talk to the target and set things up */
-static int nds32_v2_examine(struct target *target)
-{
- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
- struct nds32 *nds32 = &(nds32_v2->nds32);
- struct aice_port_s *aice = target_to_aice(target);
-
- if (!target_was_examined(target)) {
- CHECK_RETVAL(nds32_edm_config(nds32));
-
- if (nds32->reset_halt_as_examine)
- CHECK_RETVAL(nds32_reset_halt(nds32));
- }
-
- uint32_t edm_cfg;
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
-
- /* get the number of hardware breakpoints */
- nds32_v2->n_hbr = (edm_cfg & 0x7) + 1;
-
- nds32_v2->next_hbr_index = 0;
-
- LOG_INFO("%s: total hardware breakpoint %" PRId32, target_name(target),
- nds32_v2->n_hbr);
-
- nds32->target->state = TARGET_RUNNING;
- nds32->target->debug_reason = DBG_REASON_NOTHALTED;
-
- target_set_examined(target);
-
- return ERROR_OK;
-}
-
-static int nds32_v2_translate_address(struct target *target, target_addr_t *address)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
- target_addr_t physical_address;
-
- /* Following conditions need to do address translation
- * 1. BUS mode
- * 2. CPU mode under maximum interrupt level */
- if ((memory->access_channel == NDS_MEMORY_ACC_BUS) ||
- ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- nds32_reach_max_interrupt_level(nds32))) {
- if (target->type->virt2phys(target, *address, &physical_address) == ERROR_OK)
- *address = physical_address;
- else
- return ERROR_FAIL;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v2_read_buffer(struct target *target, target_addr_t address,
- uint32_t size, uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- /* BUG: If access range crosses multiple pages, the translation will not correct
- * for second page or so. */
-
- nds32_v2_translate_address(target, &address);
-
- return nds32_read_buffer(target, address, size, buffer);
-}
-
-static int nds32_v2_write_buffer(struct target *target, target_addr_t address,
- uint32_t size, const uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- /* BUG: If access range crosses multiple pages, the translation will not correct
- * for second page or so. */
-
- nds32_v2_translate_address(target, &address);
-
- return nds32_write_buffer(target, address, size, buffer);
-}
-
-static int nds32_v2_read_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- /* BUG: If access range crosses multiple pages, the translation will not correct
- * for second page or so. */
-
- nds32_v2_translate_address(target, &address);
-
- return nds32_read_memory(target, address, size, count, buffer);
-}
-
-static int nds32_v2_write_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, const uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- /* BUG: If access range crosses multiple pages, the translation will not correct
- * for second page or so. */
-
- nds32_v2_translate_address(target, &address);
-
- return nds32_write_memory(target, address, size, count, buffer);
-}
-
-/** Holds methods for V2 targets. */
-struct target_type nds32_v2_target = {
- .name = "nds32_v2",
-
- .poll = nds32_poll,
- .arch_state = nds32_arch_state,
-
- .target_request_data = nds32_v2_target_request_data,
-
- .halt = nds32_halt,
- .resume = nds32_resume,
- .step = nds32_step,
-
- .assert_reset = nds32_assert_reset,
- .deassert_reset = nds32_v2_deassert_reset,
-
- /* register access */
- .get_gdb_reg_list = nds32_get_gdb_reg_list,
-
- /* memory access */
- .read_buffer = nds32_v2_read_buffer,
- .write_buffer = nds32_v2_write_buffer,
- .read_memory = nds32_v2_read_memory,
- .write_memory = nds32_v2_write_memory,
-
- .checksum_memory = nds32_v2_checksum_memory,
-
- /* breakpoint/watchpoint */
- .add_breakpoint = nds32_v2_add_breakpoint,
- .remove_breakpoint = nds32_v2_remove_breakpoint,
- .add_watchpoint = nds32_v2_add_watchpoint,
- .remove_watchpoint = nds32_v2_remove_watchpoint,
- .hit_watchpoint = nds32_v2_hit_watchpoint,
-
- /* MMU */
- .mmu = nds32_mmu,
- .virt2phys = nds32_virtual_to_physical,
- .read_phys_memory = nds32_read_phys_memory,
- .write_phys_memory = nds32_write_phys_memory,
-
- .run_algorithm = nds32_v2_run_algorithm,
-
- .commands = nds32_command_handlers,
- .target_create = nds32_v2_target_create,
- .init_target = nds32_v2_init_target,
- .examine = nds32_v2_examine,
-};
diff --git a/src/target/nds32_v2.h b/src/target/nds32_v2.h
deleted file mode 100644
index 3c30108..0000000
--- a/src/target/nds32_v2.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_V2_H
-#define OPENOCD_TARGET_NDS32_V2_H
-
-#include "nds32.h"
-
-struct nds32_v2_common {
- struct nds32 nds32;
-
- uint32_t backup_ir0;
-
- /** number of hardware breakpoints */
- int32_t n_hbr;
-
- /** next hardware breakpoint index */
- /** increase from low index to high index */
- int32_t next_hbr_index;
-};
-
-static inline struct nds32_v2_common *target_to_nds32_v2(struct target *target)
-{
- return container_of(target->arch_info, struct nds32_v2_common, nds32);
-}
-
-#endif /* OPENOCD_TARGET_NDS32_V2_H */
diff --git a/src/target/nds32_v3.c b/src/target/nds32_v3.c
deleted file mode 100644
index 9d02e5a..0000000
--- a/src/target/nds32_v3.c
+++ /dev/null
@@ -1,510 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "breakpoints.h"
-#include "nds32_cmd.h"
-#include "nds32_aice.h"
-#include "nds32_v3.h"
-#include "nds32_v3_common.h"
-
-static int nds32_v3_activate_hardware_breakpoint(struct target *target)
-{
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct breakpoint *bp;
- int32_t hbr_index = nds32_v3->next_hbr_index;
-
- for (bp = target->breakpoints; bp; bp = bp->next) {
- if (bp->type == BKPT_SOFT) {
- /* already set at nds32_v3_add_breakpoint() */
- continue;
- } else if (bp->type == BKPT_HARD) {
- hbr_index--;
- /* set address */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address);
- /* set mask */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0);
- /* set value */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0);
-
- if (nds32_v3->nds32.memory.address_translation)
- /* enable breakpoint (virtual address) */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2);
- else
- /* enable breakpoint (physical address) */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA);
-
- LOG_DEBUG("Add hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
- bp->address);
- } else {
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3_deactivate_hardware_breakpoint(struct target *target)
-{
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct breakpoint *bp;
- int32_t hbr_index = nds32_v3->next_hbr_index;
-
- for (bp = target->breakpoints; bp; bp = bp->next) {
- if (bp->type == BKPT_SOFT) {
- continue;
- } else if (bp->type == BKPT_HARD) {
- hbr_index--;
- /* disable breakpoint */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0);
- } else {
- return ERROR_FAIL;
- }
-
- LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
- bp->address);
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3_activate_hardware_watchpoint(struct target *target)
-{
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
- struct watchpoint *wp;
- int32_t wp_num = 0;
- uint32_t wp_config = 0;
- bool ld_stop, st_stop;
-
- if (nds32_v3->nds32.global_stop)
- ld_stop = st_stop = false;
-
- for (wp = target->watchpoints; wp; wp = wp->next) {
-
- if (wp_num < nds32_v3->used_n_wp) {
- wp->mask = wp->length - 1;
- if ((wp->address % wp->length) != 0)
- wp->mask = (wp->mask << 1) + 1;
-
- if (wp->rw == WPT_READ)
- wp_config = 0x3;
- else if (wp->rw == WPT_WRITE)
- wp_config = 0x5;
- else if (wp->rw == WPT_ACCESS)
- wp_config = 0x7;
-
- /* set/unset physical address bit of BPCn according to PSW.DT */
- if (nds32_v3->nds32.memory.address_translation == false)
- wp_config |= 0x8;
-
- /* set address */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num,
- wp->address - (wp->address % wp->length));
- /* set mask */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask);
- /* enable watchpoint */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config);
- /* set value */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0);
-
- LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32,
- wp_num, wp->address, wp->mask);
-
- wp_num++;
- } else if (nds32_v3->nds32.global_stop) {
- if (wp->rw == WPT_READ)
- ld_stop = true;
- else if (wp->rw == WPT_WRITE)
- st_stop = true;
- else if (wp->rw == WPT_ACCESS)
- ld_stop = st_stop = true;
- }
- }
-
- if (nds32_v3->nds32.global_stop) {
- uint32_t edm_ctl;
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl);
- if (ld_stop)
- edm_ctl |= 0x10;
- if (st_stop)
- edm_ctl |= 0x20;
- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl);
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3_deactivate_hardware_watchpoint(struct target *target)
-{
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
- int32_t wp_num = 0;
- struct watchpoint *wp;
- bool clean_global_stop = false;
-
- for (wp = target->watchpoints; wp; wp = wp->next) {
-
- if (wp_num < nds32_v3->used_n_wp) {
- /* disable watchpoint */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0);
-
- LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR
- " mask %08" PRIx32, wp_num,
- wp->address, wp->mask);
- wp_num++;
- } else if (nds32_v3->nds32.global_stop) {
- clean_global_stop = true;
- }
- }
-
- if (clean_global_stop) {
- uint32_t edm_ctl;
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl);
- edm_ctl = edm_ctl & (~0x30);
- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl);
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3_check_interrupt_stack(struct nds32 *nds32)
-{
- uint32_t val_ir0;
- uint32_t value;
-
- /* Save interrupt level */
- nds32_get_mapped_reg(nds32, IR0, &val_ir0);
- nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3;
-
- if (nds32_reach_max_interrupt_level(nds32))
- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->",
- nds32->current_interrupt_level);
-
- /* backup $ir4 & $ir6 to avoid suppressed exception overwrite */
- nds32_get_mapped_reg(nds32, IR4, &value);
- nds32_get_mapped_reg(nds32, IR6, &value);
-
- return ERROR_OK;
-}
-
-static int nds32_v3_restore_interrupt_stack(struct nds32 *nds32)
-{
- uint32_t value;
-
- /* get backup value from cache */
- /* then set back to make the register dirty */
- nds32_get_mapped_reg(nds32, IR0, &value);
- nds32_set_mapped_reg(nds32, IR0, value);
-
- nds32_get_mapped_reg(nds32, IR4, &value);
- nds32_set_mapped_reg(nds32, IR4, value);
-
- nds32_get_mapped_reg(nds32, IR6, &value);
- nds32_set_mapped_reg(nds32, IR6, value);
-
- return ERROR_OK;
-}
-
-static int nds32_v3_deassert_reset(struct target *target)
-{
- int retval;
- struct aice_port_s *aice = target_to_aice(target);
- bool switch_to_v3_stack = false;
- uint32_t value_edm_ctl;
-
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &value_edm_ctl);
- if (((value_edm_ctl >> 6) & 0x1) == 0) { /* reset to V2 EDM mode */
- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, value_edm_ctl | (0x1 << 6));
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &value_edm_ctl);
- if (((value_edm_ctl >> 6) & 0x1) == 1)
- switch_to_v3_stack = true;
- } else
- switch_to_v3_stack = false;
-
- CHECK_RETVAL(nds32_poll(target));
-
- if (target->state != TARGET_HALTED) {
- /* reset only */
- LOG_WARNING("%s: ran after reset and before halt ...",
- target_name(target));
- retval = target_halt(target);
- if (retval != ERROR_OK)
- return retval;
-
- } else {
- /* reset-halt */
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
- struct nds32 *nds32 = &(nds32_v3->nds32);
- uint32_t value;
- uint32_t interrupt_level;
-
- if (switch_to_v3_stack == true) {
- /* PSW.INTL-- */
- nds32_get_mapped_reg(nds32, IR0, &value);
- interrupt_level = (value >> 1) & 0x3;
- interrupt_level--;
- value &= ~(0x6);
- value |= (interrupt_level << 1);
- value |= 0x400; /* set PSW.DEX */
- nds32_set_mapped_reg(nds32, IR0, value);
-
- /* copy IPC to OIPC */
- if ((interrupt_level + 1) < nds32->max_interrupt_level) {
- nds32_get_mapped_reg(nds32, IR9, &value);
- nds32_set_mapped_reg(nds32, IR11, value);
- }
- }
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3_add_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
-{
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
- struct nds32 *nds32 = &(nds32_v3->nds32);
- int result;
-
- if (breakpoint->type == BKPT_HARD) {
- /* check hardware resource */
- if (nds32_v3->n_hbr <= nds32_v3->next_hbr_index) {
- LOG_WARNING("<-- TARGET WARNING! Insert too many "
- "hardware breakpoints/watchpoints! "
- "The limit of combined hardware "
- "breakpoints/watchpoints is %" PRId32 ". -->",
- nds32_v3->n_hbr);
- LOG_WARNING("<-- TARGET STATUS: Inserted number of "
- "hardware breakpoint: %" PRId32 ", hardware "
- "watchpoints: %" PRId32 ". -->",
- nds32_v3->next_hbr_index - nds32_v3->used_n_wp,
- nds32_v3->used_n_wp);
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
-
- /* update next place to put hardware breakpoint */
- nds32_v3->next_hbr_index++;
-
- /* hardware breakpoint insertion occurs before 'continue' actually */
- return ERROR_OK;
- } else if (breakpoint->type == BKPT_SOFT) {
- result = nds32_add_software_breakpoint(target, breakpoint);
- if (result != ERROR_OK) {
- /* auto convert to hardware breakpoint if failed */
- if (nds32->auto_convert_hw_bp) {
- /* convert to hardware breakpoint */
- breakpoint->type = BKPT_HARD;
-
- return nds32_v3_add_breakpoint(target, breakpoint);
- }
- }
-
- return result;
- } else /* unrecognized breakpoint type */
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int nds32_v3_remove_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
-{
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
-
- if (breakpoint->type == BKPT_HARD) {
- if (nds32_v3->next_hbr_index <= 0)
- return ERROR_FAIL;
-
- /* update next place to put hardware breakpoint */
- nds32_v3->next_hbr_index--;
-
- /* hardware breakpoint removal occurs after 'halted' actually */
- return ERROR_OK;
- } else if (breakpoint->type == BKPT_SOFT) {
- return nds32_remove_software_breakpoint(target, breakpoint);
- } else /* unrecognized breakpoint type */
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int nds32_v3_add_watchpoint(struct target *target,
- struct watchpoint *watchpoint)
-{
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
-
- /* check hardware resource */
- if (nds32_v3->n_hbr <= nds32_v3->next_hbr_index) {
- /* No hardware resource */
- if (nds32_v3->nds32.global_stop) {
- LOG_WARNING("<-- TARGET WARNING! The number of "
- "watchpoints exceeds the hardware "
- "resources. Stop at every load/store "
- "instruction to check for watchpoint matches. -->");
- return ERROR_OK;
- }
-
- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
- "breakpoints/watchpoints! The limit of combined "
- "hardware breakpoints/watchpoints is %" PRId32 ". -->",
- nds32_v3->n_hbr);
- LOG_WARNING("<-- TARGET STATUS: Inserted number of "
- "hardware breakpoint: %" PRId32 ", hardware "
- "watchpoints: %" PRId32 ". -->",
- nds32_v3->next_hbr_index - nds32_v3->used_n_wp,
- nds32_v3->used_n_wp);
-
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
-
- /* update next place to put hardware watchpoint */
- nds32_v3->next_hbr_index++;
- nds32_v3->used_n_wp++;
-
- return ERROR_OK;
-}
-
-static int nds32_v3_remove_watchpoint(struct target *target,
- struct watchpoint *watchpoint)
-{
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
-
- if (nds32_v3->next_hbr_index <= 0) {
- if (nds32_v3->nds32.global_stop)
- return ERROR_OK;
-
- return ERROR_FAIL;
- }
-
- /* update next place to put hardware breakpoint */
- nds32_v3->next_hbr_index--;
- nds32_v3->used_n_wp--;
-
- return ERROR_OK;
-}
-
-static struct nds32_v3_common_callback nds32_v3_common_callback = {
- .check_interrupt_stack = nds32_v3_check_interrupt_stack,
- .restore_interrupt_stack = nds32_v3_restore_interrupt_stack,
- .activate_hardware_breakpoint = nds32_v3_activate_hardware_breakpoint,
- .activate_hardware_watchpoint = nds32_v3_activate_hardware_watchpoint,
- .deactivate_hardware_breakpoint = nds32_v3_deactivate_hardware_breakpoint,
- .deactivate_hardware_watchpoint = nds32_v3_deactivate_hardware_watchpoint,
-};
-
-static int nds32_v3_target_create(struct target *target, Jim_Interp *interp)
-{
- struct nds32_v3_common *nds32_v3;
-
- nds32_v3 = calloc(1, sizeof(*nds32_v3));
- if (!nds32_v3)
- return ERROR_FAIL;
-
- nds32_v3_common_register_callback(&nds32_v3_common_callback);
- nds32_v3_target_create_common(target, &(nds32_v3->nds32));
-
- return ERROR_OK;
-}
-
-/* talk to the target and set things up */
-static int nds32_v3_examine(struct target *target)
-{
- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target);
- struct nds32 *nds32 = &(nds32_v3->nds32);
- struct aice_port_s *aice = target_to_aice(target);
-
- if (!target_was_examined(target)) {
- CHECK_RETVAL(nds32_edm_config(nds32));
-
- if (nds32->reset_halt_as_examine)
- CHECK_RETVAL(nds32_reset_halt(nds32));
- }
-
- uint32_t edm_cfg;
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
-
- /* get the number of hardware breakpoints */
- nds32_v3->n_hbr = (edm_cfg & 0x7) + 1;
-
- /* low interference profiling */
- if (edm_cfg & 0x100)
- nds32_v3->low_interference_profile = true;
- else
- nds32_v3->low_interference_profile = false;
-
- nds32_v3->next_hbr_index = 0;
- nds32_v3->used_n_wp = 0;
-
- LOG_INFO("%s: total hardware breakpoint %" PRId32, target_name(target),
- nds32_v3->n_hbr);
-
- nds32->target->state = TARGET_RUNNING;
- nds32->target->debug_reason = DBG_REASON_NOTHALTED;
-
- target_set_examined(target);
-
- return ERROR_OK;
-}
-
-/** Holds methods for Andes1337 targets. */
-struct target_type nds32_v3_target = {
- .name = "nds32_v3",
-
- .poll = nds32_poll,
- .arch_state = nds32_arch_state,
-
- .target_request_data = nds32_v3_target_request_data,
-
- .halt = nds32_halt,
- .resume = nds32_resume,
- .step = nds32_step,
-
- .assert_reset = nds32_assert_reset,
- .deassert_reset = nds32_v3_deassert_reset,
-
- /* register access */
- .get_gdb_reg_list = nds32_get_gdb_reg_list,
-
- /* memory access */
- .read_buffer = nds32_v3_read_buffer,
- .write_buffer = nds32_v3_write_buffer,
- .read_memory = nds32_v3_read_memory,
- .write_memory = nds32_v3_write_memory,
-
- .checksum_memory = nds32_v3_checksum_memory,
-
- /* breakpoint/watchpoint */
- .add_breakpoint = nds32_v3_add_breakpoint,
- .remove_breakpoint = nds32_v3_remove_breakpoint,
- .add_watchpoint = nds32_v3_add_watchpoint,
- .remove_watchpoint = nds32_v3_remove_watchpoint,
- .hit_watchpoint = nds32_v3_hit_watchpoint,
-
- /* MMU */
- .mmu = nds32_mmu,
- .virt2phys = nds32_virtual_to_physical,
- .read_phys_memory = nds32_read_phys_memory,
- .write_phys_memory = nds32_write_phys_memory,
-
- .run_algorithm = nds32_v3_run_algorithm,
-
- .commands = nds32_command_handlers,
- .target_create = nds32_v3_target_create,
- .init_target = nds32_v3_init_target,
- .examine = nds32_v3_examine,
-
- .get_gdb_fileio_info = nds32_get_gdb_fileio_info,
- .gdb_fileio_end = nds32_gdb_fileio_end,
-
- .profiling = nds32_profiling,
-};
diff --git a/src/target/nds32_v3.h b/src/target/nds32_v3.h
deleted file mode 100644
index 389838d..0000000
--- a/src/target/nds32_v3.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_V3_H
-#define OPENOCD_TARGET_NDS32_V3_H
-
-#include "nds32.h"
-
-struct nds32_v3_common {
- struct nds32 nds32;
-
- /** number of hardware breakpoints */
- int32_t n_hbr;
-
- /** number of used hardware watchpoints */
- int32_t used_n_wp;
-
- /** next hardware breakpoint index */
- int32_t next_hbr_index;
-
- /** low interference profiling */
- bool low_interference_profile;
-};
-
-static inline struct nds32_v3_common *target_to_nds32_v3(struct target *target)
-{
- return container_of(target->arch_info, struct nds32_v3_common, nds32);
-}
-
-#endif /* OPENOCD_TARGET_NDS32_V3_H */
diff --git a/src/target/nds32_v3_common.c b/src/target/nds32_v3_common.c
deleted file mode 100644
index f2efab4..0000000
--- a/src/target/nds32_v3_common.c
+++ /dev/null
@@ -1,664 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "breakpoints.h"
-#include "nds32_reg.h"
-#include "nds32_disassembler.h"
-#include "nds32.h"
-#include "nds32_aice.h"
-#include "nds32_v3_common.h"
-
-static struct nds32_v3_common_callback *v3_common_callback;
-
-static int nds32_v3_register_mapping(struct nds32 *nds32, int reg_no)
-{
- if (reg_no == PC)
- return IR11;
-
- return reg_no;
-}
-
-static int nds32_v3_get_debug_reason(struct nds32 *nds32, uint32_t *reason)
-{
- uint32_t edmsw;
- struct aice_port_s *aice = target_to_aice(nds32->target);
- aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw);
-
- *reason = (edmsw >> 12) & 0x0F;
-
- return ERROR_OK;
-}
-
-/**
- * Save processor state. This is called after a HALT instruction
- * succeeds, and on other occasions the processor enters debug mode
- * (breakpoint, watchpoint, etc).
- */
-static int nds32_v3_debug_entry(struct nds32 *nds32, bool enable_watchpoint)
-{
- LOG_DEBUG("nds32_v3_debug_entry");
-
- enum target_state backup_state = nds32->target->state;
- nds32->target->state = TARGET_HALTED;
-
- if (nds32->init_arch_info_after_halted == false) {
- /* init architecture info according to config registers */
- CHECK_RETVAL(nds32_config(nds32));
-
- nds32->init_arch_info_after_halted = true;
- }
-
- /* REVISIT entire cache should already be invalid !!! */
- register_cache_invalidate(nds32->core_cache);
-
- /* deactivate all hardware breakpoints */
- CHECK_RETVAL(v3_common_callback->deactivate_hardware_breakpoint(nds32->target));
-
- if (enable_watchpoint)
- CHECK_RETVAL(v3_common_callback->deactivate_hardware_watchpoint(nds32->target));
-
- struct breakpoint *syscall_break = &(nds32->syscall_break);
- if (nds32->virtual_hosting) {
- if (syscall_break->is_set) {
- /** disable virtual hosting */
-
- /* remove breakpoint at syscall entry */
- target_remove_breakpoint(nds32->target, syscall_break);
- syscall_break->is_set = false;
-
- uint32_t value_pc;
- nds32_get_mapped_reg(nds32, PC, &value_pc);
- if (value_pc == syscall_break->address)
- /** process syscall for virtual hosting */
- nds32->hit_syscall = true;
- }
- }
-
- if (nds32_examine_debug_reason(nds32) != ERROR_OK) {
- nds32->target->state = backup_state;
-
- /* re-activate all hardware breakpoints & watchpoints */
- CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(nds32->target));
-
- if (enable_watchpoint)
- CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(nds32->target));
-
- return ERROR_FAIL;
- }
-
- /* Save registers. */
- nds32_full_context(nds32);
-
- /* check interrupt level */
- v3_common_callback->check_interrupt_stack(nds32);
-
- return ERROR_OK;
-}
-
-/**
- * Restore processor state.
- */
-static int nds32_v3_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint)
-{
- LOG_DEBUG("nds32_v3_leave_debug_state");
-
- struct target *target = nds32->target;
-
- /* activate all hardware breakpoints */
- CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(target));
-
- if (enable_watchpoint) {
- /* activate all watchpoints */
- CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(target));
- }
-
- /* restore interrupt stack */
- v3_common_callback->restore_interrupt_stack(nds32);
-
- /* REVISIT once we start caring about MMU and cache state,
- * address it here ...
- */
-
- /* restore PSW, PC, and R0 ... after flushing any modified
- * registers.
- */
- CHECK_RETVAL(nds32_restore_context(target));
-
- if (nds32->virtual_hosting) {
- /** enable virtual hosting */
- uint32_t value_ir3;
- uint32_t entry_size;
- uint32_t syscall_address;
-
- /* get syscall entry address */
- nds32_get_mapped_reg(nds32, IR3, &value_ir3);
- entry_size = 0x4 << (((value_ir3 >> 14) & 0x3) << 1);
- syscall_address = (value_ir3 & 0xFFFF0000) + entry_size * 8; /* The index of SYSCALL is 8 */
-
- if (nds32->hit_syscall) {
- /* single step to skip syscall entry */
- /* use IRET to skip syscall */
- struct aice_port_s *aice = target_to_aice(target);
- uint32_t value_ir9;
- uint32_t value_ir6;
- uint32_t syscall_id;
-
- nds32_get_mapped_reg(nds32, IR6, &value_ir6);
- syscall_id = (value_ir6 >> 16) & 0x7FFF;
-
- if (syscall_id == NDS32_SYSCALL_EXIT) {
- /* If target hits exit syscall, do not use IRET to skip handler. */
- aice_step(aice);
- } else {
- /* use api->read/write_reg to skip nds32 register cache */
- uint32_t value_dimbr;
- aice_read_debug_reg(aice, NDS_EDM_SR_DIMBR, &value_dimbr);
- aice_write_register(aice, IR11, value_dimbr + 0xC);
-
- aice_read_register(aice, IR9, &value_ir9);
- value_ir9 += 4; /* syscall is always 4 bytes */
- aice_write_register(aice, IR9, value_ir9);
-
- /* backup hardware breakpoint 0 */
- uint32_t backup_bpa, backup_bpam, backup_bpc;
- aice_read_debug_reg(aice, NDS_EDM_SR_BPA0, &backup_bpa);
- aice_read_debug_reg(aice, NDS_EDM_SR_BPAM0, &backup_bpam);
- aice_read_debug_reg(aice, NDS_EDM_SR_BPC0, &backup_bpc);
-
- /* use hardware breakpoint 0 to stop cpu after skipping syscall */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, value_ir9);
- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, 0);
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, 0xA);
-
- /* Execute two IRET.
- * First IRET is used to quit debug mode.
- * Second IRET is used to quit current syscall. */
- uint32_t dim_inst[4] = {NOP, NOP, IRET, IRET};
- aice_execute(aice, dim_inst, 4);
-
- /* restore origin hardware breakpoint 0 */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, backup_bpa);
- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, backup_bpam);
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, backup_bpc);
- }
-
- nds32->hit_syscall = false;
- }
-
- /* insert breakpoint at syscall entry */
- struct breakpoint *syscall_break = &(nds32->syscall_break);
-
- syscall_break->address = syscall_address;
- syscall_break->type = BKPT_SOFT;
- syscall_break->is_set = true;
- target_add_breakpoint(target, syscall_break);
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3_get_exception_address(struct nds32 *nds32,
- uint32_t *address, uint32_t reason)
-{
- LOG_DEBUG("nds32_v3_get_exception_address");
-
- struct aice_port_s *aice = target_to_aice(nds32->target);
- struct target *target = nds32->target;
- uint32_t edmsw;
- uint32_t edm_cfg;
- uint32_t match_bits;
- uint32_t match_count;
- int32_t i;
- static int32_t number_of_hard_break;
- uint32_t bp_control;
-
- if (number_of_hard_break == 0) {
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
- number_of_hard_break = (edm_cfg & 0x7) + 1;
- }
-
- aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw);
- /* clear matching bits (write-one-clear) */
- aice_write_debug_reg(aice, NDS_EDM_SR_EDMSW, edmsw);
- match_bits = (edmsw >> 4) & 0xFF;
- match_count = 0;
- for (i = 0 ; i < number_of_hard_break ; i++) {
- if (match_bits & (1 << i)) {
- aice_read_debug_reg(aice, NDS_EDM_SR_BPA0 + i, address);
- match_count++;
-
- /* If target hits multiple read/access watchpoint,
- * select the first one. */
- aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &bp_control);
- if (0x3 == (bp_control & 0x3)) {
- match_count = 1;
- break;
- }
- }
- }
-
- if (match_count > 1) { /* multiple hits */
- *address = 0;
- return ERROR_OK;
- } else if (match_count == 1) {
- uint32_t val_pc;
- uint32_t opcode;
- struct nds32_instruction instruction;
- struct watchpoint *wp;
- bool hit;
-
- nds32_get_mapped_reg(nds32, PC, &val_pc);
-
- if ((reason == NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE) ||
- (reason == NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE)) {
- if (edmsw & 0x4) /* check EDMSW.IS_16BIT */
- val_pc -= 2;
- else
- val_pc -= 4;
- }
-
- nds32_read_opcode(nds32, val_pc, &opcode);
- nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction);
-
- LOG_DEBUG("PC: 0x%08" PRIx32 ", access start: 0x%08" PRIx32 ", end: 0x%08" PRIx32,
- val_pc, instruction.access_start, instruction.access_end);
-
- /* check if multiple hits in the access range */
- uint32_t in_range_watch_count = 0;
- for (wp = target->watchpoints; wp; wp = wp->next) {
- if ((instruction.access_start <= wp->address) &&
- (wp->address < instruction.access_end))
- in_range_watch_count++;
- }
- if (in_range_watch_count > 1) {
- /* Hit LSMW instruction. */
- *address = 0;
- return ERROR_OK;
- }
-
- /* dispel false match */
- hit = false;
- for (wp = target->watchpoints; wp; wp = wp->next) {
- if (((*address ^ wp->address) & (~wp->mask)) == 0) {
- uint32_t watch_start;
- uint32_t watch_end;
-
- watch_start = wp->address;
- watch_end = wp->address + wp->length;
-
- if ((watch_end <= instruction.access_start) ||
- (instruction.access_end <= watch_start))
- continue;
-
- hit = true;
- break;
- }
- }
-
- if (hit)
- return ERROR_OK;
- else
- return ERROR_FAIL;
- } else if (match_count == 0) {
- /* global stop is precise exception */
- if ((reason == NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP) && nds32->global_stop) {
- /* parse instruction to get correct access address */
- uint32_t val_pc;
- uint32_t opcode;
- struct nds32_instruction instruction;
-
- nds32_get_mapped_reg(nds32, PC, &val_pc);
- nds32_read_opcode(nds32, val_pc, &opcode);
- nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction);
-
- *address = instruction.access_start;
-
- return ERROR_OK;
- }
- }
-
- *address = 0xFFFFFFFF;
- return ERROR_FAIL;
-}
-
-void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback)
-{
- v3_common_callback = callback;
-}
-
-/** target_type functions: */
-/* target request support */
-int nds32_v3_target_request_data(struct target *target,
- uint32_t size, uint8_t *buffer)
-{
- /* AndesCore could use DTR register to communicate with OpenOCD
- * to output messages
- * Target data will be put in buffer
- * The format of DTR is as follow
- * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
- * target_req_cmd has three possible values:
- * TARGET_REQ_TRACEMSG
- * TARGET_REQ_DEBUGMSG
- * TARGET_REQ_DEBUGCHAR
- * if size == 0, target will call target_asciimsg(),
- * else call target_hexmsg()
- */
- LOG_WARNING("Not implemented: %s", __func__);
-
- return ERROR_OK;
-}
-
-int nds32_v3_checksum_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *checksum)
-{
- LOG_WARNING("Not implemented: %s", __func__);
-
- return ERROR_FAIL;
-}
-
-/**
- * find out which watchpoint hits
- * get exception address and compare the address to watchpoints
- */
-int nds32_v3_hit_watchpoint(struct target *target,
- struct watchpoint **hit_watchpoint)
-{
- static struct watchpoint scan_all_watchpoint;
-
- uint32_t exception_address;
- struct watchpoint *wp;
- struct nds32 *nds32 = target_to_nds32(target);
-
- exception_address = nds32->watched_address;
-
- if (exception_address == 0xFFFFFFFF)
- return ERROR_FAIL;
-
- if (exception_address == 0) {
- scan_all_watchpoint.address = 0;
- scan_all_watchpoint.rw = WPT_WRITE;
- scan_all_watchpoint.next = 0;
- scan_all_watchpoint.unique_id = 0x5CA8;
-
- *hit_watchpoint = &scan_all_watchpoint;
- return ERROR_OK;
- }
-
- for (wp = target->watchpoints; wp; wp = wp->next) {
- if (((exception_address ^ wp->address) & (~wp->mask)) == 0) {
- *hit_watchpoint = wp;
-
- return ERROR_OK;
- }
- }
-
- return ERROR_FAIL;
-}
-
-int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32)
-{
- nds32->register_map = nds32_v3_register_mapping;
- nds32->get_debug_reason = nds32_v3_get_debug_reason;
- nds32->enter_debug_state = nds32_v3_debug_entry;
- nds32->leave_debug_state = nds32_v3_leave_debug_state;
- nds32->get_watched_address = nds32_v3_get_exception_address;
-
- /* Init target->arch_info in nds32_init_arch_info().
- * After this, user could use target_to_nds32() to get nds32 object */
- nds32_init_arch_info(target, nds32);
-
- return ERROR_OK;
-}
-
-int nds32_v3_run_algorithm(struct target *target,
- int num_mem_params,
- struct mem_param *mem_params,
- int num_reg_params,
- struct reg_param *reg_params,
- target_addr_t entry_point,
- target_addr_t exit_point,
- int timeout_ms,
- void *arch_info)
-{
- LOG_WARNING("Not implemented: %s", __func__);
-
- return ERROR_FAIL;
-}
-
-int nds32_v3_read_buffer(struct target *target, target_addr_t address,
- uint32_t size, uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- target_addr_t physical_address;
- /* BUG: If access range crosses multiple pages, the translation will not correct
- * for second page or so. */
-
- /* When DEX is set to one, hardware will enforce the following behavior without
- * modifying the corresponding control bits in PSW.
- *
- * Disable all interrupts
- * Become superuser mode
- * Turn off IT/DT
- * Use MMU_CFG.DE as the data access endian
- * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
- * Disable audio special features
- * Disable inline function call
- *
- * Because hardware will turn off IT/DT by default, it MUST translate virtual address
- * to physical address.
- */
- if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK)
- address = physical_address;
- else
- return ERROR_FAIL;
-
- int result;
- struct aice_port_s *aice = target_to_aice(target);
- /* give arbitrary initial value to avoid warning messages */
- enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU;
-
- if (nds32->hit_syscall) {
- /* Use bus mode to access memory during virtual hosting */
- origin_access_channel = memory->access_channel;
- memory->access_channel = NDS_MEMORY_ACC_BUS;
- aice_memory_access(aice, NDS_MEMORY_ACC_BUS);
- }
-
- result = nds32_read_buffer(target, address, size, buffer);
-
- if (nds32->hit_syscall) {
- /* Restore access_channel after virtual hosting */
- memory->access_channel = origin_access_channel;
- aice_memory_access(aice, origin_access_channel);
- }
-
- return result;
-}
-
-int nds32_v3_write_buffer(struct target *target, target_addr_t address,
- uint32_t size, const uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- target_addr_t physical_address;
- /* BUG: If access range crosses multiple pages, the translation will not correct
- * for second page or so. */
-
- /* When DEX is set to one, hardware will enforce the following behavior without
- * modifying the corresponding control bits in PSW.
- *
- * Disable all interrupts
- * Become superuser mode
- * Turn off IT/DT
- * Use MMU_CFG.DE as the data access endian
- * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
- * Disable audio special features
- * Disable inline function call
- *
- * Because hardware will turn off IT/DT by default, it MUST translate virtual address
- * to physical address.
- */
- if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK)
- address = physical_address;
- else
- return ERROR_FAIL;
-
- if (nds32->hit_syscall) {
- struct aice_port_s *aice = target_to_aice(target);
- enum nds_memory_access origin_access_channel;
- origin_access_channel = memory->access_channel;
-
- /* If target has no cache, use BUS mode to access memory. */
- if ((memory->dcache.line_size == 0)
- || (memory->dcache.enable == false)) {
- /* There is no Dcache or Dcache is disabled. */
- memory->access_channel = NDS_MEMORY_ACC_BUS;
- aice_memory_access(aice, NDS_MEMORY_ACC_BUS);
- }
-
- int result;
- result = nds32_gdb_fileio_write_memory(nds32, address, size, buffer);
-
- if (origin_access_channel == NDS_MEMORY_ACC_CPU) {
- memory->access_channel = NDS_MEMORY_ACC_CPU;
- aice_memory_access(aice, NDS_MEMORY_ACC_CPU);
- }
-
- return result;
- }
-
- return nds32_write_buffer(target, address, size, buffer);
-}
-
-int nds32_v3_read_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- target_addr_t physical_address;
- /* BUG: If access range crosses multiple pages, the translation will not correct
- * for second page or so. */
-
- /* When DEX is set to one, hardware will enforce the following behavior without
- * modifying the corresponding control bits in PSW.
- *
- * Disable all interrupts
- * Become superuser mode
- * Turn off IT/DT
- * Use MMU_CFG.DE as the data access endian
- * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
- * Disable audio special features
- * Disable inline function call
- *
- * Because hardware will turn off IT/DT by default, it MUST translate virtual address
- * to physical address.
- */
- if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK)
- address = physical_address;
- else
- return ERROR_FAIL;
-
- struct aice_port_s *aice = target_to_aice(target);
- /* give arbitrary initial value to avoid warning messages */
- enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU;
- int result;
-
- if (nds32->hit_syscall) {
- /* Use bus mode to access memory during virtual hosting */
- origin_access_channel = memory->access_channel;
- memory->access_channel = NDS_MEMORY_ACC_BUS;
- aice_memory_access(aice, NDS_MEMORY_ACC_BUS);
- }
-
- result = nds32_read_memory(target, address, size, count, buffer);
-
- if (nds32->hit_syscall) {
- /* Restore access_channel after virtual hosting */
- memory->access_channel = origin_access_channel;
- aice_memory_access(aice, origin_access_channel);
- }
-
- return result;
-}
-
-int nds32_v3_write_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, const uint8_t *buffer)
-{
- struct nds32 *nds32 = target_to_nds32(target);
- struct nds32_memory *memory = &(nds32->memory);
-
- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) &&
- (target->state != TARGET_HALTED)) {
- LOG_WARNING("target was not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- target_addr_t physical_address;
- /* BUG: If access range crosses multiple pages, the translation will not correct
- * for second page or so. */
-
- /* When DEX is set to one, hardware will enforce the following behavior without
- * modifying the corresponding control bits in PSW.
- *
- * Disable all interrupts
- * Become superuser mode
- * Turn off IT/DT
- * Use MMU_CFG.DE as the data access endian
- * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
- * Disable audio special features
- * Disable inline function call
- *
- * Because hardware will turn off IT/DT by default, it MUST translate virtual address
- * to physical address.
- */
- if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK)
- address = physical_address;
- else
- return ERROR_FAIL;
-
- return nds32_write_memory(target, address, size, count, buffer);
-}
-
-int nds32_v3_init_target(struct command_context *cmd_ctx,
- struct target *target)
-{
- /* Initialize anything we can set up without talking to the target */
- struct nds32 *nds32 = target_to_nds32(target);
-
- nds32_init(nds32);
-
- target->fileio_info = malloc(sizeof(struct gdb_fileio_info));
- target->fileio_info->identifier = NULL;
-
- return ERROR_OK;
-}
diff --git a/src/target/nds32_v3_common.h b/src/target/nds32_v3_common.h
deleted file mode 100644
index a98988e..0000000
--- a/src/target/nds32_v3_common.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_V3_COMMON_H
-#define OPENOCD_TARGET_NDS32_V3_COMMON_H
-
-#include "target.h"
-
-struct nds32_v3_common_callback {
- int (*check_interrupt_stack)(struct nds32 *nds32);
- int (*restore_interrupt_stack)(struct nds32 *nds32);
- int (*activate_hardware_breakpoint)(struct target *target);
- int (*activate_hardware_watchpoint)(struct target *target);
- int (*deactivate_hardware_breakpoint)(struct target *target);
- int (*deactivate_hardware_watchpoint)(struct target *target);
-};
-
-void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback);
-int nds32_v3_target_request_data(struct target *target,
- uint32_t size, uint8_t *buffer);
-int nds32_v3_checksum_memory(struct target *target,
- target_addr_t address, uint32_t count, uint32_t *checksum);
-int nds32_v3_hit_watchpoint(struct target *target,
- struct watchpoint **hit_watchpoint);
-int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32);
-int nds32_v3_run_algorithm(struct target *target,
- int num_mem_params,
- struct mem_param *mem_params,
- int num_reg_params,
- struct reg_param *reg_params,
- target_addr_t entry_point,
- target_addr_t exit_point,
- int timeout_ms,
- void *arch_info);
-int nds32_v3_read_buffer(struct target *target, target_addr_t address,
- uint32_t size, uint8_t *buffer);
-int nds32_v3_write_buffer(struct target *target, target_addr_t address,
- uint32_t size, const uint8_t *buffer);
-int nds32_v3_read_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, uint8_t *buffer);
-int nds32_v3_write_memory(struct target *target, target_addr_t address,
- uint32_t size, uint32_t count, const uint8_t *buffer);
-int nds32_v3_init_target(struct command_context *cmd_ctx,
- struct target *target);
-
-#endif /* OPENOCD_TARGET_NDS32_V3_COMMON_H */
diff --git a/src/target/nds32_v3m.c b/src/target/nds32_v3m.c
deleted file mode 100644
index 6bc549f..0000000
--- a/src/target/nds32_v3m.c
+++ /dev/null
@@ -1,495 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "breakpoints.h"
-#include "nds32_cmd.h"
-#include "nds32_aice.h"
-#include "nds32_v3m.h"
-#include "nds32_v3_common.h"
-
-static int nds32_v3m_activate_hardware_breakpoint(struct target *target)
-{
- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct breakpoint *bp;
- unsigned brp_num = nds32_v3m->n_hbr - 1;
-
- for (bp = target->breakpoints; bp; bp = bp->next) {
- if (bp->type == BKPT_SOFT) {
- /* already set at nds32_v3m_add_breakpoint() */
- continue;
- } else if (bp->type == BKPT_HARD) {
- /* set address */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + brp_num, bp->address);
- /* set mask */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + brp_num, 0);
-
- if (nds32_v3m->nds32.memory.address_translation)
- /* enable breakpoint (virtual address) */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0x2);
- else
- /* enable breakpoint (physical address) */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0xA);
-
- LOG_DEBUG("Add hardware BP %u at %08" TARGET_PRIxADDR, brp_num,
- bp->address);
-
- brp_num--;
- } else {
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_deactivate_hardware_breakpoint(struct target *target)
-{
- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct breakpoint *bp;
- unsigned brp_num = nds32_v3m->n_hbr - 1;
-
- for (bp = target->breakpoints; bp; bp = bp->next) {
- if (bp->type == BKPT_SOFT)
- continue;
- else if (bp->type == BKPT_HARD)
- /* disable breakpoint */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0x0);
- else
- return ERROR_FAIL;
-
- LOG_DEBUG("Remove hardware BP %u at %08" TARGET_PRIxADDR, brp_num,
- bp->address);
-
- brp_num--;
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_activate_hardware_watchpoint(struct target *target)
-{
- struct aice_port_s *aice = target_to_aice(target);
- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target);
- struct watchpoint *wp;
- int32_t wp_num = 0;
- uint32_t wp_config = 0;
- bool ld_stop, st_stop;
-
- if (nds32_v3m->nds32.global_stop)
- ld_stop = st_stop = false;
-
- for (wp = target->watchpoints; wp; wp = wp->next) {
-
- if (wp_num < nds32_v3m->used_n_wp) {
- wp->mask = wp->length - 1;
- if ((wp->address % wp->length) != 0)
- wp->mask = (wp->mask << 1) + 1;
-
- if (wp->rw == WPT_READ)
- wp_config = 0x3;
- else if (wp->rw == WPT_WRITE)
- wp_config = 0x5;
- else if (wp->rw == WPT_ACCESS)
- wp_config = 0x7;
-
- /* set/unset physical address bit of BPCn according to PSW.DT */
- if (nds32_v3m->nds32.memory.address_translation == false)
- wp_config |= 0x8;
-
- /* set address */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num,
- wp->address - (wp->address % wp->length));
- /* set mask */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask);
- /* enable watchpoint */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config);
-
- LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR
- " mask %08" PRIx32, wp_num, wp->address, wp->mask);
-
- wp_num++;
- } else if (nds32_v3m->nds32.global_stop) {
- if (wp->rw == WPT_READ)
- ld_stop = true;
- else if (wp->rw == WPT_WRITE)
- st_stop = true;
- else if (wp->rw == WPT_ACCESS)
- ld_stop = st_stop = true;
- }
- }
-
- if (nds32_v3m->nds32.global_stop) {
- uint32_t edm_ctl;
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl);
- if (ld_stop)
- edm_ctl |= 0x10;
- if (st_stop)
- edm_ctl |= 0x20;
- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl);
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_deactivate_hardware_watchpoint(struct target *target)
-{
- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target);
- struct aice_port_s *aice = target_to_aice(target);
- struct watchpoint *wp;
- int32_t wp_num = 0;
- bool clean_global_stop = false;
-
- for (wp = target->watchpoints; wp; wp = wp->next) {
-
- if (wp_num < nds32_v3m->used_n_wp) {
- /* disable watchpoint */
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0);
-
- LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR
- " mask %08" PRIx32, wp_num, wp->address, wp->mask);
- wp_num++;
- } else if (nds32_v3m->nds32.global_stop) {
- clean_global_stop = true;
- }
- }
-
- if (clean_global_stop) {
- uint32_t edm_ctl;
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl);
- edm_ctl = edm_ctl & (~0x30);
- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl);
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_check_interrupt_stack(struct nds32 *nds32)
-{
- uint32_t val_ir0;
- uint32_t value;
-
- /* Save interrupt level */
- nds32_get_mapped_reg(nds32, IR0, &val_ir0);
- nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3;
-
- if (nds32_reach_max_interrupt_level(nds32))
- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->",
- nds32->current_interrupt_level);
-
- /* backup $ir6 to avoid suppressed exception overwrite */
- nds32_get_mapped_reg(nds32, IR6, &value);
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_restore_interrupt_stack(struct nds32 *nds32)
-{
- uint32_t value;
-
- /* get backup value from cache */
- /* then set back to make the register dirty */
- nds32_get_mapped_reg(nds32, IR0, &value);
- nds32_set_mapped_reg(nds32, IR0, value);
-
- nds32_get_mapped_reg(nds32, IR6, &value);
- nds32_set_mapped_reg(nds32, IR6, value);
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_deassert_reset(struct target *target)
-{
- int retval;
-
- CHECK_RETVAL(nds32_poll(target));
-
- if (target->state != TARGET_HALTED) {
- /* reset only */
- LOG_WARNING("%s: ran after reset and before halt ...",
- target_name(target));
- retval = target_halt(target);
- if (retval != ERROR_OK)
- return retval;
-
- }
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_add_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
-{
- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target);
- struct nds32 *nds32 = &(nds32_v3m->nds32);
- int result;
-
- if (breakpoint->type == BKPT_HARD) {
- /* check hardware resource */
- if (nds32_v3m->next_hbr_index < nds32_v3m->next_hwp_index) {
- LOG_WARNING("<-- TARGET WARNING! Insert too many "
- "hardware breakpoints/watchpoints! "
- "The limit of combined hardware "
- "breakpoints/watchpoints is %" PRId32 ". -->",
- nds32_v3m->n_hbr);
- LOG_WARNING("<-- TARGET STATUS: Inserted number of "
- "hardware breakpoint: %" PRId32 ", hardware "
- "watchpoints: %" PRId32 ". -->",
- nds32_v3m->n_hbr - nds32_v3m->next_hbr_index - 1,
- nds32_v3m->used_n_wp);
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
-
- /* update next place to put hardware breakpoint */
- nds32_v3m->next_hbr_index--;
-
- /* hardware breakpoint insertion occurs before 'continue' actually */
- return ERROR_OK;
- } else if (breakpoint->type == BKPT_SOFT) {
- result = nds32_add_software_breakpoint(target, breakpoint);
- if (result != ERROR_OK) {
- /* auto convert to hardware breakpoint if failed */
- if (nds32->auto_convert_hw_bp) {
- /* convert to hardware breakpoint */
- breakpoint->type = BKPT_HARD;
-
- return nds32_v3m_add_breakpoint(target, breakpoint);
- }
- }
-
- return result;
- } else /* unrecognized breakpoint type */
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_remove_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
-{
- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target);
-
- if (breakpoint->type == BKPT_HARD) {
- if (nds32_v3m->next_hbr_index >= nds32_v3m->n_hbr - 1)
- return ERROR_FAIL;
-
- /* update next place to put hardware breakpoint */
- nds32_v3m->next_hbr_index++;
-
- /* hardware breakpoint removal occurs after 'halted' actually */
- return ERROR_OK;
- } else if (breakpoint->type == BKPT_SOFT) {
- return nds32_remove_software_breakpoint(target, breakpoint);
- } else /* unrecognized breakpoint type */
- return ERROR_FAIL;
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_add_watchpoint(struct target *target,
- struct watchpoint *watchpoint)
-{
- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target);
-
- /* check hardware resource */
- if (nds32_v3m->next_hwp_index >= nds32_v3m->n_hwp) {
- /* No hardware resource */
- if (nds32_v3m->nds32.global_stop) {
- LOG_WARNING("<-- TARGET WARNING! The number of "
- "watchpoints exceeds the hardware "
- "resources. Stop at every load/store "
- "instruction to check for watchpoint matches. -->");
- return ERROR_OK;
- }
-
- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
- "watchpoints! The limit of hardware watchpoints "
- "is %" PRId32 ". -->", nds32_v3m->n_hwp);
- LOG_WARNING("<-- TARGET STATUS: Inserted number of "
- "hardware watchpoint: %" PRId32 ". -->",
- nds32_v3m->used_n_wp);
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
-
- if (nds32_v3m->next_hwp_index > nds32_v3m->next_hbr_index) {
- /* No hardware resource */
- if (nds32_v3m->nds32.global_stop) {
- LOG_WARNING("<-- TARGET WARNING! The number of "
- "watchpoints exceeds the hardware "
- "resources. Stop at every load/store "
- "instruction to check for watchpoint matches. -->");
- return ERROR_OK;
- }
-
- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
- "breakpoints/watchpoints! The limit of combined "
- "hardware breakpoints/watchpoints is %" PRId32 ". -->",
- nds32_v3m->n_hbr);
- LOG_WARNING("<-- TARGET STATUS: Inserted number of "
- "hardware breakpoint: %" PRId32 ", hardware "
- "watchpoints: %" PRId32 ". -->",
- nds32_v3m->n_hbr - nds32_v3m->next_hbr_index - 1,
- nds32_v3m->used_n_wp);
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
-
- /* update next place to put hardware watchpoint */
- nds32_v3m->next_hwp_index++;
- nds32_v3m->used_n_wp++;
-
- return ERROR_OK;
-}
-
-static int nds32_v3m_remove_watchpoint(struct target *target,
- struct watchpoint *watchpoint)
-{
- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target);
-
- if (nds32_v3m->next_hwp_index <= 0) {
- if (nds32_v3m->nds32.global_stop)
- return ERROR_OK;
-
- return ERROR_FAIL;
- }
-
- /* update next place to put hardware watchpoint */
- nds32_v3m->next_hwp_index--;
- nds32_v3m->used_n_wp--;
-
- return ERROR_OK;
-}
-
-static struct nds32_v3_common_callback nds32_v3m_common_callback = {
- .check_interrupt_stack = nds32_v3m_check_interrupt_stack,
- .restore_interrupt_stack = nds32_v3m_restore_interrupt_stack,
- .activate_hardware_breakpoint = nds32_v3m_activate_hardware_breakpoint,
- .activate_hardware_watchpoint = nds32_v3m_activate_hardware_watchpoint,
- .deactivate_hardware_breakpoint = nds32_v3m_deactivate_hardware_breakpoint,
- .deactivate_hardware_watchpoint = nds32_v3m_deactivate_hardware_watchpoint,
-};
-
-static int nds32_v3m_target_create(struct target *target, Jim_Interp *interp)
-{
- struct nds32_v3m_common *nds32_v3m;
-
- nds32_v3m = calloc(1, sizeof(*nds32_v3m));
- if (!nds32_v3m)
- return ERROR_FAIL;
-
- nds32_v3_common_register_callback(&nds32_v3m_common_callback);
- nds32_v3_target_create_common(target, &(nds32_v3m->nds32));
-
- return ERROR_OK;
-}
-
-/* talk to the target and set things up */
-static int nds32_v3m_examine(struct target *target)
-{
- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target);
- struct nds32 *nds32 = &(nds32_v3m->nds32);
- struct aice_port_s *aice = target_to_aice(target);
-
- if (!target_was_examined(target)) {
- CHECK_RETVAL(nds32_edm_config(nds32));
-
- if (nds32->reset_halt_as_examine)
- CHECK_RETVAL(nds32_reset_halt(nds32));
- }
-
- uint32_t edm_cfg;
- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
-
- /* get the number of hardware breakpoints */
- nds32_v3m->n_hbr = (edm_cfg & 0x7) + 1;
- nds32_v3m->used_n_wp = 0;
-
- /* get the number of hardware watchpoints */
- /* If the WP field is hardwired to zero, it means this is a
- * simple breakpoint. Otherwise, if the WP field is writable
- * then it means this is a regular watchpoints. */
- nds32_v3m->n_hwp = 0;
- for (int32_t i = 0 ; i < nds32_v3m->n_hbr ; i++) {
- /** check the hardware breakpoint is simple or not */
- uint32_t tmp_value;
- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + i, 0x1);
- aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &tmp_value);
-
- if (tmp_value)
- nds32_v3m->n_hwp++;
- }
- /* hardware breakpoint is inserted from high index to low index */
- nds32_v3m->next_hbr_index = nds32_v3m->n_hbr - 1;
- /* hardware watchpoint is inserted from low index to high index */
- nds32_v3m->next_hwp_index = 0;
-
- LOG_INFO("%s: total hardware breakpoint %" PRId32 " (simple breakpoint %" PRId32 ")",
- target_name(target), nds32_v3m->n_hbr, nds32_v3m->n_hbr - nds32_v3m->n_hwp);
- LOG_INFO("%s: total hardware watchpoint %" PRId32, target_name(target), nds32_v3m->n_hwp);
-
- nds32->target->state = TARGET_RUNNING;
- nds32->target->debug_reason = DBG_REASON_NOTHALTED;
-
- target_set_examined(target);
-
- return ERROR_OK;
-}
-
-/** Holds methods for NDS32 V3m targets. */
-struct target_type nds32_v3m_target = {
- .name = "nds32_v3m",
-
- .poll = nds32_poll,
- .arch_state = nds32_arch_state,
-
- .target_request_data = nds32_v3_target_request_data,
-
- .halt = nds32_halt,
- .resume = nds32_resume,
- .step = nds32_step,
-
- .assert_reset = nds32_assert_reset,
- .deassert_reset = nds32_v3m_deassert_reset,
-
- /* register access */
- .get_gdb_reg_list = nds32_get_gdb_reg_list,
-
- /* memory access */
- .read_buffer = nds32_v3_read_buffer,
- .write_buffer = nds32_v3_write_buffer,
- .read_memory = nds32_v3_read_memory,
- .write_memory = nds32_v3_write_memory,
-
- .checksum_memory = nds32_v3_checksum_memory,
-
- /* breakpoint/watchpoint */
- .add_breakpoint = nds32_v3m_add_breakpoint,
- .remove_breakpoint = nds32_v3m_remove_breakpoint,
- .add_watchpoint = nds32_v3m_add_watchpoint,
- .remove_watchpoint = nds32_v3m_remove_watchpoint,
- .hit_watchpoint = nds32_v3_hit_watchpoint,
-
- /* MMU */
- .mmu = nds32_mmu,
- .virt2phys = nds32_virtual_to_physical,
- .read_phys_memory = nds32_read_phys_memory,
- .write_phys_memory = nds32_write_phys_memory,
-
- .run_algorithm = nds32_v3_run_algorithm,
-
- .commands = nds32_command_handlers,
- .target_create = nds32_v3m_target_create,
- .init_target = nds32_v3_init_target,
- .examine = nds32_v3m_examine,
-
- .get_gdb_fileio_info = nds32_get_gdb_fileio_info,
- .gdb_fileio_end = nds32_gdb_fileio_end,
-};
diff --git a/src/target/nds32_v3m.h b/src/target/nds32_v3m.h
deleted file mode 100644
index f21dd62..0000000
--- a/src/target/nds32_v3m.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/***************************************************************************
- * Copyright (C) 2013 Andes Technology *
- * Hsiangkai Wang <hkwang@andestech.com> *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_NDS32_V3M_H
-#define OPENOCD_TARGET_NDS32_V3M_H
-
-#include "nds32.h"
-
-struct nds32_v3m_common {
- struct nds32 nds32;
-
- /** number of hardware breakpoints */
- int32_t n_hbr;
-
- /** number of hardware watchpoints */
- int32_t n_hwp;
-
- /** number of used hardware watchpoints */
- int32_t used_n_wp;
-
- /** next hardware breakpoint index */
- /** for simple breakpoints, hardware breakpoints are inserted
- * from high index to low index */
- int32_t next_hbr_index;
-
- /** next hardware watchpoint index */
- /** increase from low index to high index */
- int32_t next_hwp_index;
-};
-
-static inline struct nds32_v3m_common *target_to_nds32_v3m(struct target *target)
-{
- return container_of(target->arch_info, struct nds32_v3m_common, nds32);
-}
-
-#endif /* OPENOCD_TARGET_NDS32_V3M_H */
diff --git a/src/target/openrisc/or1k_du_adv.c b/src/target/openrisc/or1k_du_adv.c
index cfb7d0e..e4c89e5 100644
--- a/src/target/openrisc/or1k_du_adv.c
+++ b/src/target/openrisc/or1k_du_adv.c
@@ -934,7 +934,7 @@ static int or1k_adv_jtag_write_memory(struct or1k_jtag *jtag_info,
void *t = NULL;
struct target *target = jtag_info->target;
if ((target->endianness == TARGET_BIG_ENDIAN) && (size != 1)) {
- t = malloc(count * size * sizeof(uint8_t));
+ t = calloc(count * size, sizeof(uint8_t));
if (!t) {
LOG_ERROR("Out of memory");
return ERROR_FAIL;
@@ -947,6 +947,9 @@ static int or1k_adv_jtag_write_memory(struct or1k_jtag *jtag_info,
case 2:
buf_bswap16(t, buffer, size * count);
break;
+ default:
+ free(t);
+ return ERROR_TARGET_FAILURE;
}
buffer = t;
}
diff --git a/src/target/rtt.c b/src/target/rtt.c
index ef2c45d..b14c42f 100644
--- a/src/target/rtt.c
+++ b/src/target/rtt.c
@@ -241,43 +241,37 @@ int target_rtt_find_control_block(struct target *target,
target_addr_t *address, size_t size, const char *id, bool *found,
void *user_data)
{
+ target_addr_t address_end = *address + size;
uint8_t buf[1024];
*found = false;
- size_t j = 0;
- size_t cb_offset = 0;
+ size_t id_matched_length = 0;
const size_t id_length = strlen(id);
LOG_INFO("rtt: Searching for control block '%s'", id);
- for (target_addr_t addr = 0; addr < size; addr = addr + sizeof(buf)) {
+ for (target_addr_t addr = *address; addr < address_end; addr += sizeof(buf)) {
int ret;
- const size_t buf_size = MIN(sizeof(buf), size - addr);
- ret = target_read_buffer(target, *address + addr, buf_size, buf);
+ const size_t buf_size = MIN(sizeof(buf), address_end - addr);
+ ret = target_read_buffer(target, addr, buf_size, buf);
if (ret != ERROR_OK)
return ret;
- size_t start = 0;
- size_t i = 0;
-
- while (i < buf_size) {
- if (buf[i] != id[j]) {
- start++;
- cb_offset++;
- i = start;
- j = 0;
-
- continue;
+ for (size_t buf_off = 0; buf_off < buf_size; buf_off++) {
+ if (id_matched_length > 0 &&
+ buf[buf_off] != id[id_matched_length]) {
+ /* Start from beginning */
+ id_matched_length = 0;
}
- i++;
- j++;
+ if (buf[buf_off] == id[id_matched_length])
+ id_matched_length++;
- if (j == id_length) {
- *address = *address + cb_offset;
+ if (id_matched_length == id_length) {
+ *address = addr + buf_off + 1 - id_length;
*found = true;
return ERROR_OK;
}
diff --git a/src/target/startup.tcl b/src/target/startup.tcl
index 290e79d..35492a6 100644
--- a/src/target/startup.tcl
+++ b/src/target/startup.tcl
@@ -114,10 +114,21 @@ proc ocd_process_reset_inner { MODE } {
continue
}
- # don't wait for targets where examination is deferred
- # they can not be halted anyway at this point
- if { ![$t was_examined] && [$t examine_deferred] } {
- continue
+ if { ![$t was_examined] } {
+ # don't wait for targets where examination is deferred
+ # they can not be halted anyway at this point
+ if { [$t examine_deferred] } {
+ continue
+ }
+ # try to re-examine or target state will be unknown
+ $t invoke-event examine-start
+ set err [catch "$t arp_examine allow-defer"]
+ if { $err } {
+ $t invoke-event examine-fail
+ return -code error [format "TARGET: %s - Not examined" $t]
+ } else {
+ $t invoke-event examine-end
+ }
}
# Wait up to 1 second for target to halt. Why 1sec? Cause
diff --git a/src/target/target.c b/src/target/target.c
index f09c9a5..db0eb09 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -92,9 +92,6 @@ extern struct target_type dsp5680xx_target;
extern struct target_type testee_target;
extern struct target_type avr32_ap7k_target;
extern struct target_type hla_target;
-extern struct target_type nds32_v2_target;
-extern struct target_type nds32_v3_target;
-extern struct target_type nds32_v3m_target;
extern struct target_type esp32_target;
extern struct target_type esp32s2_target;
extern struct target_type esp32s3_target;
@@ -132,9 +129,6 @@ static struct target_type *target_types[] = {
&testee_target,
&avr32_ap7k_target,
&hla_target,
- &nds32_v2_target,
- &nds32_v3_target,
- &nds32_v3m_target,
&esp32_target,
&esp32s2_target,
&esp32s3_target,
@@ -4253,11 +4247,19 @@ static void write_gmon(uint32_t *samples, uint32_t sample_num, const char *filen
/* max should be (largest sample + 1)
* Refer to binutils/gprof/hist.c (find_histogram_for_pc) */
- max++;
+ if (max < UINT32_MAX)
+ max++;
+
+ /* gprof requires (max - min) >= 2 */
+ while ((max - min) < 2) {
+ if (max < UINT32_MAX)
+ max++;
+ else
+ min--;
+ }
}
- int address_space = max - min;
- assert(address_space >= 2);
+ uint32_t address_space = max - min;
/* FIXME: What is the reasonable number of buckets?
* The profiling result will be more accurate if there are enough buckets. */
@@ -4333,6 +4335,19 @@ COMMAND_HANDLER(handle_profile_command)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], offset);
+ uint32_t start_address = 0;
+ uint32_t end_address = 0;
+ bool with_range = false;
+ if (CMD_ARGC == 4) {
+ with_range = true;
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], start_address);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], end_address);
+ if (start_address > end_address || (end_address - start_address) < 2) {
+ command_print(CMD, "Error: end - start < 2");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+ }
+
uint32_t *samples = malloc(sizeof(uint32_t) * MAX_PROFILE_SAMPLE_NUM);
if (!samples) {
LOG_ERROR("No memory to store samples.");
@@ -4385,15 +4400,6 @@ COMMAND_HANDLER(handle_profile_command)
return retval;
}
- uint32_t start_address = 0;
- uint32_t end_address = 0;
- bool with_range = false;
- if (CMD_ARGC == 4) {
- with_range = true;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], start_address);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], end_address);
- }
-
write_gmon(samples, num_of_samples, CMD_ARGV[1],
with_range, start_address, end_address, target, duration_ms);
command_print(CMD, "Wrote %s", CMD_ARGV[1]);
@@ -6435,16 +6441,52 @@ static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return JIM_OK;
}
+static struct target_list *
+__attribute__((warn_unused_result))
+create_target_list_node(Jim_Obj *const name) {
+ int len;
+ const char *targetname = Jim_GetString(name, &len);
+ struct target *target = get_target(targetname);
+ LOG_DEBUG("%s ", targetname);
+ if (!target)
+ return NULL;
+
+ struct target_list *new = malloc(sizeof(struct target_list));
+ if (!new) {
+ LOG_ERROR("Out of memory");
+ return new;
+ }
+
+ new->target = target;
+ return new;
+}
+
+static int get_target_with_common_rtos_type(struct list_head *lh, struct target **result)
+{
+ struct target *target = NULL;
+ struct target_list *curr;
+ foreach_smp_target(curr, lh) {
+ struct rtos *curr_rtos = curr->target->rtos;
+ if (curr_rtos) {
+ if (target && target->rtos && target->rtos->type != curr_rtos->type) {
+ LOG_ERROR("Different rtos types in members of one smp target!");
+ return JIM_ERR;
+ }
+ target = curr->target;
+ }
+ }
+ *result = target;
+ return JIM_OK;
+}
+
static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- int i;
- const char *targetname;
- int retval, len;
static int smp_group = 1;
- struct target *target = NULL;
- struct target_list *head, *new;
- retval = 0;
+ if (argc == 1) {
+ LOG_DEBUG("Empty SMP target");
+ return JIM_OK;
+ }
LOG_DEBUG("%d", argc);
/* argv[1] = target to associate in smp
* argv[2] = target to associate in smp
@@ -6458,27 +6500,24 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
INIT_LIST_HEAD(lh);
- for (i = 1; i < argc; i++) {
-
- targetname = Jim_GetString(argv[i], &len);
- target = get_target(targetname);
- LOG_DEBUG("%s ", targetname);
- if (target) {
- new = malloc(sizeof(struct target_list));
- new->target = target;
+ for (int i = 1; i < argc; i++) {
+ struct target_list *new = create_target_list_node(argv[i]);
+ if (new)
list_add_tail(&new->lh, lh);
- }
}
/* now parse the list of cpu and put the target in smp mode*/
- foreach_smp_target(head, lh) {
- target = head->target;
+ struct target_list *curr;
+ foreach_smp_target(curr, lh) {
+ struct target *target = curr->target;
target->smp = smp_group;
target->smp_targets = lh;
}
smp_group++;
- if (target && target->rtos)
- retval = rtos_smp_init(target);
+ struct target *rtos_target;
+ int retval = get_target_with_common_rtos_type(lh, &rtos_target);
+ if (retval == JIM_OK && rtos_target)
+ retval = rtos_smp_init(rtos_target);
return retval;
}
diff --git a/src/target/target.h b/src/target/target.h
index 197890b..8589e17 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -199,6 +199,10 @@ struct target {
struct list_head *smp_targets; /* list all targets in this smp group/cluster
* The head of the list is shared between the
* cluster, thus here there is a pointer */
+ bool smp_halt_event_postponed; /* Some SMP implementations (currently Cortex-M) stores
+ * 'halted' events and emits them after all targets of
+ * the SMP group has been polled */
+
/* the gdb service is there in case of smp, we have only one gdb server
* for all smp target
* the target attached to the gdb is changing dynamically by changing
diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c
index 4dfff6a..b57e2d6 100644
--- a/src/target/xtensa/xtensa.c
+++ b/src/target/xtensa/xtensa.c
@@ -168,8 +168,9 @@
#define XT_REG_A3 (xtensa_regs[XT_REG_IDX_AR3].reg_num)
#define XT_REG_A4 (xtensa_regs[XT_REG_IDX_AR4].reg_num)
-#define XT_PS_REG_NUM_BASE (0xc0U) /* (EPS2 - 2), for adding DBGLEVEL */
-#define XT_PC_REG_NUM_BASE (0xb0U) /* (EPC1 - 1), for adding DBGLEVEL */
+#define XT_PS_REG_NUM (0xe6U)
+#define XT_EPS_REG_NUM_BASE (0xc0U) /* (EPS2 - 2), for adding DBGLEVEL */
+#define XT_EPC_REG_NUM_BASE (0xb0U) /* (EPC1 - 1), for adding DBGLEVEL */
#define XT_PC_REG_NUM_VIRTUAL (0xffU) /* Marker for computing PC (EPC[DBGLEVEL) */
#define XT_PC_DBREG_NUM_BASE (0x20U) /* External (i.e., GDB) access */
@@ -245,7 +246,7 @@ struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS] = {
XT_MK_REG_DESC("ar63", 0x3F, XT_REG_GENERAL, 0),
XT_MK_REG_DESC("windowbase", 0x48, XT_REG_SPECIAL, 0),
XT_MK_REG_DESC("windowstart", 0x49, XT_REG_SPECIAL, 0),
- XT_MK_REG_DESC("ps", 0xE6, XT_REG_SPECIAL, 0), /* PS (not mapped through EPS[]) */
+ XT_MK_REG_DESC("ps", XT_PS_REG_NUM, XT_REG_SPECIAL, 0), /* PS (not mapped through EPS[]) */
XT_MK_REG_DESC("ibreakenable", 0x60, XT_REG_SPECIAL, 0),
XT_MK_REG_DESC("ddr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD),
XT_MK_REG_DESC("ibreaka0", 0x80, XT_REG_SPECIAL, 0),
@@ -630,7 +631,7 @@ static int xtensa_write_dirty_registers(struct target *target)
/* reg number of PC for debug interrupt depends on NDEBUGLEVEL
**/
reg_num =
- (XT_PC_REG_NUM_BASE +
+ (XT_EPC_REG_NUM_BASE +
xtensa->core_config->debug.irq_level);
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3));
}
@@ -800,8 +801,7 @@ int xtensa_examine(struct target *target)
return ERROR_TARGET_FAILURE;
}
LOG_DEBUG("OCD_ID = %08" PRIx32, xtensa->dbg_mod.device_id);
- if (!target_was_examined(target))
- target_set_examined(target);
+ target_set_examined(target);
xtensa_smpbreak_write(xtensa, xtensa->smp_break);
return ERROR_OK;
}
@@ -1105,10 +1105,10 @@ int xtensa_fetch_all_regs(struct target *target)
case XT_REG_SPECIAL:
if (reg_num == XT_PC_REG_NUM_VIRTUAL) {
/* reg number of PC for debug interrupt depends on NDEBUGLEVEL */
- reg_num = (XT_PC_REG_NUM_BASE + xtensa->core_config->debug.irq_level);
+ reg_num = XT_EPC_REG_NUM_BASE + xtensa->core_config->debug.irq_level;
} else if (reg_num == xtensa_regs[XT_REG_IDX_PS].reg_num) {
/* reg number of PS for debug interrupt depends on NDEBUGLEVEL */
- reg_num = (XT_PS_REG_NUM_BASE + xtensa->core_config->debug.irq_level);
+ reg_num = XT_EPS_REG_NUM_BASE + xtensa->core_config->debug.irq_level;
} else if (reg_num == xtensa_regs[XT_REG_IDX_CPENABLE].reg_num) {
/* CPENABLE already read/updated; don't re-read */
reg_fetched = false;
@@ -1629,7 +1629,6 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
target->debug_reason = DBG_REASON_SINGLESTEP;
target->state = TARGET_HALTED;
- target_call_event_callbacks(target, TARGET_EVENT_HALTED);
LOG_DEBUG("Done stepping, PC=%" PRIX32, cur_pc);
if (cause & DEBUGCAUSE_DB) {
@@ -1657,7 +1656,12 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
int xtensa_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
{
- return xtensa_do_step(target, current, address, handle_breakpoints);
+ int retval = xtensa_do_step(target, current, address, handle_breakpoints);
+ if (retval != ERROR_OK)
+ return retval;
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+
+ return ERROR_OK;
}
/**
@@ -1780,9 +1784,9 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si
if (res != ERROR_OK) {
if (xtensa->probe_lsddr32p != 0) {
/* Disable fast memory access instructions and retry before reporting an error */
- LOG_TARGET_INFO(target, "Disabling LDDR32.P/SDDR32.P");
+ LOG_TARGET_DEBUG(target, "Disabling LDDR32.P/SDDR32.P");
xtensa->probe_lsddr32p = 0;
- res = xtensa_read_memory(target, address, size, count, buffer);
+ res = xtensa_read_memory(target, address, size, count, albuff);
bswap = false;
} else {
LOG_TARGET_WARNING(target, "Failed reading %d bytes at address "TARGET_ADDR_FMT,
@@ -2502,6 +2506,12 @@ static int xtensa_build_reg_cache(struct target *target)
unsigned int j;
for (j = 0; j < reg_cache->num_regs; j++) {
if (!strcmp(reg_cache->reg_list[j].name, xtensa->contiguous_regs_desc[i]->name)) {
+ /* Register number field is not filled above.
+ Here we are assigning the corresponding index from the contiguous reg list.
+ These indexes are in the same order with gdb g-packet request/response.
+ Some more changes may be required for sparse reg lists.
+ */
+ reg_cache->reg_list[j].number = i;
xtensa->contiguous_regs_list[i] = &(reg_cache->reg_list[j]);
LOG_TARGET_DEBUG(target,
"POPULATE contiguous regs list: %-16s, dbreg_num 0x%04x",
@@ -3441,8 +3451,8 @@ COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa)
else
rptr->flags = 0;
- if ((rptr->reg_num == (XT_PS_REG_NUM_BASE + xtensa->core_config->debug.irq_level)) &&
- (xtensa->core_config->core_type == XT_LX) && (rptr->type == XT_REG_SPECIAL)) {
+ if (rptr->reg_num == (XT_EPS_REG_NUM_BASE + xtensa->core_config->debug.irq_level) &&
+ xtensa->core_config->core_type == XT_LX && rptr->type == XT_REG_SPECIAL) {
xtensa->eps_dbglevel_idx = XT_NUM_REGS + xtensa->num_optregs - 1;
LOG_DEBUG("Setting PS (%s) index to %d", rptr->name, xtensa->eps_dbglevel_idx);
}
diff --git a/tcl/board/nds32_xc5.cfg b/tcl/board/nds32_xc5.cfg
deleted file mode 100644
index 82a117e..0000000
--- a/tcl/board/nds32_xc5.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-set _CPUTAPID 0x1000063d
-set _CHIPNAME nds32
-source [find target/nds32v3.cfg]
-
-jtag init
diff --git a/tcl/cpld/xilinx-xcu.cfg b/tcl/cpld/xilinx-xcu.cfg
index 57a59f5..9df696d 100644
--- a/tcl/cpld/xilinx-xcu.cfg
+++ b/tcl/cpld/xilinx-xcu.cfg
@@ -9,7 +9,7 @@ if { [info exists CHIPNAME] } {
set _CHIPNAME xcu
}
-# The cvarious chips in the Ultrascale family have different IR length.
+# The various chips in the Ultrascale family have different IR length.
# Set $CHIP before including this file to determine the device.
array set _XCU_DATA {
XCKU025 {0x03824093 6}
diff --git a/tcl/interface/nds32-aice.cfg b/tcl/interface/nds32-aice.cfg
deleted file mode 100644
index 1d9717c..0000000
--- a/tcl/interface/nds32-aice.cfg
+++ /dev/null
@@ -1,17 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-#
-# Andes AICE
-#
-# http://www.andestech.com
-#
-
-adapter driver aice
-aice desc "Andes AICE adapter"
-# adapter serial "C001-42163"
-aice vid_pid 0x1CFC 0x0000
-aice port aice_usb
-reset_config trst_and_srst
-adapter speed 24000
-aice retry_times 50
-aice count_to_check_dbger 30
diff --git a/tcl/interface/raspberrypi2-native.cfg b/tcl/interface/raspberrypi2-native.cfg
index 5faabed..d5edded 100644
--- a/tcl/interface/raspberrypi2-native.cfg
+++ b/tcl/interface/raspberrypi2-native.cfg
@@ -15,9 +15,9 @@ adapter driver bcm2835gpio
bcm2835gpio peripheral_base 0x3F000000
# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
-# These depend on system clock, calibrated for stock 700MHz
+# These depend on system clock, calibrated for scaling_max_freq 900MHz
# bcm2835gpio speed SPEED_COEFF SPEED_OFFSET
-bcm2835gpio speed_coeffs 146203 36
+bcm2835gpio speed_coeffs 225000 36
# Each of the JTAG lines need a gpio number set: tck tms tdi tdo
# Header pin numbers: 23 22 19 21
diff --git a/tcl/target/atmega32u4.cfg b/tcl/target/atmega32u4.cfg
new file mode 100644
index 0000000..9199c74
--- /dev/null
+++ b/tcl/target/atmega32u4.cfg
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ATmega32U4
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME avr
+}
+
+if { [info exists ENDIAN] } {
+ set _ENDIAN $ENDIAN
+} else {
+ set _ENDIAN little
+}
+
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID 0x4958703f
+}
+
+adapter speed 4500
+
+jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME
diff --git a/tcl/target/max32620.cfg b/tcl/target/max32620.cfg
index 9f0f492..f3a9f84 100644
--- a/tcl/target/max32620.cfg
+++ b/tcl/target/max32620.cfg
@@ -16,8 +16,10 @@ if {[using_jtag]} {
swd newdap max32620 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version
}
+dap create max32620.dap -chain-position max32620.cpu
+
# target configuration
-target create max32620.cpu cortex_m -chain-position max32620.cpu
+target create max32620.cpu cortex_m -dap max32620.dap
max32620.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000
# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]
diff --git a/tcl/target/max32625.cfg b/tcl/target/max32625.cfg
index 35e1c3b..90eb392 100644
--- a/tcl/target/max32625.cfg
+++ b/tcl/target/max32625.cfg
@@ -16,8 +16,10 @@ if {[using_jtag]} {
swd newdap max32625 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version
}
+dap create max32625.dap -chain-position max32625.cpu
+
# target configuration
-target create max32625.cpu cortex_m -chain-position max32625.cpu
+target create max32625.cpu cortex_m -dap max32625.dap
max32625.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000
# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]
diff --git a/tcl/target/max3263x.cfg b/tcl/target/max3263x.cfg
index 52a5a77..852e04a 100644
--- a/tcl/target/max3263x.cfg
+++ b/tcl/target/max3263x.cfg
@@ -16,8 +16,10 @@ if {[using_jtag]} {
swd newdap max3263x cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version
}
+dap create max3263x.dap -chain-position max3263x.cpu
+
# target configuration
-target create max3263x.cpu cortex_m -chain-position max3263x.cpu
+target create max3263x.cpu cortex_m -dap max3263x.dap
max3263x.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000
# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]
diff --git a/tcl/target/nds32v2.cfg b/tcl/target/nds32v2.cfg
deleted file mode 100644
index 07814b7..0000000
--- a/tcl/target/nds32v2.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-#
-# Andes Core
-#
-# http://www.andestech.com
-#
-
-jtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID
-
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME nds32_v2 -endian little -chain-position $_TARGETNAME
diff --git a/tcl/target/nds32v3.cfg b/tcl/target/nds32v3.cfg
deleted file mode 100644
index 0fd1369..0000000
--- a/tcl/target/nds32v3.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-#
-# Andes Core
-#
-# http://www.andestech.com
-#
-
-jtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID
-
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME nds32_v3 -endian little -chain-position $_TARGETNAME
diff --git a/tcl/target/nds32v3m.cfg b/tcl/target/nds32v3m.cfg
deleted file mode 100644
index 29a2478..0000000
--- a/tcl/target/nds32v3m.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-#
-# Andes Core
-#
-# http://www.andestech.com
-#
-
-jtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID
-
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME nds32_v3m -endian little -chain-position $_TARGETNAME
diff --git a/tcl/target/rp2040-core0.cfg b/tcl/target/rp2040-core0.cfg
deleted file mode 100644
index 8c3533b..0000000
--- a/tcl/target/rp2040-core0.cfg
+++ /dev/null
@@ -1,37 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-transport select swd
-
-source [find target/swj-dp.tcl]
-
-if { [info exists CHIPNAME] } {
- set _CHIPNAME $CHIPNAME
-} else {
- set _CHIPNAME rp2040
-}
-
-if { [info exists WORKAREASIZE] } {
- set _WORKAREASIZE $WORKAREASIZE
-} else {
- set _WORKAREASIZE 0x10000
-}
-
-if { [info exists CPUTAPID] } {
- set _CPUTAPID $CPUTAPID
-} else {
- set _CPUTAPID 0x01002927
-}
-
-swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID
-dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap
-$_TARGETNAME configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE
-
-set _FLASHNAME $_CHIPNAME.flash
-set _FLASHSIZE 0x200000
-set _FLASHBASE 0x10000000
-flash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME
-
-# srst does not exist; use SYSRESETREQ to perform a soft reset
-cortex_m reset_config sysresetreq
diff --git a/tcl/target/rp2040.cfg b/tcl/target/rp2040.cfg
new file mode 100644
index 0000000..0593e03
--- /dev/null
+++ b/tcl/target/rp2040.cfg
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# RP2040 is a microcontroller with dual Cortex-M0+ core.
+# https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html
+
+# The device requires multidrop SWD for debug.
+transport select swd
+
+source [find target/swj-dp.tcl]
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME rp2040
+}
+
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x10000
+}
+
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID 0x01002927
+}
+
+# Set to '0' or '1' for single core configuration, 'SMP' for -rtos hwthread
+# handling of both cores, anything else for isolated debugging of both cores
+if { [info exists USE_CORE] } {
+ set _USE_CORE $USE_CORE
+} else {
+ set _USE_CORE SMP
+}
+set _BOTH_CORES [expr { $_USE_CORE != 0 && $_USE_CORE != 1 }]
+
+swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID
+
+# core 0
+if { $_USE_CORE != 1 } {
+ dap create $_CHIPNAME.dap0 -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id 0
+ set _TARGETNAME_0 $_CHIPNAME.core0
+ target create $_TARGETNAME_0 cortex_m -dap $_CHIPNAME.dap0 -coreid 0
+ # srst does not exist; use SYSRESETREQ to perform a soft reset
+ $_TARGETNAME_0 cortex_m reset_config sysresetreq
+}
+
+# core 1
+if { $_USE_CORE != 0 } {
+ dap create $_CHIPNAME.dap1 -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id 1
+ set _TARGETNAME_1 $_CHIPNAME.core1
+ target create $_TARGETNAME_1 cortex_m -dap $_CHIPNAME.dap1 -coreid 1
+ $_TARGETNAME_1 cortex_m reset_config sysresetreq
+}
+
+if {[string compare $_USE_CORE SMP] == 0} {
+ $_TARGETNAME_0 configure -rtos hwthread
+ $_TARGETNAME_1 configure -rtos hwthread
+ target smp $_TARGETNAME_0 $_TARGETNAME_1
+}
+
+if { $_USE_CORE == 1 } {
+ set _FLASH_TARGET $_TARGETNAME_1
+} else {
+ set _FLASH_TARGET $_TARGETNAME_0
+}
+# Backup the work area. The flash probe runs an algorithm on the target CPU.
+# The flash is probed during gdb connect if gdb_memory_map is enabled (by default).
+$_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE -work-area-backup 1
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME rp2040_flash 0x10000000 0 0 0 $_FLASH_TARGET
+
+if { $_BOTH_CORES } {
+ # Alias to ensure gdb connecting to core 1 gets the correct memory map
+ flash bank $_CHIPNAME.alias virtual 0x10000000 0 0 0 $_TARGETNAME_1 $_FLASHNAME
+
+ # Select core 0
+ targets $_TARGETNAME_0
+}
diff --git a/tcl/target/stm32x5x_common.cfg b/tcl/target/stm32x5x_common.cfg
index c506e22..fb3aeb1 100644
--- a/tcl/target/stm32x5x_common.cfg
+++ b/tcl/target/stm32x5x_common.cfg
@@ -58,7 +58,9 @@ if {[using_jtag]} {
reset_config srst_nogate
-if {![using_hla]} {
+if {[using_hla]} {
+ echo "Warn : The selected adapter does not support debugging this device in secure mode"
+} else {
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
cortex_m reset_config sysresetreq
@@ -71,13 +73,18 @@ proc stm32x5x_is_secure {} {
}
proc stm32x5x_ahb_ap_non_secure_access {} {
- # SPROT=1=Non Secure access, Priv=1
- [[target current] cget -dap] apcsw 0x4B000000 0x4F000000
+ # in HLA mode, non-secure debugging is possible without changing the AP CSW
+ if {![using_hla]} {
+ # SPROT=1=Non Secure access, Priv=1
+ [[target current] cget -dap] apcsw 0x4B000000 0x4F000000
+ }
}
proc stm32x5x_ahb_ap_secure_access {} {
- # SPROT=0=Secure access, Priv=1
- [[target current] cget -dap] apcsw 0x0B000000 0x4F000000
+ if {![using_hla]} {
+ # SPROT=0=Secure access, Priv=1
+ [[target current] cget -dap] apcsw 0x0B000000 0x4F000000
+ }
}
$_TARGETNAME configure -event reset-start {
@@ -152,10 +159,11 @@ lappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu
proc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {
targets $_targetname
- # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
- # change this value accordingly to configure trace pins
+ # Set TRACE_EN and TRACE_IOEN in DBGMCU_CR
+ # Leave TRACE_MODE untouched (defaults to async).
+ # When using sync change this value accordingly to configure trace pins
# assignment
- mmw 0xE0044004 0x00000020 0
+ mmw 0xE0044004 0x00000030 0
}
$_CHIPNAME.tpiu configure -event pre-enable "_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME"
diff --git a/tcl/target/ti_k3.cfg b/tcl/target/ti_k3.cfg
index 254bb69..2454357 100644
--- a/tcl/target/ti_k3.cfg
+++ b/tcl/target/ti_k3.cfg
@@ -12,6 +12,8 @@
# Has 2 ARMV8 Cores and 4 R5 Cores, M4F and an M3
#
+source [find target/swj-dp.tcl]
+
if { [info exists SOC] } {
set _soc $SOC
} else {
@@ -164,7 +166,8 @@ switch $_soc {
}
}
-jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_K3_DAP_TAPID -ignore-version
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_K3_DAP_TAPID -ignore-version
+
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
set _TARGETNAME $_CHIPNAME.cpu
diff --git a/tcl/target/xtensa-core-esp32.cfg b/tcl/target/xtensa-core-esp32.cfg
index e7b5a20..9a70072 100644
--- a/tcl/target/xtensa-core-esp32.cfg
+++ b/tcl/target/xtensa-core-esp32.cfg
@@ -22,6 +22,7 @@ xtensa xtmem irom 0x40000000 0x64F00
xtensa xtmem iram 0x40070000 0x30000
xtensa xtmem iram 0x400C0000 0x2000
xtensa xtmem drom 0x3F400000 0x800000
+xtensa xtmem drom 0x3FF90000 0x10000
xtensa xtmem dram 0x3FFAE000 0x52000
xtensa xtmem dram 0x3FF80000 0x2000
xtensa xtmem dram 0x3F800000 0x400000
@@ -35,7 +36,7 @@ xtensa xtmem dram 0x60000000 0x20000000
xtensa xtopt debuglevel 6
xtensa xtopt ibreaknum 2
xtensa xtopt dbreaknum 2
-xtensa xtopt tracemem 8192
+xtensa xtopt tracemem 0x4000
xtensa xtopt tracememrev 1
xtensa xtopt perfcount 2
@@ -46,7 +47,7 @@ xtensa xtopt perfcount 2
# in "Read General Registers" (g-packet) requests.
# NOTE: For contiguous format, registers listed in GDB order.
# xtregs: Total number of Xtensa registers in the system
-xtensa xtregs 205
+xtensa xtregs 173
xtensa xtregfmt contiguous 105
xtensa xtreg pc 0x0020
xtensa xtreg ar0 0x0100
@@ -123,8 +124,6 @@ xtensa xtreg configid0 0x02b0
xtensa xtreg configid1 0x02d0
xtensa xtreg ps 0x02e6
xtensa xtreg threadptr 0x03e7
-
-# added by hand for esp32
xtensa xtreg br 0x0204
xtensa xtreg scompare1 0x020c
xtensa xtreg acclo 0x0210
@@ -155,13 +154,10 @@ xtensa xtreg f14 0x003e
xtensa xtreg f15 0x003f
xtensa xtreg fcr 0x03e8
xtensa xtreg fsr 0x03e9
-
xtensa xtreg mmid 0x0259
xtensa xtreg ibreakenable 0x0260
-
xtensa xtreg memctl 0x0261
xtensa xtreg atomctl 0x0263
-
xtensa xtreg ddr 0x0268
xtensa xtreg ibreaka0 0x0280
xtensa xtreg ibreaka1 0x0281
@@ -226,35 +222,3 @@ xtensa xtreg a12 0x000c
xtensa xtreg a13 0x000d
xtensa xtreg a14 0x000e
xtensa xtreg a15 0x000f
-xtensa xtreg pwrctl 0x2028
-xtensa xtreg pwrstat 0x2029
-xtensa xtreg eristat 0x202a
-xtensa xtreg cs_itctrl 0x202b
-xtensa xtreg cs_claimset 0x202c
-xtensa xtreg cs_claimclr 0x202d
-xtensa xtreg cs_lockaccess 0x202e
-xtensa xtreg cs_lockstatus 0x202f
-xtensa xtreg cs_authstatus 0x2030
-xtensa xtreg fault_info 0x203f
-xtensa xtreg trax_id 0x2040
-xtensa xtreg trax_control 0x2041
-xtensa xtreg trax_status 0x2042
-xtensa xtreg trax_data 0x2043
-xtensa xtreg trax_address 0x2044
-xtensa xtreg trax_pctrigger 0x2045
-xtensa xtreg trax_pcmatch 0x2046
-xtensa xtreg trax_delay 0x2047
-xtensa xtreg trax_memstart 0x2048
-xtensa xtreg trax_memend 0x2049
-xtensa xtreg pmg 0x2057
-xtensa xtreg pmpc 0x2058
-xtensa xtreg pm0 0x2059
-xtensa xtreg pm1 0x205a
-xtensa xtreg pmctrl0 0x2061
-xtensa xtreg pmctrl1 0x2062
-xtensa xtreg pmstat0 0x2069
-xtensa xtreg pmstat1 0x206a
-xtensa xtreg ocdid 0x2071
-xtensa xtreg ocd_dcrclr 0x2072
-xtensa xtreg ocd_dcrset 0x2073
-xtensa xtreg ocd_dsr 0x2074
diff --git a/tcl/target/xtensa-core-esp32s2.cfg b/tcl/target/xtensa-core-esp32s2.cfg
index e590e51..b38cb1d 100644
--- a/tcl/target/xtensa-core-esp32s2.cfg
+++ b/tcl/target/xtensa-core-esp32s2.cfg
@@ -23,6 +23,7 @@ xtensa xtmem iram 0x40020000 0x50000
xtensa xtmem iram 0x40070000 0x2000
xtensa xtmem drom 0x3F000000 0x400000
xtensa xtmem drom 0x3F4D3FFC 0xAAC004
+xtensa xtmem drom 0x3FFA0000 0x10000
xtensa xtmem dram 0x3FFB0000 0x50000
xtensa xtmem dram 0x3FF9E000 0x2000
xtensa xtmem dram 0x50000000 0x2000
@@ -36,8 +37,8 @@ xtensa xtmem dram 0x60000000 0x20000000
xtensa xtopt debuglevel 6
xtensa xtopt ibreaknum 2
xtensa xtopt dbreaknum 2
-xtensa xtopt tracemem 8192
-xtensa xtopt tracememrev 1
+xtensa xtopt tracemem 0x4000
+xtensa xtopt tracememrev 0
xtensa xtopt perfcount 2
# Core Registers
@@ -48,7 +49,7 @@ xtensa xtopt perfcount 2
# NOTE: For contiguous format, registers listed in GDB order.
# xtregs: Total number of Xtensa registers in the system
xtensa xtregs 171
-xtensa xtregfmt contiguous 72
+xtensa xtregfmt contiguous 73
xtensa xtreg pc 0x0020
xtensa xtreg ar0 0x0100
xtensa xtreg ar1 0x0101
@@ -121,8 +122,7 @@ xtensa xtreg configid0 0x02b0
xtensa xtreg configid1 0x02d0
xtensa xtreg ps 0x02e6
xtensa xtreg threadptr 0x03e7
-# gpio_out should be 0x0300? Hits an exception on wrover
-xtensa xtreg gpio_out 0x0268
+xtensa xtreg gpio_out 0x0300
xtensa xtreg mmid 0x0259
xtensa xtreg ibreakenable 0x0260
xtensa xtreg ddr 0x0268
@@ -173,6 +173,38 @@ xtensa xtreg misc0 0x02f4
xtensa xtreg misc1 0x02f5
xtensa xtreg misc2 0x02f6
xtensa xtreg misc3 0x02f7
+xtensa xtreg pwrctl 0x2014
+xtensa xtreg pwrstat 0x2015
+xtensa xtreg eristat 0x2016
+xtensa xtreg cs_itctrl 0x2017
+xtensa xtreg cs_claimset 0x2018
+xtensa xtreg cs_claimclr 0x2019
+xtensa xtreg cs_lockaccess 0x201a
+xtensa xtreg cs_lockstatus 0x201b
+xtensa xtreg cs_authstatus 0x201c
+xtensa xtreg fault_info 0x202b
+xtensa xtreg trax_id 0x202c
+xtensa xtreg trax_control 0x202d
+xtensa xtreg trax_status 0x202e
+xtensa xtreg trax_data 0x202f
+xtensa xtreg trax_address 0x2030
+xtensa xtreg trax_pctrigger 0x2031
+xtensa xtreg trax_pcmatch 0x2032
+xtensa xtreg trax_delay 0x2033
+xtensa xtreg trax_memstart 0x2034
+xtensa xtreg trax_memend 0x2035
+xtensa xtreg pmg 0x2043
+xtensa xtreg pmpc 0x2044
+xtensa xtreg pm0 0x2045
+xtensa xtreg pm1 0x2046
+xtensa xtreg pmctrl0 0x2047
+xtensa xtreg pmctrl1 0x2048
+xtensa xtreg pmstat0 0x2049
+xtensa xtreg pmstat1 0x204a
+xtensa xtreg ocdid 0x204b
+xtensa xtreg ocd_dcrclr 0x204c
+xtensa xtreg ocd_dcrset 0x204d
+xtensa xtreg ocd_dsr 0x204e
xtensa xtreg a0 0x0000
xtensa xtreg a1 0x0001
xtensa xtreg a2 0x0002
@@ -189,35 +221,3 @@ xtensa xtreg a12 0x000c
xtensa xtreg a13 0x000d
xtensa xtreg a14 0x000e
xtensa xtreg a15 0x000f
-xtensa xtreg pwrctl 0x2028
-xtensa xtreg pwrstat 0x2029
-xtensa xtreg eristat 0x202a
-xtensa xtreg cs_itctrl 0x202b
-xtensa xtreg cs_claimset 0x202c
-xtensa xtreg cs_claimclr 0x202d
-xtensa xtreg cs_lockaccess 0x202e
-xtensa xtreg cs_lockstatus 0x202f
-xtensa xtreg cs_authstatus 0x2030
-xtensa xtreg fault_info 0x203f
-xtensa xtreg trax_id 0x2040
-xtensa xtreg trax_control 0x2041
-xtensa xtreg trax_status 0x2042
-xtensa xtreg trax_data 0x2043
-xtensa xtreg trax_address 0x2044
-xtensa xtreg trax_pctrigger 0x2045
-xtensa xtreg trax_pcmatch 0x2046
-xtensa xtreg trax_delay 0x2047
-xtensa xtreg trax_memstart 0x2048
-xtensa xtreg trax_memend 0x2049
-xtensa xtreg pmg 0x2057
-xtensa xtreg pmpc 0x2058
-xtensa xtreg pm0 0x2059
-xtensa xtreg pm1 0x205a
-xtensa xtreg pmctrl0 0x2061
-xtensa xtreg pmctrl1 0x2062
-xtensa xtreg pmstat0 0x2069
-xtensa xtreg pmstat1 0x206a
-xtensa xtreg ocdid 0x2071
-xtensa xtreg ocd_dcrclr 0x2072
-xtensa xtreg ocd_dcrset 0x2073
-xtensa xtreg ocd_dsr 0x2074
diff --git a/tcl/target/xtensa-core-esp32s3.cfg b/tcl/target/xtensa-core-esp32s3.cfg
index f5c1cb3..b3f20e3 100644
--- a/tcl/target/xtensa-core-esp32s3.cfg
+++ b/tcl/target/xtensa-core-esp32s3.cfg
@@ -20,6 +20,7 @@ xtensa xtmem irom 0x40000000 0x60000
xtensa xtmem iram 0x40370000 0x70000
xtensa xtmem iram 0x600FE000 0x2000
xtensa xtmem drom 0x3C000000 0x1000000
+xtensa xtmem drom 0x3FF00000 0x20000
xtensa xtmem dram 0x3FC88000 0x78000
xtensa xtmem dram 0x600FE000 0x2000
xtensa xtmem dram 0x50000000 0x2000
@@ -31,8 +32,8 @@ xtensa xtmem dram 0x60000000 0x10000000
xtensa xtopt debuglevel 6
xtensa xtopt ibreaknum 2
xtensa xtopt dbreaknum 2
-xtensa xtopt tracemem 16384
-xtensa xtopt tracememrev 1
+xtensa xtopt tracemem 0x4000
+xtensa xtopt tracememrev 0
xtensa xtopt perfcount 2
@@ -43,7 +44,7 @@ xtensa xtopt perfcount 2
# in "Read General Registers" (g-packet) requests.
# NOTE: For contiguous format, registers listed in GDB order.
# xtregs: Total number of Xtensa registers in the system
-xtensa xtregs 244
+xtensa xtregs 228
xtensa xtregfmt contiguous 128
xtensa xtreg pc 0x0020
xtensa xtreg ar0 0x0100
@@ -128,10 +129,7 @@ xtensa xtreg m0 0x0220
xtensa xtreg m1 0x0221
xtensa xtreg m2 0x0222
xtensa xtreg m3 0x0223
-
-# TODO: update gpioout address while testing on S3 HW
-xtensa xtreg gpioout 0x02f4
-
+xtensa xtreg gpio_out 0x030c
xtensa xtreg f0 0x0030
xtensa xtreg f1 0x0031
xtensa xtreg f2 0x0032
@@ -150,35 +148,32 @@ xtensa xtreg f14 0x003e
xtensa xtreg f15 0x003f
xtensa xtreg fcr 0x03e8
xtensa xtreg fsr 0x03e9
-
-# TODO: update TIE state
-xtensa xtreg accx_0 0x02f4
-xtensa xtreg accx_1 0x02f4
-xtensa xtreg qacc_h_0 0x02f4
-xtensa xtreg qacc_h_1 0x02f4
-xtensa xtreg qacc_h_2 0x02f4
-xtensa xtreg qacc_h_3 0x02f4
-xtensa xtreg qacc_h_4 0x02f4
-xtensa xtreg qacc_l_0 0x02f4
-xtensa xtreg qacc_l_1 0x02f4
-xtensa xtreg qacc_l_2 0x02f4
-xtensa xtreg qacc_l_3 0x02f4
-xtensa xtreg qacc_l_4 0x02f4
-xtensa xtreg sar_byte 0x02f4
-xtensa xtreg fft_bit_width 0x02f4
-xtensa xtreg ua_state_0 0x02f4
-xtensa xtreg ua_state_1 0x02f4
-xtensa xtreg ua_state_2 0x02f4
-xtensa xtreg ua_state_3 0x02f4
-xtensa xtreg q0 0x02f4
-xtensa xtreg q1 0x02f4
-xtensa xtreg q2 0x02f4
-xtensa xtreg q3 0x02f4
-xtensa xtreg q4 0x02f4
-xtensa xtreg q5 0x02f4
-xtensa xtreg q6 0x02f4
-xtensa xtreg q7 0x02f4
-
+xtensa xtreg accx_0 0x0300
+xtensa xtreg accx_1 0x0301
+xtensa xtreg qacc_h_0 0x0302
+xtensa xtreg qacc_h_1 0x0303
+xtensa xtreg qacc_h_2 0x0304
+xtensa xtreg qacc_h_3 0x0305
+xtensa xtreg qacc_h_4 0x0306
+xtensa xtreg qacc_l_0 0x0307
+xtensa xtreg qacc_l_1 0x0308
+xtensa xtreg qacc_l_2 0x0309
+xtensa xtreg qacc_l_3 0x030a
+xtensa xtreg qacc_l_4 0x030b
+xtensa xtreg sar_byte 0x030d
+xtensa xtreg fft_bit_width 0x030e
+xtensa xtreg ua_state_0 0x030f
+xtensa xtreg ua_state_1 0x0310
+xtensa xtreg ua_state_2 0x0311
+xtensa xtreg ua_state_3 0x0312
+xtensa xtreg q0 0x1008
+xtensa xtreg q1 0x1009
+xtensa xtreg q2 0x100a
+xtensa xtreg q3 0x100b
+xtensa xtreg q4 0x100c
+xtensa xtreg q5 0x100d
+xtensa xtreg q6 0x100e
+xtensa xtreg q7 0x100f
xtensa xtreg mmid 0x0259
xtensa xtreg ibreakenable 0x0260
xtensa xtreg memctl 0x0261
@@ -231,38 +226,38 @@ xtensa xtreg misc0 0x02f4
xtensa xtreg misc1 0x02f5
xtensa xtreg misc2 0x02f6
xtensa xtreg misc3 0x02f7
-xtensa xtreg pwrctl 0x2025
-xtensa xtreg pwrstat 0x2026
-xtensa xtreg eristat 0x2027
-xtensa xtreg cs_itctrl 0x2028
-xtensa xtreg cs_claimset 0x2029
-xtensa xtreg cs_claimclr 0x202a
-xtensa xtreg cs_lockaccess 0x202b
-xtensa xtreg cs_lockstatus 0x202c
-xtensa xtreg cs_authstatus 0x202d
-xtensa xtreg fault_info 0x203c
-xtensa xtreg trax_id 0x203d
-xtensa xtreg trax_control 0x203e
-xtensa xtreg trax_status 0x203f
-xtensa xtreg trax_data 0x2040
-xtensa xtreg trax_address 0x2041
-xtensa xtreg trax_pctrigger 0x2042
-xtensa xtreg trax_pcmatch 0x2043
-xtensa xtreg trax_delay 0x2044
-xtensa xtreg trax_memstart 0x2045
-xtensa xtreg trax_memend 0x2046
-xtensa xtreg pmg 0x2054
-xtensa xtreg pmpc 0x2055
-xtensa xtreg pm0 0x2056
-xtensa xtreg pm1 0x2057
-xtensa xtreg pmctrl0 0x2058
-xtensa xtreg pmctrl1 0x2059
-xtensa xtreg pmstat0 0x205a
-xtensa xtreg pmstat1 0x205b
-xtensa xtreg ocdid 0x205c
-xtensa xtreg ocd_dcrclr 0x205d
-xtensa xtreg ocd_dcrset 0x205e
-xtensa xtreg ocd_dsr 0x205f
+xtensa xtreg pwrctl 0x2028
+xtensa xtreg pwrstat 0x2029
+xtensa xtreg eristat 0x202a
+xtensa xtreg cs_itctrl 0x202b
+xtensa xtreg cs_claimset 0x202c
+xtensa xtreg cs_claimclr 0x202d
+xtensa xtreg cs_lockaccess 0x202e
+xtensa xtreg cs_lockstatus 0x202f
+xtensa xtreg cs_authstatus 0x2030
+xtensa xtreg fault_info 0x203f
+xtensa xtreg trax_id 0x2040
+xtensa xtreg trax_control 0x2041
+xtensa xtreg trax_status 0x2042
+xtensa xtreg trax_data 0x2043
+xtensa xtreg trax_address 0x2044
+xtensa xtreg trax_pctrigger 0x2045
+xtensa xtreg trax_pcmatch 0x2046
+xtensa xtreg trax_delay 0x2047
+xtensa xtreg trax_memstart 0x2048
+xtensa xtreg trax_memend 0x2049
+xtensa xtreg pmg 0x2057
+xtensa xtreg pmpc 0x2058
+xtensa xtreg pm0 0x2059
+xtensa xtreg pm1 0x205a
+xtensa xtreg pmctrl0 0x205b
+xtensa xtreg pmctrl1 0x205c
+xtensa xtreg pmstat0 0x205d
+xtensa xtreg pmstat1 0x205e
+xtensa xtreg ocdid 0x205f
+xtensa xtreg ocd_dcrclr 0x2060
+xtensa xtreg ocd_dcrset 0x2061
+xtensa xtreg ocd_dsr 0x2062
xtensa xtreg a0 0x0000
xtensa xtreg a1 0x0001
xtensa xtreg a2 0x0002
@@ -279,19 +274,3 @@ xtensa xtreg a12 0x000c
xtensa xtreg a13 0x000d
xtensa xtreg a14 0x000e
xtensa xtreg a15 0x000f
-xtensa xtreg b0 0x0010
-xtensa xtreg b1 0x0011
-xtensa xtreg b2 0x0012
-xtensa xtreg b3 0x0013
-xtensa xtreg b4 0x0014
-xtensa xtreg b5 0x0015
-xtensa xtreg b6 0x0016
-xtensa xtreg b7 0x0017
-xtensa xtreg b8 0x0018
-xtensa xtreg b9 0x0019
-xtensa xtreg b10 0x001a
-xtensa xtreg b11 0x001b
-xtensa xtreg b12 0x001c
-xtensa xtreg b13 0x001d
-xtensa xtreg b14 0x001e
-xtensa xtreg b15 0x001f
diff --git a/tools/scripts/camelcase.txt b/tools/scripts/camelcase.txt
index 59fe5ca..2caa81c 100644
--- a/tools/scripts/camelcase.txt
+++ b/tools/scripts/camelcase.txt
@@ -175,10 +175,7 @@ __FreeBSD_kernel__
# for Windows
CreateFile
CloseHandle
-CreatePipe
-CreateProcess
FormatMessage
-GetLastError
GetModuleFileName
GetSystemTimeAsFileTime
GetTickCount
@@ -189,29 +186,16 @@ MsgWaitForMultipleObjects
PeekMessage
PeekNamedPipe
QuadPart
-ReadFile
SetConsoleCtrlHandler
-SetHandleInformation
Sleep
WaitForSingleObject
-WriteFile
WSACleanup
WSAGetLastError
WSAStartup
-ZeroMemory
-bInheritHandle
-dwFlags
dwHighDateTime
dwLowDateTime
dwPlatformId
dwOSVersionInfoSize
-hProcess
-hThread
-hStdError
-hStdInput
-hStdOutput
-lpSecurityDescriptor
-nLength
# OpenOCD exceptions that should be removed
KiB