aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2023-03-16 17:52:48 -0700
committerTim Newsome <tim@sifive.com>2023-03-16 18:02:35 -0700
commit868ebdd89ca75a73bffe335395aa1ed522dda660 (patch)
tree95ead6f4982b85a6cc90d5832712523a8ee7b77a /src
parent3387015af01f18cc350c4764fbd533068ed15f3d (diff)
parent1293ddd65713d6551775b67169387622ada477c1 (diff)
downloadriscv-openocd-868ebdd89ca75a73bffe335395aa1ed522dda660.zip
riscv-openocd-868ebdd89ca75a73bffe335395aa1ed522dda660.tar.gz
riscv-openocd-868ebdd89ca75a73bffe335395aa1ed522dda660.tar.bz2
Merge commit '1293ddd65713d6551775b67169387622ada477c1' into from_upstream
This includes https://sourceforge.net/p/openocd/mailman/message/37710818/, which should fix #814. Conflicts: .travis.yml contrib/loaders/flash/stm32/stm32f1x.S contrib/loaders/flash/stm32/stm32f2x.S doc/openocd.texi src/rtos/FreeRTOS.c src/server/gdb_server.c src/target/riscv/riscv-013.c src/target/riscv/riscv.c src/target/riscv/riscv.h src/target/riscv/riscv_semihosting.c tcl/target/esp_common.cfg tcl/target/gd32vf103.cfg tools/scripts/checkpatch.pl Change-Id: I1986c13298ca0dafbe3aecaf1b0b35626525e4eb
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/flash/Makefile.am2
-rw-r--r--src/flash/common.c15
-rw-r--r--src/flash/common.h15
-rw-r--r--src/flash/nand/Makefile.am2
-rw-r--r--src/flash/nand/arm_io.c15
-rw-r--r--src/flash/nand/arm_io.h15
-rw-r--r--src/flash/nand/at91sam9.c15
-rw-r--r--src/flash/nand/core.c15
-rw-r--r--src/flash/nand/core.h15
-rw-r--r--src/flash/nand/davinci.c15
-rw-r--r--src/flash/nand/driver.c15
-rw-r--r--src/flash/nand/driver.h15
-rw-r--r--src/flash/nand/ecc.c26
-rw-r--r--src/flash/nand/ecc_kw.c15
-rw-r--r--src/flash/nand/fileio.c15
-rw-r--r--src/flash/nand/fileio.h15
-rw-r--r--src/flash/nand/imp.h15
-rw-r--r--src/flash/nand/lpc3180.c15
-rw-r--r--src/flash/nand/lpc3180.h15
-rw-r--r--src/flash/nand/lpc32xx.c15
-rw-r--r--src/flash/nand/lpc32xx.h15
-rw-r--r--src/flash/nand/mx3.c15
-rw-r--r--src/flash/nand/mx3.h15
-rw-r--r--src/flash/nand/mxc.c15
-rw-r--r--src/flash/nand/mxc.h15
-rw-r--r--src/flash/nand/nonce.c15
-rw-r--r--src/flash/nand/nuc910.c15
-rw-r--r--src/flash/nand/nuc910.h15
-rw-r--r--src/flash/nand/orion.c15
-rw-r--r--src/flash/nand/s3c2410.c15
-rw-r--r--src/flash/nand/s3c2412.c15
-rw-r--r--src/flash/nand/s3c2440.c15
-rw-r--r--src/flash/nand/s3c2443.c15
-rw-r--r--src/flash/nand/s3c24xx.c15
-rw-r--r--src/flash/nand/s3c24xx.h15
-rw-r--r--src/flash/nand/s3c24xx_regs.h14
-rw-r--r--src/flash/nand/s3c6400.c15
-rw-r--r--src/flash/nand/tcl.c15
-rw-r--r--src/flash/nor/Makefile.am3
-rw-r--r--src/flash/nor/aduc702x.c15
-rw-r--r--src/flash/nor/aducm360.c15
-rw-r--r--src/flash/nor/ambiqmicro.c29
-rw-r--r--src/flash/nor/at91sam3.c64
-rw-r--r--src/flash/nor/at91sam4.c65
-rw-r--r--src/flash/nor/at91sam4l.c15
-rw-r--r--src/flash/nor/at91sam7.c26
-rw-r--r--src/flash/nor/at91samd.c15
-rw-r--r--src/flash/nor/ath79.c16
-rw-r--r--src/flash/nor/atsame5.c15
-rw-r--r--src/flash/nor/atsamv.c69
-rw-r--r--src/flash/nor/avrf.c15
-rw-r--r--src/flash/nor/bluenrg-x.c44
-rw-r--r--src/flash/nor/bluenrg-x.h15
-rw-r--r--src/flash/nor/cc26xx.c25
-rw-r--r--src/flash/nor/cc26xx.h25
-rw-r--r--src/flash/nor/cc3220sf.c20
-rw-r--r--src/flash/nor/cc3220sf.h20
-rw-r--r--src/flash/nor/cfi.c15
-rw-r--r--src/flash/nor/cfi.h15
-rw-r--r--src/flash/nor/core.c15
-rw-r--r--src/flash/nor/core.h17
-rw-r--r--src/flash/nor/driver.h15
-rw-r--r--src/flash/nor/drivers.c17
-rw-r--r--src/flash/nor/dsp5680xx_flash.c15
-rw-r--r--src/flash/nor/efm32.c19
-rw-r--r--src/flash/nor/em357.c17
-rw-r--r--src/flash/nor/esirisc_flash.c15
-rw-r--r--src/flash/nor/faux.c15
-rw-r--r--src/flash/nor/fespi.c21
-rw-r--r--src/flash/nor/fm3.c15
-rw-r--r--src/flash/nor/fm4.c18
-rw-r--r--src/flash/nor/imp.h15
-rw-r--r--src/flash/nor/jtagspi.c15
-rw-r--r--src/flash/nor/kinetis.c91
-rw-r--r--src/flash/nor/kinetis_ke.c37
-rw-r--r--src/flash/nor/lpc2000.c15
-rw-r--r--src/flash/nor/lpc288x.c15
-rw-r--r--src/flash/nor/lpc2900.c15
-rw-r--r--src/flash/nor/lpcspifi.c15
-rw-r--r--src/flash/nor/max32xxx.c15
-rw-r--r--src/flash/nor/mdr.c15
-rw-r--r--src/flash/nor/mrvlqspi.c15
-rw-r--r--src/flash/nor/msp432.c30
-rw-r--r--src/flash/nor/msp432.h30
-rw-r--r--src/flash/nor/niietcm4.c15
-rw-r--r--src/flash/nor/non_cfi.c15
-rw-r--r--src/flash/nor/non_cfi.h15
-rw-r--r--src/flash/nor/npcx.c4
-rw-r--r--src/flash/nor/nrf5.c17
-rw-r--r--src/flash/nor/numicro.c15
-rw-r--r--src/flash/nor/ocl.c15
-rw-r--r--src/flash/nor/ocl.h15
-rw-r--r--src/flash/nor/pic32mx.c17
-rw-r--r--src/flash/nor/psoc4.c25
-rw-r--r--src/flash/nor/psoc5lp.c47
-rw-r--r--src/flash/nor/psoc6.c18
-rw-r--r--src/flash/nor/renesas_rpchf.c3
-rw-r--r--src/flash/nor/rp2040.c2
-rw-r--r--src/flash/nor/rsl10.c843
-rw-r--r--src/flash/nor/sfdp.c14
-rw-r--r--src/flash/nor/sfdp.h14
-rw-r--r--src/flash/nor/sh_qspi.c3
-rw-r--r--src/flash/nor/sim3x.c36
-rw-r--r--src/flash/nor/spi.c15
-rw-r--r--src/flash/nor/spi.h15
-rw-r--r--src/flash/nor/stellaris.c15
-rw-r--r--src/flash/nor/stm32f1x.c17
-rw-r--r--src/flash/nor/stm32f2x.c17
-rw-r--r--src/flash/nor/stm32h7x.c15
-rw-r--r--src/flash/nor/stm32l4x.c23
-rw-r--r--src/flash/nor/stm32l4x.h15
-rw-r--r--src/flash/nor/stm32lx.c17
-rw-r--r--src/flash/nor/stmqspi.c43
-rw-r--r--src/flash/nor/stmqspi.h15
-rw-r--r--src/flash/nor/stmsmi.c15
-rw-r--r--src/flash/nor/str7x.c15
-rw-r--r--src/flash/nor/str9x.c15
-rw-r--r--src/flash/nor/str9xpec.c15
-rw-r--r--src/flash/nor/swm050.c15
-rw-r--r--src/flash/nor/tcl.c15
-rw-r--r--src/flash/nor/tms470.c18
-rw-r--r--src/flash/nor/virtual.c15
-rw-r--r--src/flash/nor/w600.c17
-rw-r--r--src/flash/nor/xcf.c15
-rw-r--r--src/flash/nor/xmc1xxx.c20
-rw-r--r--src/flash/nor/xmc4xxx.c15
-rw-r--r--src/flash/startup.tcl2
-rw-r--r--src/hello.c15
-rw-r--r--src/hello.h15
-rw-r--r--src/helper/Makefile.am2
-rwxr-xr-xsrc/helper/bin2char.sh1
-rw-r--r--src/helper/binarybuffer.c15
-rw-r--r--src/helper/binarybuffer.h15
-rw-r--r--src/helper/bits.h15
-rw-r--r--src/helper/command.c35
-rw-r--r--src/helper/command.h15
-rw-r--r--src/helper/configuration.c21
-rw-r--r--src/helper/configuration.h15
-rw-r--r--src/helper/fileio.c15
-rw-r--r--src/helper/fileio.h15
-rw-r--r--src/helper/jep106.c15
-rw-r--r--src/helper/jep106.h15
-rw-r--r--src/helper/jep106.inc106
-rw-r--r--src/helper/jim-nvp.c31
-rw-r--r--src/helper/jim-nvp.h171
-rw-r--r--src/helper/log.c21
-rw-r--r--src/helper/log.h16
-rw-r--r--src/helper/options.c15
-rw-r--r--src/helper/replacements.c15
-rw-r--r--src/helper/replacements.h15
-rw-r--r--src/helper/startup.tcl2
-rw-r--r--src/helper/system.h15
-rw-r--r--src/helper/time_support.c15
-rw-r--r--src/helper/time_support.h15
-rw-r--r--src/helper/time_support_common.c15
-rw-r--r--src/helper/types.h15
-rwxr-xr-xsrc/helper/update_jep106.pl2
-rw-r--r--src/helper/util.c15
-rw-r--r--src/helper/util.h15
-rw-r--r--src/jtag/Makefile.am2
-rw-r--r--src/jtag/adapter.c323
-rw-r--r--src/jtag/adapter.h63
-rw-r--r--src/jtag/aice/Makefile.am2
-rw-r--r--src/jtag/aice/aice_interface.c15
-rw-r--r--src/jtag/aice/aice_interface.h15
-rw-r--r--src/jtag/aice/aice_pipe.c15
-rw-r--r--src/jtag/aice/aice_pipe.h15
-rw-r--r--src/jtag/aice/aice_port.c15
-rw-r--r--src/jtag/aice/aice_port.h15
-rw-r--r--src/jtag/aice/aice_transport.c15
-rw-r--r--src/jtag/aice/aice_transport.h15
-rw-r--r--src/jtag/aice/aice_usb.c15
-rw-r--r--src/jtag/aice/aice_usb.h15
-rw-r--r--src/jtag/commands.c15
-rw-r--r--src/jtag/commands.h15
-rw-r--r--src/jtag/core.c34
-rw-r--r--src/jtag/drivers/Makefile.am5
-rw-r--r--src/jtag/drivers/Makefile.rlink23
-rw-r--r--src/jtag/drivers/OpenULINK/Makefile23
-rw-r--r--src/jtag/drivers/OpenULINK/include/common.h15
-rw-r--r--src/jtag/drivers/OpenULINK/include/delay.h15
-rw-r--r--src/jtag/drivers/OpenULINK/include/io.h15
-rw-r--r--src/jtag/drivers/OpenULINK/include/jtag.h15
-rw-r--r--src/jtag/drivers/OpenULINK/include/main.h15
-rw-r--r--src/jtag/drivers/OpenULINK/include/msgtypes.h15
-rw-r--r--src/jtag/drivers/OpenULINK/include/protocol.h15
-rw-r--r--src/jtag/drivers/OpenULINK/include/reg_ezusb.h15
-rw-r--r--src/jtag/drivers/OpenULINK/include/usb.h15
-rw-r--r--src/jtag/drivers/OpenULINK/src/USBJmpTb.a5123
-rw-r--r--src/jtag/drivers/OpenULINK/src/delay.c15
-rw-r--r--src/jtag/drivers/OpenULINK/src/jtag.c15
-rw-r--r--src/jtag/drivers/OpenULINK/src/main.c15
-rw-r--r--src/jtag/drivers/OpenULINK/src/protocol.c15
-rw-r--r--src/jtag/drivers/OpenULINK/src/usb.c15
-rw-r--r--src/jtag/drivers/am335xgpio.c652
-rw-r--r--src/jtag/drivers/amt_jtagaccel.c15
-rw-r--r--src/jtag/drivers/arm-jtag-ew.c15
-rw-r--r--src/jtag/drivers/at91rm9200.c15
-rw-r--r--src/jtag/drivers/bcm2835gpio.c655
-rw-r--r--src/jtag/drivers/bitbang.c15
-rw-r--r--src/jtag/drivers/bitbang.h15
-rw-r--r--src/jtag/drivers/bitq.c15
-rw-r--r--src/jtag/drivers/bitq.h15
-rw-r--r--src/jtag/drivers/buspirate.c15
-rw-r--r--src/jtag/drivers/cmsis_dap.c15
-rw-r--r--src/jtag/drivers/cmsis_dap.h2
-rw-r--r--src/jtag/drivers/cmsis_dap_usb_bulk.c15
-rw-r--r--src/jtag/drivers/cmsis_dap_usb_hid.c15
-rw-r--r--src/jtag/drivers/driver.c15
-rw-r--r--src/jtag/drivers/dummy.c15
-rw-r--r--src/jtag/drivers/ep93xx.c28
-rw-r--r--src/jtag/drivers/esp_usb_jtag.c796
-rw-r--r--src/jtag/drivers/ft232r.c15
-rw-r--r--src/jtag/drivers/ftdi.c15
-rw-r--r--src/jtag/drivers/gw16012.c15
-rw-r--r--src/jtag/drivers/imx_gpio.c15
-rw-r--r--src/jtag/drivers/jlink.c15
-rw-r--r--src/jtag/drivers/jtag_dpi.c15
-rw-r--r--src/jtag/drivers/jtag_vpi.c15
-rw-r--r--src/jtag/drivers/kitprog.c45
m---------src/jtag/drivers/libjaylink0
-rw-r--r--src/jtag/drivers/libusb_helper.c15
-rw-r--r--src/jtag/drivers/libusb_helper.h15
-rw-r--r--src/jtag/drivers/linuxgpiod.c656
-rw-r--r--src/jtag/drivers/minidriver_imp.h15
-rw-r--r--src/jtag/drivers/mpsse.c15
-rw-r--r--src/jtag/drivers/mpsse.h15
-rw-r--r--src/jtag/drivers/nulink_usb.c15
-rw-r--r--src/jtag/drivers/opendous.c15
-rw-r--r--src/jtag/drivers/openjtag.c15
-rw-r--r--src/jtag/drivers/osbdm.c15
-rw-r--r--src/jtag/drivers/parport.c15
-rw-r--r--src/jtag/drivers/presto.c15
-rw-r--r--src/jtag/drivers/remote_bitbang.c15
-rw-r--r--src/jtag/drivers/rlink.c15
-rw-r--r--src/jtag/drivers/rlink.h15
-rw-r--r--src/jtag/drivers/rlink_call.m424
-rw-r--r--src/jtag/drivers/rlink_dtc_cmd.h15
-rw-r--r--src/jtag/drivers/rlink_ep1_cmd.h15
-rw-r--r--src/jtag/drivers/rlink_init.m424
-rw-r--r--src/jtag/drivers/rlink_st7.h15
-rw-r--r--src/jtag/drivers/rshim.c63
-rw-r--r--src/jtag/drivers/stlink_usb.c66
-rw-r--r--src/jtag/drivers/sysfsgpio.c15
-rw-r--r--src/jtag/drivers/ti_icdi_usb.c15
-rw-r--r--src/jtag/drivers/ulink.c15
-rw-r--r--src/jtag/drivers/usb_blaster/Makefile.am2
-rw-r--r--src/jtag/drivers/usb_blaster/ublast2_access_libusb.c15
-rw-r--r--src/jtag/drivers/usb_blaster/ublast_access.h15
-rw-r--r--src/jtag/drivers/usb_blaster/ublast_access_ftdi.c15
-rw-r--r--src/jtag/drivers/usb_blaster/usb_blaster.c15
-rw-r--r--src/jtag/drivers/usbprog.c17
-rw-r--r--src/jtag/drivers/vdebug.c559
-rw-r--r--src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c15
-rw-r--r--src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c15
-rw-r--r--src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c15
-rw-r--r--src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c15
-rw-r--r--src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c15
-rw-r--r--src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h15
-rw-r--r--src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h15
-rw-r--r--src/jtag/drivers/versaloon/versaloon.c15
-rw-r--r--src/jtag/drivers/versaloon/versaloon.h15
-rw-r--r--src/jtag/drivers/versaloon/versaloon_include.h15
-rw-r--r--src/jtag/drivers/versaloon/versaloon_internal.h15
-rw-r--r--src/jtag/drivers/vsllink.c15
-rw-r--r--src/jtag/drivers/xds110.c15
-rw-r--r--src/jtag/drivers/xlnx-pcie-xvc.c5
-rw-r--r--src/jtag/hla/Makefile.am2
-rw-r--r--src/jtag/hla/hla_interface.c15
-rw-r--r--src/jtag/hla/hla_interface.h15
-rw-r--r--src/jtag/hla/hla_layout.c15
-rw-r--r--src/jtag/hla/hla_layout.h15
-rw-r--r--src/jtag/hla/hla_tcl.c15
-rw-r--r--src/jtag/hla/hla_tcl.h15
-rw-r--r--src/jtag/hla/hla_transport.c15
-rw-r--r--src/jtag/hla/hla_transport.h15
-rw-r--r--src/jtag/interface.c15
-rw-r--r--src/jtag/interface.h15
-rw-r--r--src/jtag/interfaces.c21
-rw-r--r--src/jtag/interfaces.h15
-rw-r--r--src/jtag/jtag.h28
-rw-r--r--src/jtag/minidriver.h15
-rw-r--r--src/jtag/startup.tcl409
-rw-r--r--src/jtag/swd.h15
-rw-r--r--src/jtag/swim.c2
-rw-r--r--src/jtag/tcl.c15
-rw-r--r--src/jtag/tcl.h15
-rw-r--r--src/main.c15
-rw-r--r--src/openocd.c19
-rw-r--r--src/openocd.h15
-rw-r--r--src/pld/Makefile.am2
-rw-r--r--src/pld/pld.c15
-rw-r--r--src/pld/pld.h15
-rw-r--r--src/pld/virtex2.c15
-rw-r--r--src/pld/virtex2.h15
-rw-r--r--src/pld/xilinx_bit.c15
-rw-r--r--src/pld/xilinx_bit.h15
-rw-r--r--src/rtos/FreeRTOS.c35
-rw-r--r--src/rtos/Makefile.am2
-rw-r--r--src/rtos/ThreadX.c15
-rw-r--r--src/rtos/chibios.c15
-rw-r--r--src/rtos/chromium-ec.c4
-rw-r--r--src/rtos/eCos.c15
-rw-r--r--src/rtos/embKernel.c15
-rw-r--r--src/rtos/hwthread.c16
-rw-r--r--src/rtos/linux.c15
-rw-r--r--src/rtos/linux_header.h2
-rw-r--r--src/rtos/mqx.c15
-rw-r--r--src/rtos/nuttx.c19
-rw-r--r--src/rtos/nuttx_header.h15
-rw-r--r--src/rtos/riot.c15
-rw-r--r--src/rtos/rtos.c135
-rw-r--r--src/rtos/rtos.h15
-rw-r--r--src/rtos/rtos_chibios_stackings.c19
-rw-r--r--src/rtos/rtos_chibios_stackings.h15
-rw-r--r--src/rtos/rtos_ecos_stackings.c18
-rw-r--r--src/rtos/rtos_ecos_stackings.h16
-rw-r--r--src/rtos/rtos_embkernel_stackings.c17
-rw-r--r--src/rtos/rtos_embkernel_stackings.h15
-rw-r--r--src/rtos/rtos_mqx_stackings.c17
-rw-r--r--src/rtos/rtos_mqx_stackings.h15
-rw-r--r--src/rtos/rtos_riot_stackings.c19
-rw-r--r--src/rtos/rtos_riot_stackings.h15
-rw-r--r--src/rtos/rtos_standard_stackings.c21
-rw-r--r--src/rtos/rtos_standard_stackings.h15
-rw-r--r--src/rtos/rtos_ucos_iii_stackings.c17
-rw-r--r--src/rtos/rtos_ucos_iii_stackings.h15
-rw-r--r--src/rtos/uCOS-III.c15
-rw-r--r--src/rtos/zephyr.c6
-rw-r--r--src/rtt/Makefile.am2
-rw-r--r--src/rtt/rtt.c15
-rw-r--r--src/rtt/rtt.h15
-rw-r--r--src/rtt/tcl.c15
-rw-r--r--src/server/Makefile.am2
-rw-r--r--src/server/gdb_server.c251
-rw-r--r--src/server/gdb_server.h15
-rw-r--r--src/server/ipdbg.c2
-rw-r--r--src/server/rtt_server.c15
-rw-r--r--src/server/rtt_server.h15
-rw-r--r--src/server/server.c31
-rw-r--r--src/server/server.h17
-rw-r--r--src/server/startup.tcl2
-rw-r--r--src/server/tcl_server.c15
-rw-r--r--src/server/tcl_server.h15
-rw-r--r--src/server/telnet_server.c15
-rw-r--r--src/server/telnet_server.h15
-rw-r--r--src/svf/Makefile.am2
-rw-r--r--src/svf/svf.c15
-rw-r--r--src/svf/svf.h15
-rw-r--r--src/target/Makefile.am2
-rw-r--r--src/target/a64_disassembler.c15
-rw-r--r--src/target/a64_disassembler.h15
-rw-r--r--src/target/aarch64.c46
-rw-r--r--src/target/aarch64.h24
-rw-r--r--src/target/adi_v5_dapdirect.c15
-rw-r--r--src/target/adi_v5_jtag.c208
-rw-r--r--src/target/adi_v5_swd.c77
-rw-r--r--src/target/algorithm.c15
-rw-r--r--src/target/algorithm.h15
-rw-r--r--src/target/arc.c20
-rw-r--r--src/target/arc.h8
-rw-r--r--src/target/arc_cmd.c8
-rw-r--r--src/target/arc_cmd.h4
-rw-r--r--src/target/arc_jtag.c4
-rw-r--r--src/target/arc_jtag.h4
-rw-r--r--src/target/arc_mem.c4
-rw-r--r--src/target/arc_mem.h4
-rw-r--r--src/target/arm.h26
-rw-r--r--src/target/arm11.c15
-rw-r--r--src/target/arm11.h15
-rw-r--r--src/target/arm11_dbgtap.c15
-rw-r--r--src/target/arm11_dbgtap.h15
-rw-r--r--src/target/arm720t.c15
-rw-r--r--src/target/arm720t.h20
-rw-r--r--src/target/arm7_9_common.c15
-rw-r--r--src/target/arm7_9_common.h20
-rw-r--r--src/target/arm7tdmi.c15
-rw-r--r--src/target/arm7tdmi.h15
-rw-r--r--src/target/arm920t.c15
-rw-r--r--src/target/arm920t.h20
-rw-r--r--src/target/arm926ejs.c15
-rw-r--r--src/target/arm926ejs.h20
-rw-r--r--src/target/arm946e.c21
-rw-r--r--src/target/arm946e.h26
-rw-r--r--src/target/arm966e.c15
-rw-r--r--src/target/arm966e.h20
-rw-r--r--src/target/arm9tdmi.c15
-rw-r--r--src/target/arm9tdmi.h15
-rw-r--r--src/target/arm_adi_v5.c646
-rw-r--r--src/target/arm_adi_v5.h157
-rw-r--r--src/target/arm_cti.c42
-rw-r--r--src/target/arm_cti.h16
-rw-r--r--src/target/arm_dap.c92
-rw-r--r--src/target/arm_disassembler.c15
-rw-r--r--src/target/arm_disassembler.h15
-rw-r--r--src/target/arm_dpm.c15
-rw-r--r--src/target/arm_dpm.h15
-rw-r--r--src/target/arm_jtag.c15
-rw-r--r--src/target/arm_jtag.h15
-rw-r--r--src/target/arm_opcodes.h15
-rw-r--r--src/target/arm_semihosting.c15
-rw-r--r--src/target/arm_semihosting.h15
-rw-r--r--src/target/arm_simulator.c15
-rw-r--r--src/target/arm_simulator.h15
-rw-r--r--src/target/arm_tpiu_swo.c44
-rw-r--r--src/target/armv4_5.c78
-rw-r--r--src/target/armv4_5.h15
-rw-r--r--src/target/armv4_5_cache.c15
-rw-r--r--src/target/armv4_5_cache.h15
-rw-r--r--src/target/armv4_5_mmu.c15
-rw-r--r--src/target/armv4_5_mmu.h15
-rw-r--r--src/target/armv7a.c15
-rw-r--r--src/target/armv7a.h20
-rw-r--r--src/target/armv7a_cache.c15
-rw-r--r--src/target/armv7a_cache.h15
-rw-r--r--src/target/armv7a_cache_l2x.c15
-rw-r--r--src/target/armv7a_cache_l2x.h15
-rw-r--r--src/target/armv7a_mmu.c15
-rw-r--r--src/target/armv7a_mmu.h15
-rw-r--r--src/target/armv7m.c34
-rw-r--r--src/target/armv7m.h28
-rw-r--r--src/target/armv7m_trace.c15
-rw-r--r--src/target/armv7m_trace.h15
-rw-r--r--src/target/armv8.c42
-rw-r--r--src/target/armv8.h23
-rw-r--r--src/target/armv8_cache.c15
-rw-r--r--src/target/armv8_cache.h15
-rw-r--r--src/target/armv8_dpm.c27
-rw-r--r--src/target/armv8_dpm.h12
-rw-r--r--src/target/armv8_opcodes.c13
-rw-r--r--src/target/armv8_opcodes.h20
-rw-r--r--src/target/avr32_ap7k.c15
-rw-r--r--src/target/avr32_ap7k.h21
-rw-r--r--src/target/avr32_jtag.c15
-rw-r--r--src/target/avr32_jtag.h15
-rw-r--r--src/target/avr32_mem.c15
-rw-r--r--src/target/avr32_mem.h15
-rw-r--r--src/target/avr32_regs.c15
-rw-r--r--src/target/avr32_regs.h15
-rw-r--r--src/target/avrt.c15
-rw-r--r--src/target/avrt.h15
-rw-r--r--src/target/breakpoints.c19
-rw-r--r--src/target/breakpoints.h15
-rw-r--r--src/target/cortex_a.c39
-rw-r--r--src/target/cortex_a.h25
-rw-r--r--src/target/cortex_m.c79
-rw-r--r--src/target/cortex_m.h27
-rw-r--r--src/target/dsp563xx.c17
-rw-r--r--src/target/dsp563xx.h15
-rw-r--r--src/target/dsp563xx_once.c15
-rw-r--r--src/target/dsp563xx_once.h15
-rw-r--r--src/target/dsp5680xx.c17
-rw-r--r--src/target/dsp5680xx.h17
-rw-r--r--src/target/embeddedice.c15
-rw-r--r--src/target/embeddedice.h15
-rw-r--r--src/target/esirisc.c15
-rw-r--r--src/target/esirisc.h15
-rw-r--r--src/target/esirisc_jtag.c15
-rw-r--r--src/target/esirisc_jtag.h15
-rw-r--r--src/target/esirisc_regs.h15
-rw-r--r--src/target/esirisc_trace.c15
-rw-r--r--src/target/esirisc_trace.h15
-rw-r--r--src/target/espressif/Makefile.am11
-rw-r--r--src/target/espressif/esp32.c503
-rw-r--r--src/target/espressif/esp32s2.c258
-rw-r--r--src/target/espressif/esp32s2.h40
-rw-r--r--src/target/espressif/esp32s3.c422
-rw-r--r--src/target/espressif/esp_semihosting.c127
-rw-r--r--src/target/espressif/esp_semihosting.h55
-rw-r--r--src/target/espressif/esp_xtensa.c29
-rw-r--r--src/target/espressif/esp_xtensa.h24
-rw-r--r--src/target/espressif/esp_xtensa_semihosting.c114
-rw-r--r--src/target/espressif/esp_xtensa_semihosting.h15
-rw-r--r--src/target/espressif/esp_xtensa_smp.c931
-rw-r--r--src/target/espressif/esp_xtensa_smp.h54
-rw-r--r--src/target/etb.c15
-rw-r--r--src/target/etb.h15
-rw-r--r--src/target/etm.c15
-rw-r--r--src/target/etm.h15
-rw-r--r--src/target/etm_dummy.c15
-rw-r--r--src/target/etm_dummy.h15
-rw-r--r--src/target/fa526.c15
-rw-r--r--src/target/feroceon.c15
-rw-r--r--src/target/hla_target.c25
-rw-r--r--src/target/image.c15
-rw-r--r--src/target/image.h15
-rw-r--r--src/target/lakemont.c15
-rw-r--r--src/target/lakemont.h15
-rw-r--r--src/target/ls1_sap.c19
-rw-r--r--src/target/mem_ap.c38
-rw-r--r--src/target/mips32.c15
-rw-r--r--src/target/mips32.h22
-rw-r--r--src/target/mips32_dmaacc.c15
-rw-r--r--src/target/mips32_dmaacc.h15
-rw-r--r--src/target/mips32_pracc.c19
-rw-r--r--src/target/mips32_pracc.h19
-rw-r--r--src/target/mips64.c4
-rw-r--r--src/target/mips64.h5
-rw-r--r--src/target/mips64_pracc.c4
-rw-r--r--src/target/mips_ejtag.c15
-rw-r--r--src/target/mips_ejtag.h15
-rw-r--r--src/target/mips_m4k.c17
-rw-r--r--src/target/mips_m4k.h24
-rw-r--r--src/target/mips_mips64.c12
-rw-r--r--src/target/mips_mips64.h3
-rw-r--r--src/target/nds32.c15
-rw-r--r--src/target/nds32.h18
-rw-r--r--src/target/nds32_aice.c15
-rw-r--r--src/target/nds32_aice.h15
-rw-r--r--src/target/nds32_cmd.c15
-rw-r--r--src/target/nds32_cmd.h15
-rw-r--r--src/target/nds32_disassembler.c15
-rw-r--r--src/target/nds32_disassembler.h15
-rw-r--r--src/target/nds32_edm.h15
-rw-r--r--src/target/nds32_insn.h15
-rw-r--r--src/target/nds32_reg.c15
-rw-r--r--src/target/nds32_reg.h15
-rw-r--r--src/target/nds32_tlb.c15
-rw-r--r--src/target/nds32_tlb.h15
-rw-r--r--src/target/nds32_v2.c15
-rw-r--r--src/target/nds32_v2.h15
-rw-r--r--src/target/nds32_v3.c15
-rw-r--r--src/target/nds32_v3.h15
-rw-r--r--src/target/nds32_v3_common.c15
-rw-r--r--src/target/nds32_v3_common.h15
-rw-r--r--src/target/nds32_v3m.c15
-rw-r--r--src/target/nds32_v3m.h15
-rw-r--r--src/target/openrisc/Makefile.am2
-rw-r--r--src/target/openrisc/jsp_server.c15
-rw-r--r--src/target/openrisc/jsp_server.h2
-rw-r--r--src/target/openrisc/or1k.c15
-rw-r--r--src/target/openrisc/or1k.h15
-rw-r--r--src/target/openrisc/or1k_du.h15
-rw-r--r--src/target/openrisc/or1k_du_adv.c15
-rw-r--r--src/target/openrisc/or1k_tap.h15
-rw-r--r--src/target/openrisc/or1k_tap_mohor.c15
-rw-r--r--src/target/openrisc/or1k_tap_vjtag.c15
-rw-r--r--src/target/openrisc/or1k_tap_xilinx_bscan.c15
-rw-r--r--src/target/quark_d20xx.c15
-rw-r--r--src/target/quark_x10xx.c15
-rw-r--r--src/target/register.c15
-rw-r--r--src/target/register.h15
-rw-r--r--src/target/riscv/Makefile.am2
-rw-r--r--src/target/riscv/batch.c2
-rw-r--r--src/target/riscv/program.c2
-rw-r--r--src/target/riscv/riscv-011.c15
-rw-r--r--src/target/riscv/riscv-013.c31
-rw-r--r--src/target/riscv/riscv.c126
-rw-r--r--src/target/riscv/riscv.h57
-rw-r--r--src/target/riscv/riscv_semihosting.c40
-rw-r--r--src/target/rtt.c15
-rw-r--r--src/target/rtt.h15
-rw-r--r--src/target/semihosting_common.c120
-rw-r--r--src/target/semihosting_common.h48
-rw-r--r--src/target/smp.c14
-rw-r--r--src/target/smp.h14
-rw-r--r--src/target/startup.tcl2
-rw-r--r--src/target/stm8.c15
-rw-r--r--src/target/stm8.h20
-rw-r--r--src/target/target.c60
-rw-r--r--src/target/target.h31
-rw-r--r--src/target/target_request.c15
-rw-r--r--src/target/target_request.h15
-rw-r--r--src/target/target_type.h24
-rw-r--r--src/target/testee.c15
-rw-r--r--src/target/trace.c15
-rw-r--r--src/target/trace.h15
-rw-r--r--src/target/x86_32_common.c15
-rw-r--r--src/target/x86_32_common.h20
-rw-r--r--src/target/xscale.c15
-rw-r--r--src/target/xscale.h21
-rw-r--r--src/target/xtensa/Makefile.am4
-rw-r--r--src/target/xtensa/xtensa.c3009
-rw-r--r--src/target/xtensa/xtensa.h233
-rw-r--r--src/target/xtensa/xtensa_chip.c196
-rw-r--r--src/target/xtensa/xtensa_chip.h34
-rw-r--r--src/target/xtensa/xtensa_debug_module.c266
-rw-r--r--src/target/xtensa/xtensa_debug_module.h386
-rw-r--r--src/target/xtensa/xtensa_regs.h241
-rw-r--r--src/transport/Makefile.am2
-rw-r--r--src/transport/transport.c15
-rw-r--r--src/transport/transport.h15
-rw-r--r--src/xsvf/Makefile.am2
-rw-r--r--src/xsvf/xsvf.c15
-rw-r--r--src/xsvf/xsvf.h15
586 files changed, 12042 insertions, 11048 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 432c31e..6d79cd6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libopenocd.la
bin_PROGRAMS += %D%/openocd
diff --git a/src/flash/Makefile.am b/src/flash/Makefile.am
index 4c70702..c5eb248 100644
--- a/src/flash/Makefile.am
+++ b/src/flash/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libflash.la
%C%_libflash_la_SOURCES = \
%D%/common.c %D%/common.h
diff --git a/src/flash/common.c b/src/flash/common.c
index 0e7fe13..ebd9396 100644
--- a/src/flash/common.c
+++ b/src/flash/common.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/common.h b/src/flash/common.h
index 69f60d9..15aea5b 100644
--- a/src/flash/common.h
+++ b/src/flash/common.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_COMMON_H
diff --git a/src/flash/nand/Makefile.am b/src/flash/nand/Makefile.am
index abe90f8..6a1a9b1 100644
--- a/src/flash/nand/Makefile.am
+++ b/src/flash/nand/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libocdflashnand.la
%C%_libocdflashnand_la_SOURCES = \
diff --git a/src/flash/nand/arm_io.c b/src/flash/nand/arm_io.c
index 2b0c081..80bd0cf 100644
--- a/src/flash/nand/arm_io.c
+++ b/src/flash/nand/arm_io.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2009 by Marvell Semiconductors, Inc.
* Written by Nicolas Pitre <nico at marvell.com>
*
* Copyright (C) 2009 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/arm_io.h b/src/flash/nand/arm_io.h
index 8bb3114..10f0e66 100644
--- a/src/flash/nand/arm_io.h
+++ b/src/flash/nand/arm_io.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (C) 2009 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENOCD_FLASH_NAND_ARM_IO_H
#define OPENOCD_FLASH_NAND_ARM_IO_H
diff --git a/src/flash/nand/at91sam9.c b/src/flash/nand/at91sam9.c
index c8886d1..bfbba67 100644
--- a/src/flash/nand/at91sam9.c
+++ b/src/flash/nand/at91sam9.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2009 by Dean Glazeski
* dnglaze@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c
index c1f1bc4..37e1d12 100644
--- a/src/flash/nand/core.c
+++ b/src/flash/nand/core.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* Partially based on drivers/mtd/nand_ids.c from Linux. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h
index 12fc2b7..19c53d1 100644
--- a/src/flash/nand/core.h
+++ b/src/flash/nand/core.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
@@ -6,19 +8,6 @@
* Copyright (C) 2000 David Woodhouse <dwmw2@mvhi.com> *
* Copyright (C) 2000 Steven J. Hill <sjhill@realitydiluted.com> *
* Copyright (C) 2000 Thomas Gleixner <tglx@linutronix.de> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NAND_CORE_H
diff --git a/src/flash/nand/davinci.c b/src/flash/nand/davinci.c
index 1aa7ffc..b7169fe 100644
--- a/src/flash/nand/davinci.c
+++ b/src/flash/nand/davinci.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by David Brownell *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/driver.c b/src/flash/nand/driver.c
index b525f3d..02e5c09 100644
--- a/src/flash/nand/driver.c
+++ b/src/flash/nand/driver.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/driver.h b/src/flash/nand/driver.h
index 690ee91..a874cc8 100644
--- a/src/flash/nand/driver.h
+++ b/src/flash/nand/driver.h
@@ -1,21 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NAND_DRIVER_H
diff --git a/src/flash/nand/ecc.c b/src/flash/nand/ecc.c
index 25b2eb1..20b8ba8 100644
--- a/src/flash/nand/ecc.c
+++ b/src/flash/nand/ecc.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later WITH eCos-exception-2.0
+
/*
* This file contains an ECC algorithm from Toshiba that allows for detection
* and correction of 1-bit errors in a 256 byte block of data.
@@ -10,30 +12,6 @@
* Toshiba America Electronics Components, Inc.
*
* Copyright (C) 2006 Thomas Gleixner <tglx at linutronix.de>
- *
- * This file is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 or (at your option) any
- * later version.
- *
- * This file is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, if other files instantiate templates or use
- * macros or inline functions from these files, or you compile these
- * files and link them with other works to produce a work based on these
- * files, these files do not by themselves cause the resulting work to be
- * covered by the GNU General Public License. However the source code for
- * these files must still be made available in accordance with section (3)
- * of the GNU General Public License.
- *
- * This exception does not invalidate any other reasons why a work based on
- * this file might be covered by the GNU General Public License.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/ecc_kw.c b/src/flash/nand/ecc_kw.c
index fb3481d..cea1a5a 100644
--- a/src/flash/nand/ecc_kw.c
+++ b/src/flash/nand/ecc_kw.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Reed-Solomon ECC handling for the Marvell Kirkwood SOC
* Copyright (C) 2009 Marvell Semiconductor, Inc.
*
* Authors: Lennert Buytenhek <buytenh@wantstofly.org>
* Nicolas Pitre <nico@fluxnic.net>
- *
- * This file is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 or (at your option) any
- * later version.
- *
- * This file is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/fileio.c b/src/flash/nand/fileio.c
index b9c7f79..ca618b3 100644
--- a/src/flash/nand/fileio.c
+++ b/src/flash/nand/fileio.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* Partially based on drivers/mtd/nand_ids.c from Linux. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/fileio.h b/src/flash/nand/fileio.h
index 6a094c2..a8d2524 100644
--- a/src/flash/nand/fileio.h
+++ b/src/flash/nand/fileio.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NAND_FILEIO_H
diff --git a/src/flash/nand/imp.h b/src/flash/nand/imp.h
index c8a4ed9..7b4f38e 100644
--- a/src/flash/nand/imp.h
+++ b/src/flash/nand/imp.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NAND_IMP_H
diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c
index bda7b87..c1af1d7 100644
--- a/src/flash/nand/lpc3180.c
+++ b/src/flash/nand/lpc3180.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
*
* Copyright (C) 2010 richard vegh <vegh.ricsi@gmail.com> *
* Copyright (C) 2010 Oyvind Harboe <oyvind.harboe@zylin.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/lpc3180.h b/src/flash/nand/lpc3180.h
index c02ee5b..519be7e 100644
--- a/src/flash/nand/lpc3180.h
+++ b/src/flash/nand/lpc3180.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NAND_LPC3180_H
diff --git a/src/flash/nand/lpc32xx.c b/src/flash/nand/lpc32xx.c
index 49890c2..2c578d1 100644
--- a/src/flash/nand/lpc32xx.c
+++ b/src/flash/nand/lpc32xx.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -9,19 +11,6 @@
* Based on a combination of the lpc3180 driver and code from *
* uboot-2009.03-lpc32xx by Kevin Wells. *
* Any bugs are mine. --BSt *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/lpc32xx.h b/src/flash/nand/lpc32xx.h
index 12c8f48..f399142 100644
--- a/src/flash/nand/lpc32xx.h
+++ b/src/flash/nand/lpc32xx.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NAND_LPC32XX_H
diff --git a/src/flash/nand/mx3.c b/src/flash/nand/mx3.c
index dc8d619..86e9468 100644
--- a/src/flash/nand/mx3.c
+++ b/src/flash/nand/mx3.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Alexei Babich *
* Rezonans plc., Chelyabinsk, Russia *
* impatt@mail.ru *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/mx3.h b/src/flash/nand/mx3.h
index 00664d8..b272962 100644
--- a/src/flash/nand/mx3.h
+++ b/src/flash/nand/mx3.h
@@ -1,20 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Alexei Babich *
* Rezonans plc., Chelyabinsk, Russia *
* impatt@mail.ru *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NAND_MX3_H
diff --git a/src/flash/nand/mxc.c b/src/flash/nand/mxc.c
index 7aac721..845a3bb 100644
--- a/src/flash/nand/mxc.c
+++ b/src/flash/nand/mxc.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Alexei Babich *
* Rezonans plc., Chelyabinsk, Russia *
@@ -8,19 +10,6 @@
* *
* Copyright (C) 2011 by Erik Ahlen *
* Avalon Innovation, Sweden *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/mxc.h b/src/flash/nand/mxc.h
index a188728..ae2c03a 100644
--- a/src/flash/nand/mxc.h
+++ b/src/flash/nand/mxc.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Alexei Babich *
* Rezonans plc., Chelyabinsk, Russia *
@@ -5,19 +7,6 @@
* *
* Copyright (C) 2011 by Erik Ahlen *
* Avalon Innovation, Sweden *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NAND_MXC_H
diff --git a/src/flash/nand/nonce.c b/src/flash/nand/nonce.c
index 6fda261..bce4ed0 100644
--- a/src/flash/nand/nonce.c
+++ b/src/flash/nand/nonce.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/nuc910.c b/src/flash/nand/nuc910.c
index 9546f2f..d7f69e6 100644
--- a/src/flash/nand/nuc910.c
+++ b/src/flash/nand/nuc910.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/nuc910.h b/src/flash/nand/nuc910.h
index 8877cf6..3d633dc 100644
--- a/src/flash/nand/nuc910.h
+++ b/src/flash/nand/nuc910.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2010 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/orion.c b/src/flash/nand/orion.c
index 69814ec..7b19cbd 100644
--- a/src/flash/nand/orion.c
+++ b/src/flash/nand/orion.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Marvell Semiconductors, Inc. *
* Written by Nicolas Pitre <nico at marvell.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c2410.c b/src/flash/nand/s3c2410.c
index 57b51b4..98268eb 100644
--- a/src/flash/nand/s3c2410.c
+++ b/src/flash/nand/s3c2410.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007, 2008 by Ben Dooks *
* ben@fluff.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c2412.c b/src/flash/nand/s3c2412.c
index 002378a..0eec35f 100644
--- a/src/flash/nand/s3c2412.c
+++ b/src/flash/nand/s3c2412.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007, 2008 by Ben Dooks *
* ben@fluff.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c2440.c b/src/flash/nand/s3c2440.c
index 44670e6..789144c 100644
--- a/src/flash/nand/s3c2440.c
+++ b/src/flash/nand/s3c2440.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007, 2008 by Ben Dooks *
* ben@fluff.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c2443.c b/src/flash/nand/s3c2443.c
index ffd3864..7166702 100644
--- a/src/flash/nand/s3c2443.c
+++ b/src/flash/nand/s3c2443.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007, 2008 by Ben Dooks *
* ben@fluff.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c24xx.c b/src/flash/nand/s3c24xx.c
index c0471ed..5c2f2bc 100644
--- a/src/flash/nand/s3c24xx.c
+++ b/src/flash/nand/s3c24xx.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007, 2008 by Ben Dooks *
* ben@fluff.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c24xx.h b/src/flash/nand/s3c24xx.h
index 4b0c02f..6b196a1 100644
--- a/src/flash/nand/s3c24xx.h
+++ b/src/flash/nand/s3c24xx.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007, 2008 by Ben Dooks *
* ben@fluff.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NAND_S3C24XX_H
diff --git a/src/flash/nand/s3c24xx_regs.h b/src/flash/nand/s3c24xx_regs.h
index 46bda6b..3960cb3 100644
--- a/src/flash/nand/s3c24xx_regs.h
+++ b/src/flash/nand/s3c24xx_regs.h
@@ -1,19 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
/***************************************************************************
* Copyright (C) 2004, 2005 by Simtec Electronics *
* linux@simtec.co.uk *
* http://www.simtec.co.uk/products/SWLINUX/ *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; version 2 of the License. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c6400.c b/src/flash/nand/s3c6400.c
index 7058133..aebe044 100644
--- a/src/flash/nand/s3c6400.c
+++ b/src/flash/nand/s3c6400.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Peter Korsgaard <jacmet@sunsite.dk> *
* Heavily based on s3c2412.c by Ben Dooks <ben@fluff.org> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/tcl.c b/src/flash/nand/tcl.c
index b796fb7..4bb15fa 100644
--- a/src/flash/nand/tcl.c
+++ b/src/flash/nand/tcl.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* Partially based on drivers/mtd/nand_ids.c from Linux. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index a5ef422..f04f0d2 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libocdflashnor.la
%C%_libocdflashnor_la_SOURCES = \
%D%/core.c \
@@ -54,6 +56,7 @@ NOR_DRIVERS = \
%D%/psoc6.c \
%D%/renesas_rpchf.c \
%D%/rp2040.c \
+ %D%/rsl10.c \
%D%/sfdp.c \
%D%/sh_qspi.c \
%D%/sim3x.c \
diff --git a/src/flash/nor/aduc702x.c b/src/flash/nor/aduc702x.c
index 492b658..ea7f5e3 100644
--- a/src/flash/nor/aduc702x.c
+++ b/src/flash/nor/aduc702x.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 by Kevin McGuire *
* Copyright (C) 2008 by Marcel Wijlaars *
* Copyright (C) 2009 by Michael Ashton *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/aducm360.c b/src/flash/nor/aducm360.c
index 4e816fd..ce9bf24 100644
--- a/src/flash/nor/aducm360.c
+++ b/src/flash/nor/aducm360.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by Ivan Buliev *
* i.buliev@mikrosistemi.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/***************************************************************************
diff --git a/src/flash/nor/ambiqmicro.c b/src/flash/nor/ambiqmicro.c
index 6eda928..2b458bc 100644
--- a/src/flash/nor/ambiqmicro.c
+++ b/src/flash/nor/ambiqmicro.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: BSD-3-Clause
+
/******************************************************************************
*
* @file ambiqmicro.c
@@ -14,33 +16,6 @@
* Copyright (c) 2015-2016, Ambiq Micro, Inc.
*
* All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
*****************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c
index cec86fc..fb6d98b 100644
--- a/src/flash/nor/at91sam3.c
+++ b/src/flash/nor/at91sam3.c
@@ -1,59 +1,17 @@
-/***************************************************************************
- * Copyright (C) 2009 by Duane Ellis *
- * openocd@duaneellis.com *
- * *
- * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) *
- * olaf@uni-paderborn.de *
- * *
- * Copyright (C) 2011 by Olivier Schonken (at91sam3x* support) * *
- * and Jim Norris *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
-****************************************************************************/
-
-/* Some of the lower level code was based on code supplied by
- * ATMEL under this copyright. */
-
-/* BEGIN ATMEL COPYRIGHT */
-/* ----------------------------------------------------------------------------
- * ATMEL Microcontroller Software Support
- * ----------------------------------------------------------------------------
- * Copyright (c) 2009, Atmel Corporation
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the disclaimer below.
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code)
+
+/*
+ * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com>
*
- * Atmel's name may not be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * at91sam3s* support
+ * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de>
+ * Copyright (C) 2011 by Olivier Schonken and Jim Norris
*
- * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * ----------------------------------------------------------------------------
+ * Some of the lower level code was based on code supplied by
+ * ATMEL under BSD-Source-Code License and this copyright.
+ * ATMEL Microcontroller Software Support
+ * Copyright (c) 2009, Atmel Corporation. All rights reserved.
*/
-/* END ATMEL COPYRIGHT */
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c
index 4ec2ee8..6b94373 100644
--- a/src/flash/nor/at91sam4.c
+++ b/src/flash/nor/at91sam4.c
@@ -1,60 +1,19 @@
-/***************************************************************************
- * Copyright (C) 2009 by Duane Ellis *
- * openocd@duaneellis.com *
- * *
- * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) *
- * olaf@uni-paderborn.de *
- * *
- * Copyright (C) 2011 by Olivier Schonken, Jim Norris *
- * (at91sam3x* & at91sam4 support)* *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
-****************************************************************************/
-
-/* Some of the lower level code was based on code supplied by
- * ATMEL under this copyright. */
-
-/* BEGIN ATMEL COPYRIGHT */
-/* ----------------------------------------------------------------------------
- * ATMEL Microcontroller Software Support
- * ----------------------------------------------------------------------------
- * Copyright (c) 2009, Atmel Corporation
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code)
+
+/*
+ * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com>
*
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the disclaimer below.
+ * at91sam3s* support
+ * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de>
*
- * Atmel's name may not be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * at91sam3x* & at91sam4 support
+ * Copyright (C) 2011 by Olivier Schonken, Jim Norris
*
- * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * ----------------------------------------------------------------------------
+ * Some of the lower level code was based on code supplied by
+ * ATMEL under BSD-Source-Code License and this copyright.
+ * ATMEL Microcontroller Software Support
+ * Copyright (c) 2009, Atmel Corporation. All rights reserved.
*/
-/* END ATMEL COPYRIGHT */
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/flash/nor/at91sam4l.c b/src/flash/nor/at91sam4l.c
index 77dc07f..ddf42a8 100644
--- a/src/flash/nor/at91sam4l.c
+++ b/src/flash/nor/at91sam4l.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Andrey Yurovsky *
* Andrey Yurovsky <yurovsky@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/at91sam7.c b/src/flash/nor/at91sam7.c
index f98d186..8d8cf22 100644
--- a/src/flash/nor/at91sam7.c
+++ b/src/flash/nor/at91sam7.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Magnus Lundin *
* lundin@mlu.mine.nu *
* *
* Copyright (C) 2008 by Gheorghe Guran (atlas) *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************/
/***************************************************************************
@@ -587,8 +576,6 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
t_bank->bank_number = bnk;
t_bank->base = base_address + bnk * bank_size;
t_bank->size = bank_size;
- t_bank->chip_width = 0;
- t_bank->bus_width = 4;
t_bank->num_sectors = sectors_num;
/* allocate sectors */
@@ -702,8 +689,6 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
uint32_t bank_size;
uint32_t ext_freq = 0;
- unsigned int chip_width;
- unsigned int bus_width;
unsigned int banks_num;
unsigned int num_sectors;
@@ -727,9 +712,6 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], base_address);
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[3], chip_width);
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[4], bus_width);
-
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[8], banks_num);
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[9], num_sectors);
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[10], pages_per_sector);
@@ -743,7 +725,7 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
at91sam7_info->ext_freq = ext_freq;
}
- if ((bus_width == 0) || (banks_num == 0) || (num_sectors == 0) ||
+ if ((banks_num == 0) || (num_sectors == 0) ||
(pages_per_sector == 0) || (page_size == 0) || (num_nvmbits == 0)) {
at91sam7_info->flash_autodetection = 1;
return ERROR_OK;
@@ -772,8 +754,6 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
t_bank->bank_number = bnk;
t_bank->base = base_address + bnk * bank_size;
t_bank->size = bank_size;
- t_bank->chip_width = chip_width;
- t_bank->bus_width = bus_width;
t_bank->num_sectors = num_sectors;
/* allocate sectors */
diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c
index 5f314d8..a0252a2 100644
--- a/src/flash/nor/at91samd.c
+++ b/src/flash/nor/at91samd.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Andrey Yurovsky *
* Andrey Yurovsky <yurovsky@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/ath79.c b/src/flash/nor/ath79.c
index 394b6dd..1d1ec02 100644
--- a/src/flash/nor/ath79.c
+++ b/src/flash/nor/ath79.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by Tobias Diedrich *
* <ranma+openwrt@tdiedrich.de> *
@@ -5,20 +7,6 @@
* based on the stmsmi code written by Antonio Borneo *
* <borneo.antonio@gmail.com> *
* *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc. *
- * *
***************************************************************************/
/*
* Driver for the Atheros AR7xxx/AR9xxx SPI flash interface.
diff --git a/src/flash/nor/atsame5.c b/src/flash/nor/atsame5.c
index fbf0fb2..fdd610f 100644
--- a/src/flash/nor/atsame5.c
+++ b/src/flash/nor/atsame5.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by Tomas Vanek *
* vanekt@fbl.cz *
@@ -5,19 +7,6 @@
* Based on at91samd.c *
* Copyright (C) 2013 by Andrey Yurovsky *
* Andrey Yurovsky <yurovsky@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/atsamv.c b/src/flash/nor/atsamv.c
index efc2423..67533fc 100644
--- a/src/flash/nor/atsamv.c
+++ b/src/flash/nor/atsamv.c
@@ -1,63 +1,22 @@
-/***************************************************************************
- * Copyright (C) 2009 by Duane Ellis *
- * openocd@duaneellis.com *
- * *
- * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) *
- * olaf@uni-paderborn.de *
- * *
- * Copyright (C) 2011 by Olivier Schonken, Jim Norris *
- * (at91sam3x* & at91sam4 support)* *
- * *
- * Copyright (C) 2015 Morgan Quigley *
- * (atsamv, atsams, and atsame support) *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-/* Some of the lower level code was based on code supplied by
- * ATMEL under this copyright. */
-
-/* BEGIN ATMEL COPYRIGHT */
-/* ----------------------------------------------------------------------------
- * ATMEL Microcontroller Software Support
- * ----------------------------------------------------------------------------
- * Copyright (c) 2009, Atmel Corporation
- *
- * All rights reserved.
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code)
+
+/*
+ * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com>
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
+ * at91sam3s* support
+ * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de>
*
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the disclaimer below.
+ * at91sam3x* & at91sam4 support
+ * Copyright (C) 2011 by Olivier Schonken and Jim Norris
*
- * Atmel's name may not be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * atsamv, atsams, and atsame support
+ * Copyright (C) 2015 Morgan Quigley
*
- * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * ----------------------------------------------------------------------------
+ * Some of the lower level code was based on code supplied by
+ * ATMEL under BSD-Source-Code License and this copyright.
+ * ATMEL Microcontroller Software Support
+ * Copyright (c) 2009, Atmel Corporation. All rights reserved.
*/
-/* END ATMEL COPYRIGHT */
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c
index 634f739..0e2e263 100644
--- a/src/flash/nor/avrf.c
+++ b/src/flash/nor/avrf.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Simon Qian *
* SimonQian@SimonQian.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/bluenrg-x.c b/src/flash/nor/bluenrg-x.c
index 16075ec..9ced2e9 100644
--- a/src/flash/nor/bluenrg-x.c
+++ b/src/flash/nor/bluenrg-x.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by Michele Sardo *
* msmttchr@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -247,7 +236,7 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
struct target *target = bank->target;
uint32_t buffer_size = 16384 + 8;
struct working_area *write_algorithm;
- struct working_area *write_algorithm_sp;
+ struct working_area *write_algorithm_stack;
struct working_area *source;
uint32_t address = bank->base + offset;
struct reg_param reg_params[5];
@@ -296,10 +285,10 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- /* Stack pointer area */
+ /* Stack area */
if (target_alloc_working_area(target, 128,
- &write_algorithm_sp) != ERROR_OK) {
- LOG_DEBUG("no working area for write code stack pointer");
+ &write_algorithm_stack) != ERROR_OK) {
+ LOG_DEBUG("no working area for target algorithm stack");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
@@ -311,8 +300,19 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
init_reg_param(&reg_params[4], "sp", 32, PARAM_OUT);
- /* Put the parameter at the first available stack location */
- init_mem_param(&mem_params[0], write_algorithm_sp->address + 80, 32, PARAM_OUT);
+ /* Put the 4th parameter at the location in the stack frame of target write() function.
+ * See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.lst
+ * 34 ldr r6, [sp, #80]
+ * ^^^ offset
+ */
+ init_mem_param(&mem_params[0], write_algorithm_stack->address + 80, 32, PARAM_OUT);
+ /* Stack for target write algorithm - target write() function has
+ * __attribute__((naked)) so it does not setup the new stack frame.
+ * Therefore the stack frame uses the area from SP upwards!
+ * Interrupts are disabled and no subroutines are called from write()
+ * so no need to allocate stack below SP.
+ * TODO: remove __attribute__((naked)) and use similar parameter passing as stm32l4x */
+ buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_stack->address);
/* FIFO start address (first two words used for write and read pointers) */
buf_set_u32(reg_params[0].value, 0, 32, source->address);
@@ -322,14 +322,12 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
buf_set_u32(reg_params[2].value, 0, 32, address);
/* Number of bytes */
buf_set_u32(reg_params[3].value, 0, 32, count);
- /* Stack pointer for program working area */
- buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_sp->address);
/* Flash register base address */
buf_set_u32(mem_params[0].value, 0, 32, bluenrgx_info->flash_ptr->flash_regs_base);
LOG_DEBUG("source->address = " TARGET_ADDR_FMT, source->address);
LOG_DEBUG("source->address+ source->size = " TARGET_ADDR_FMT, source->address+source->size);
- LOG_DEBUG("write_algorithm_sp->address = " TARGET_ADDR_FMT, write_algorithm_sp->address);
+ LOG_DEBUG("write_algorithm_stack->address = " TARGET_ADDR_FMT, write_algorithm_stack->address);
LOG_DEBUG("address = %08" PRIx32, address);
LOG_DEBUG("count = %08" PRIx32, count);
@@ -368,7 +366,7 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
}
target_free_working_area(target, source);
target_free_working_area(target, write_algorithm);
- target_free_working_area(target, write_algorithm_sp);
+ target_free_working_area(target, write_algorithm_stack);
destroy_reg_param(&reg_params[0]);
destroy_reg_param(&reg_params[1]);
diff --git a/src/flash/nor/bluenrg-x.h b/src/flash/nor/bluenrg-x.h
index 3b84b8b..720cb6e 100644
--- a/src/flash/nor/bluenrg-x.h
+++ b/src/flash/nor/bluenrg-x.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2019 by STMicroelectronics. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_BLUENRGX_H
diff --git a/src/flash/nor/cc26xx.c b/src/flash/nor/cc26xx.c
index 7e52649..6256ba6 100644
--- a/src/flash/nor/cc26xx.c
+++ b/src/flash/nor/cc26xx.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -45,6 +34,16 @@ struct cc26xx_bank {
uint32_t params_addr[2];
};
+/* Flash helper algorithm for CC26x0 Chameleon targets */
+static const uint8_t cc26x0_algo[] = {
+#include "../../../contrib/loaders/flash/cc26xx/cc26x0_algo.inc"
+};
+
+/* Flash helper algorithm for CC26x2 Agama targets */
+static const uint8_t cc26x2_algo[] = {
+#include "../../../contrib/loaders/flash/cc26xx/cc26x2_algo.inc"
+};
+
static int cc26xx_auto_probe(struct flash_bank *bank);
static uint32_t cc26xx_device_type(uint32_t icepick_id, uint32_t user_id)
diff --git a/src/flash/nor/cc26xx.h b/src/flash/nor/cc26xx.h
index 51a09f1..83fc940 100644
--- a/src/flash/nor/cc26xx.h
+++ b/src/flash/nor/cc26xx.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_CC26XX_H
@@ -88,14 +77,4 @@ struct cc26xx_algo_params {
uint8_t status[4];
};
-/* Flash helper algorithm for CC26x0 Chameleon targets */
-const uint8_t cc26x0_algo[] = {
-#include "../../../contrib/loaders/flash/cc26xx/cc26x0_algo.inc"
-};
-
-/* Flash helper algorithm for CC26x2 Agama targets */
-const uint8_t cc26x2_algo[] = {
-#include "../../../contrib/loaders/flash/cc26xx/cc26x2_algo.inc"
-};
-
#endif /* OPENOCD_FLASH_NOR_CC26XX_H */
diff --git a/src/flash/nor/cc3220sf.c b/src/flash/nor/cc3220sf.c
index 723e605..432a393 100644
--- a/src/flash/nor/cc3220sf.c
+++ b/src/flash/nor/cc3220sf.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -33,6 +22,11 @@ struct cc3220sf_bank {
struct armv7m_algorithm armv7m_info;
};
+/* Flash helper algorithm for CC3220SF */
+static const uint8_t cc3220sf_algo[] = {
+#include "../../../contrib/loaders/flash/cc3220sf/cc3220sf.inc"
+};
+
static int cc3220sf_mass_erase(struct flash_bank *bank)
{
struct target *target = bank->target;
diff --git a/src/flash/nor/cc3220sf.h b/src/flash/nor/cc3220sf.h
index 36c17be..eb2a6c6 100644
--- a/src/flash/nor/cc3220sf.h
+++ b/src/flash/nor/cc3220sf.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_CC3220SF_H
@@ -37,9 +26,4 @@
#define FMC_ERASE_VALUE (FMC_DEFAULT_VALUE | FMC_ERASE_BIT)
#define FMC_MERASE_VALUE (FMC_DEFAULT_VALUE | FMC_MERASE_BIT)
-/* Flash helper algorithm for CC3220SF */
-const uint8_t cc3220sf_algo[] = {
-#include "../../../contrib/loaders/flash/cc3220sf/cc3220sf.inc"
-};
-
#endif /* OPENOCD_FLASH_NOR_CC3220SF_H */
diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c
index 8511586..78bc91e 100644
--- a/src/flash/nor/cfi.c
+++ b/src/flash/nor/cfi.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -5,19 +7,6 @@
* michael@schwingen.org *
* Copyright (C) 2010 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/cfi.h b/src/flash/nor/cfi.h
index f8ca290..ec7f474 100644
--- a/src/flash/nor/cfi.h
+++ b/src/flash/nor/cfi.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_CFI_H
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
index f4ff5df..5e6c971 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com> *
@@ -5,19 +7,6 @@
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
* Copyright (C) 2017-2018 Tomas Vanek <vanekt@fbl.cz> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h
index 97a368e..8c26ba0 100644
--- a/src/flash/nor/core.h
+++ b/src/flash/nor/core.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_CORE_H
@@ -31,8 +20,6 @@
struct image;
-#define FLASH_MAX_ERROR_STR (128)
-
/**
* Describes the geometry and status of a single flash sector
* within a flash bank. A single bank typically consists of multiple
diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h
index 7a5be65..931f794 100644
--- a/src/flash/nor/driver.h
+++ b/src/flash/nor/driver.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_DRIVER_H
diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c
index 387fc71..bd3363b 100644
--- a/src/flash/nor/drivers.c
+++ b/src/flash/nor/drivers.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -90,6 +79,7 @@ extern const struct flash_driver w600_flash;
extern const struct flash_driver xcf_flash;
extern const struct flash_driver xmc1xxx_flash;
extern const struct flash_driver xmc4xxx_flash;
+extern const struct flash_driver rsl10_flash;
/**
* The list of built-in flash drivers.
@@ -166,6 +156,7 @@ static const struct flash_driver * const flash_drivers[] = {
&xmc1xxx_flash,
&xmc4xxx_flash,
&w600_flash,
+ &rsl10_flash,
NULL,
};
diff --git a/src/flash/nor/dsp5680xx_flash.c b/src/flash/nor/dsp5680xx_flash.c
index 858b669..b1625f1 100644
--- a/src/flash/nor/dsp5680xx_flash.c
+++ b/src/flash/nor/dsp5680xx_flash.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Rodrigo L. Rosa *
* rodrigorosa.LG@gmail.com *
@@ -6,19 +8,6 @@
* Kevin McGuire *
* Marcel Wijlaars *
* Michael Ashton *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c
index 2c5a502..3a49afc 100644
--- a/src/flash/nor/efm32.c
+++ b/src/flash/nor/efm32.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -16,19 +18,6 @@
* *
* Copyright (C) 2021 Doug Brunner *
* doug.a.brunner@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -1086,8 +1075,8 @@ static int efm32x_probe(struct flash_bank *bank)
LOG_INFO("detected part: %s Gecko, rev %d",
efm32_mcu_info->family_data->name, efm32_mcu_info->prod_rev);
- LOG_INFO("flash size = %dkbytes", efm32_mcu_info->flash_sz_kib);
- LOG_INFO("flash page size = %dbytes", efm32_mcu_info->page_size);
+ LOG_INFO("flash size = %d KiB", efm32_mcu_info->flash_sz_kib);
+ LOG_INFO("flash page size = %d B", efm32_mcu_info->page_size);
assert(efm32_mcu_info->page_size != 0);
diff --git a/src/flash/nor/em357.c b/src/flash/nor/em357.c
index 705c1b3..043494c 100644
--- a/src/flash/nor/em357.c
+++ b/src/flash/nor/em357.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
*
* Copyright (C) 2011 by Erik Botö
* erik.boto@pelagicore.com
- *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -720,7 +709,7 @@ static int em357_probe(struct flash_bank *bank)
em357_info->ppage_size = 4;
- LOG_INFO("flash size = %dkbytes", num_pages*page_size/1024);
+ LOG_INFO("flash size = %d KiB", num_pages*page_size/1024);
free(bank->sectors);
diff --git a/src/flash/nor/esirisc_flash.c b/src/flash/nor/esirisc_flash.c
index 23fd01e..938d0f6 100644
--- a/src/flash/nor/esirisc_flash.c
+++ b/src/flash/nor/esirisc_flash.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* James Zhao <hjz@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/faux.c b/src/flash/nor/faux.c
index 7646e4b..e76dc49 100644
--- a/src/flash/nor/faux.c
+++ b/src/flash/nor/faux.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/fespi.c b/src/flash/nor/fespi.c
index 5474ffa..9191764 100644
--- a/src/flash/nor/fespi.c
+++ b/src/flash/nor/fespi.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
* Modified by Megan Wachs <megan@sifive.com> from the original stmsmi.c *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* The Freedom E SPI controller is a SPI bus controller
@@ -523,6 +512,12 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
}
}
+ struct riscv_info *riscv = riscv_info(target);
+ if (!is_riscv(riscv)) {
+ LOG_ERROR("Unexpected target type");
+ return ERROR_FAIL;
+ }
+
unsigned int xlen = riscv_xlen(target);
struct working_area *algorithm_wa = NULL;
struct working_area *data_wa = NULL;
diff --git a/src/flash/nor/fm3.c b/src/flash/nor/fm3.c
index 831f342..48f4493 100644
--- a/src/flash/nor/fm3.c
+++ b/src/flash/nor/fm3.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Marc Willam, Holger Wech *
* openOCD.fseu(AT)de.fujitsu.com *
@@ -5,19 +7,6 @@
* *
* Copyright (C) 2013 Nemui Trinomius *
* nemuisan_kawausogasuki@live.jp *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/fm4.c b/src/flash/nor/fm4.c
index 09865d2..979ae84 100644
--- a/src/flash/nor/fm4.c
+++ b/src/flash/nor/fm4.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Spansion FM4 flash
*
@@ -686,24 +688,8 @@ FLASH_BANK_COMMAND_HANDLER(fm4_flash_bank_command)
return ret;
}
-static const struct command_registration fm4_exec_command_handlers[] = {
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration fm4_command_handlers[] = {
- {
- .name = "fm4",
- .mode = COMMAND_ANY,
- .help = "fm4 flash command group",
- .usage = "",
- .chain = fm4_exec_command_handlers,
- },
- COMMAND_REGISTRATION_DONE
-};
-
const struct flash_driver fm4_flash = {
.name = "fm4",
- .commands = fm4_command_handlers,
.flash_bank_command = fm4_flash_bank_command,
.info = fm4_get_info_command,
.probe = fm4_probe,
diff --git a/src/flash/nor/imp.h b/src/flash/nor/imp.h
index f66cf03..199d670 100644
--- a/src/flash/nor/imp.h
+++ b/src/flash/nor/imp.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_IMP_H
diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c
index a5672c6..c176ca8 100644
--- a/src/flash/nor/jtagspi.c
+++ b/src/flash/nor/jtagspi.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 Robert Jordens <jordens@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c
index edb4eb5..7137b4a 100644
--- a/src/flash/nor/kinetis.c
+++ b/src/flash/nor/kinetis.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* kesmtp@freenet.de *
@@ -13,19 +15,6 @@
* *
* Copyright (C) 2015 Tomas Vanek *
* vanekt@fbl.cz *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -108,6 +97,8 @@
#define SMC_PMSTAT 0x4007E003
#define SMC32_PMCTRL 0x4007E00C
#define SMC32_PMSTAT 0x4007E014
+#define PMC_REGSC 0x4007D002
+#define MC_PMCTRL 0x4007E003
#define MCM_PLACR 0xF000300C
/* Offsets */
@@ -199,6 +190,9 @@
#define KINETIS_K_SDID_K60_M150 0x000001C0
#define KINETIS_K_SDID_K70_M150 0x000001D0
+#define KINETIS_K_REVID_MASK 0x0000F000
+#define KINETIS_K_REVID_SHIFT 12
+
#define KINETIS_SDID_SERIESID_MASK 0x00F00000
#define KINETIS_SDID_SERIESID_K 0x00000000
#define KINETIS_SDID_SERIESID_KL 0x00100000
@@ -309,6 +303,7 @@ struct kinetis_chip {
enum {
KINETIS_SMC,
KINETIS_SMC32,
+ KINETIS_MC,
} sysmodectrlr_type;
char name[40];
@@ -402,16 +397,23 @@ static int kinetis_auto_probe(struct flash_bank *bank);
static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
{
- int retval;
LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value);
- retval = dap_queue_ap_write(dap_ap(dap, MDM_AP), reg, value);
+ struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);
+ if (!ap) {
+ LOG_DEBUG("MDM: failed to get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_queue_ap_write(ap, reg, value);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a write request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed");
return retval;
@@ -423,15 +425,21 @@ static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint3
static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
{
- int retval;
+ struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);
+ if (!ap) {
+ LOG_DEBUG("MDM: failed to get AP");
+ return ERROR_FAIL;
+ }
- retval = dap_queue_ap_read(dap_ap(dap, MDM_AP), reg, result);
+ int retval = dap_queue_ap_read(ap, reg, result);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a read request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed");
return retval;
@@ -787,12 +795,18 @@ COMMAND_HANDLER(kinetis_check_flash_security_status)
if ((val & (MDM_STAT_SYSSEC | MDM_STAT_FREADY)) != MDM_STAT_FREADY) {
uint32_t stats[32];
+ struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);
+ if (!ap) {
+ LOG_ERROR("MDM: failed to get AP");
+ return ERROR_OK;
+ }
for (unsigned int i = 0; i < 32; i++) {
stats[i] = MDM_STAT_FREADY;
- dap_queue_ap_read(dap_ap(dap, MDM_AP), MDM_REG_STAT, &stats[i]);
+ dap_queue_ap_read(ap, MDM_REG_STAT, &stats[i]);
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed when validating secured state");
return ERROR_OK;
@@ -934,7 +948,7 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
unsigned num_blocks;
struct kinetis_flash_bank *k_bank;
struct flash_bank *bank;
- char base_name[69], name[80], num[4];
+ char base_name[69], name[87], num[11];
char *class, *p;
num_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks;
@@ -1529,6 +1543,17 @@ static int kinetis_read_pmstat(struct kinetis_chip *k_chip, uint8_t *pmstat)
if (result == ERROR_OK)
*pmstat = stat32 & 0xff;
return result;
+
+ case KINETIS_MC:
+ /* emulate SMC by reading PMC_REGSC bit 3 (VLPRS) */
+ result = target_read_u8(target, PMC_REGSC, pmstat);
+ if (result == ERROR_OK) {
+ if (*pmstat & 0x08)
+ *pmstat = PM_STAT_VLPR;
+ else
+ *pmstat = PM_STAT_RUN;
+ }
+ return result;
}
return ERROR_FAIL;
}
@@ -1569,6 +1594,10 @@ static int kinetis_check_run_mode(struct kinetis_chip *k_chip)
case KINETIS_SMC32:
result = target_write_u32(target, SMC32_PMCTRL, PM_CTRL_RUNM_RUN);
break;
+
+ case KINETIS_MC:
+ result = target_write_u32(target, MC_PMCTRL, PM_CTRL_RUNM_RUN);
+ break;
}
if (result != ERROR_OK)
return result;
@@ -2135,6 +2164,24 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
}
}
+ /* first revision of some devices has no SMC */
+ switch (mcu_type) {
+ case KINETIS_K_SDID_K10_M100:
+ case KINETIS_K_SDID_K20_M100:
+ case KINETIS_K_SDID_K30_M100:
+ case KINETIS_K_SDID_K40_M100:
+ case KINETIS_K_SDID_K60_M100:
+ {
+ uint32_t revid = (k_chip->sim_sdid & KINETIS_K_REVID_MASK) >> KINETIS_K_REVID_SHIFT;
+ /* highest bit set corresponds to rev 2.x */
+ if (revid <= 7) {
+ k_chip->sysmodectrlr_type = KINETIS_MC;
+ strcat(name, " Rev 1.x");
+ }
+ }
+ break;
+ }
+
} else {
/* Newer K-series or KL series MCU */
familyid = (k_chip->sim_sdid & KINETIS_SDID_FAMILYID_MASK) >> KINETIS_SDID_FAMILYID_SHIFT;
@@ -2615,12 +2662,12 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
snprintf(k_chip->name, sizeof(k_chip->name), name, flash_marking);
LOG_INFO("Kinetis %s detected: %u flash blocks", k_chip->name, num_blocks);
- LOG_INFO("%u PFlash banks: %" PRIu32 "k total", k_chip->num_pflash_blocks, pflash_size_k);
+ LOG_INFO("%u PFlash banks: %" PRIu32 " KiB total", k_chip->num_pflash_blocks, pflash_size_k);
if (k_chip->num_nvm_blocks) {
nvm_size_k = k_chip->nvm_size / 1024;
dflash_size_k = k_chip->dflash_size / 1024;
- LOG_INFO("%u FlexNVM banks: %" PRIu32 "k total, %" PRIu32 "k available as data flash, %" PRIu32 "bytes FlexRAM",
- k_chip->num_nvm_blocks, nvm_size_k, dflash_size_k, ee_size);
+ LOG_INFO("%u FlexNVM banks: %" PRIu32 " KiB total, %" PRIu32 " KiB available as data flash, %"
+ PRIu32 " bytes FlexRAM", k_chip->num_nvm_blocks, nvm_size_k, dflash_size_k, ee_size);
}
k_chip->probed = true;
diff --git a/src/flash/nor/kinetis_ke.c b/src/flash/nor/kinetis_ke.c
index 48749e6..c069f3a 100644
--- a/src/flash/nor/kinetis_ke.c
+++ b/src/flash/nor/kinetis_ke.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by Ivan Meleca *
* ivan@artekit.eu *
@@ -18,19 +20,6 @@
* *
* Copyright (C) 2015 Tomas Vanek *
* vanekt@fbl.cz *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -147,16 +136,23 @@ struct kinetis_ke_flash_bank {
static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
{
- int retval;
LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value);
- retval = dap_queue_ap_write(dap_ap(dap, 1), reg, value);
+ struct adiv5_ap *ap = dap_get_ap(dap, 1);
+ if (!ap) {
+ LOG_DEBUG("MDM: failed to get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_queue_ap_write(ap, reg, value);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a write request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed");
return retval;
@@ -167,14 +163,21 @@ static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, ui
static int kinetis_ke_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
{
- int retval;
- retval = dap_queue_ap_read(dap_ap(dap, 1), reg, result);
+ struct adiv5_ap *ap = dap_get_ap(dap, 1);
+ if (!ap) {
+ LOG_DEBUG("MDM: failed to get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_queue_ap_read(ap, reg, result);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a read request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed");
return retval;
diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c
index 465199d..f12eef7 100644
--- a/src/flash/nor/lpc2000.c
+++ b/src/flash/nor/lpc2000.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -14,19 +16,6 @@
* *
* LPC8N04/HNS31xx support Copyright (C) 2018 *
* by Jean-Christian de Rivaz jcdr [at] innodelec [dot] ch *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/lpc288x.c b/src/flash/nor/lpc288x.c
index 1c10e50..3006db1 100644
--- a/src/flash/nor/lpc288x.c
+++ b/src/flash/nor/lpc288x.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 by *
* Karl RobinSod <karl.robinsod@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/***************************************************************************
diff --git a/src/flash/nor/lpc2900.c b/src/flash/nor/lpc2900.c
index 4bf5297..c30fa76 100644
--- a/src/flash/nor/lpc2900.c
+++ b/src/flash/nor/lpc2900.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by *
* Rolf Meeser <rolfm_9dq@yahoo.de> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/lpcspifi.c b/src/flash/nor/lpcspifi.c
index 160e2dc..f950f21 100644
--- a/src/flash/nor/lpcspifi.c
+++ b/src/flash/nor/lpcspifi.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2012 by George Harris *
* george@luminairecoffee.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/max32xxx.c b/src/flash/nor/max32xxx.c
index e7a690d..51d6ae2 100644
--- a/src/flash/nor/max32xxx.c
+++ b/src/flash/nor/max32xxx.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2016 by Maxim Integrated *
* Kevin Gillespie <kevin.gillespie@maximintegrated.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/mdr.c b/src/flash/nor/mdr.c
index f3c8552..f6285de 100644
--- a/src/flash/nor/mdr.c
+++ b/src/flash/nor/mdr.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2013 by Paul Fertser *
* fercerpav@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/mrvlqspi.c b/src/flash/nor/mrvlqspi.c
index a752f09..4eb6522 100644
--- a/src/flash/nor/mrvlqspi.c
+++ b/src/flash/nor/mrvlqspi.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2014 by Mahavir Jain <mjain@marvell.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/flash/nor/msp432.c b/src/flash/nor/msp432.c
index 61741c8..d9b9695 100644
--- a/src/flash/nor/msp432.c
+++ b/src/flash/nor/msp432.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Texas Instruments, Inc. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -56,6 +45,21 @@ struct msp432_bank {
struct armv7m_algorithm armv7m_info;
};
+/* Flash helper algorithm for MSP432P401x targets */
+static const uint8_t msp432p401x_algo[] = {
+#include "../../../contrib/loaders/flash/msp432/msp432p401x_algo.inc"
+};
+
+/* Flash helper algorithm for MSP432P411x targets */
+static const uint8_t msp432p411x_algo[] = {
+#include "../../../contrib/loaders/flash/msp432/msp432p411x_algo.inc"
+};
+
+/* Flash helper algorithm for MSP432E4x targets */
+static const uint8_t msp432e4x_algo[] = {
+#include "../../../contrib/loaders/flash/msp432/msp432e4x_algo.inc"
+};
+
static int msp432_auto_probe(struct flash_bank *bank);
static int msp432_device_type(uint32_t family_type, uint32_t device_id,
diff --git a/src/flash/nor/msp432.h b/src/flash/nor/msp432.h
index af1d40c..d0a62c4 100644
--- a/src/flash/nor/msp432.h
+++ b/src/flash/nor/msp432.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2018 by Texas Instruments, Inc. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_MSP432_H
@@ -112,19 +101,4 @@ struct msp432_algo_params {
uint8_t unlock_bsl[4];
};
-/* Flash helper algorithm for MSP432P401x targets */
-const uint8_t msp432p401x_algo[] = {
-#include "../../../contrib/loaders/flash/msp432/msp432p401x_algo.inc"
-};
-
-/* Flash helper algorithm for MSP432P411x targets */
-const uint8_t msp432p411x_algo[] = {
-#include "../../../contrib/loaders/flash/msp432/msp432p411x_algo.inc"
-};
-
-/* Flash helper algorithm for MSP432E4x targets */
-const uint8_t msp432e4x_algo[] = {
-#include "../../../contrib/loaders/flash/msp432/msp432e4x_algo.inc"
-};
-
#endif /* OPENOCD_FLASH_NOR_MSP432_H */
diff --git a/src/flash/nor/niietcm4.c b/src/flash/nor/niietcm4.c
index 6f9a5d3..0c36e2c 100644
--- a/src/flash/nor/niietcm4.c
+++ b/src/flash/nor/niietcm4.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by Bogdan Kolbov *
* kolbov@niiet.ru *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/non_cfi.c b/src/flash/nor/non_cfi.c
index 1566f38..f096ba6 100644
--- a/src/flash/nor/non_cfi.c
+++ b/src/flash/nor/non_cfi.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* Copyright (C) 2009 Michael Schwingen *
* michael@schwingen.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/non_cfi.h b/src/flash/nor/non_cfi.h
index c411cb8..47d7e59 100644
--- a/src/flash/nor/non_cfi.h
+++ b/src/flash/nor/non_cfi.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_NON_CFI_H
diff --git a/src/flash/nor/npcx.c b/src/flash/nor/npcx.c
index a4d6395..bc84753 100644
--- a/src/flash/nor/npcx.c
+++ b/src/flash/nor/npcx.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2020 by Nuvoton Technology Corporation
@@ -17,7 +17,7 @@
#include "../../../contrib/loaders/flash/npcx/npcx_flash.h"
/* NPCX flash loader */
-const uint8_t npcx_algo[] = {
+static const uint8_t npcx_algo[] = {
#include "../../../contrib/loaders/flash/npcx/npcx_algo.inc"
};
diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c
index c964155..d5de4a4 100644
--- a/src/flash/nor/nrf5.c
+++ b/src/flash/nor/nrf5.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Synapse Product Development *
* Andrey Smirnov <andrew.smironv@gmail.com> *
* Angus Gratton <gus@projectgus.com> *
* Erdem U. Altunyurt <spamjunkeater@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -147,7 +136,7 @@ struct nrf5_device_spec {
};
struct nrf5_info {
- uint32_t refcount;
+ unsigned int refcount;
struct nrf5_bank {
struct nrf5_info *chip;
diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c
index 3487508..1a73eb2 100644
--- a/src/flash/nor/numicro.c
+++ b/src/flash/nor/numicro.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by James K. Larson *
* jlarson@pacifier.com *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2015 Nemui Trinomius *
* nemuisan_kawausogasuki@live.jp *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/ocl.c b/src/flash/nor/ocl.c
index 813537d..e00c365 100644
--- a/src/flash/nor/ocl.c
+++ b/src/flash/nor/ocl.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Pavel Chromy *
* chromy@asix.cz *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/ocl.h b/src/flash/nor/ocl.h
index b1fe308..4c86495 100644
--- a/src/flash/nor/ocl.h
+++ b/src/flash/nor/ocl.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Pavel Chromy *
* chromy@asix.cz *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_OCL_H
diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c
index 31433e0..9a1a634 100644
--- a/src/flash/nor/pic32mx.c
+++ b/src/flash/nor/pic32mx.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by John McCarthy *
* jgmcc@magma.ca *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -770,7 +759,7 @@ static int pic32mx_probe(struct flash_bank *bank)
}
}
- LOG_INFO("flash size = %" PRIu32 "kbytes", num_pages / 1024);
+ LOG_INFO("flash size = %" PRIu32 " KiB", num_pages / 1024);
free(bank->sectors);
diff --git a/src/flash/nor/psoc4.c b/src/flash/nor/psoc4.c
index 0a2702a..c935bd5 100644
--- a/src/flash/nor/psoc4.c
+++ b/src/flash/nor/psoc4.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2014 by Tomas Vanek (PSoC 4 support derived from STM32) *
* vanekt@fbl.cz *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -662,8 +651,8 @@ static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer,
if (row_offset)
memset(row_buffer, bank->default_padded_value, row_offset);
- bool save_poll = jtag_poll_get_enabled();
- jtag_poll_set_enabled(false);
+ /* Mask automatic polling triggered by execution of halted events */
+ bool save_poll_mask = jtag_poll_mask();
while (count) {
uint32_t chunk_size = psoc4_info->row_size - row_offset;
@@ -704,7 +693,7 @@ static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer,
}
cleanup:
- jtag_poll_set_enabled(save_poll);
+ jtag_poll_unmask(save_poll_mask);
free(sysrq_buffer);
return retval;
@@ -785,7 +774,7 @@ static int psoc4_probe(struct flash_bank *bank)
num_macros++;
}
- LOG_DEBUG("SPCIF geometry: %" PRIu32 " kb flash, row %" PRIu32 " bytes.",
+ LOG_DEBUG("SPCIF geometry: %" PRIu32 " KiB flash, row %" PRIu32 " bytes.",
flash_size_in_kb, row_size);
/* if the user sets the size manually then ignore the probed value
@@ -799,7 +788,7 @@ static int psoc4_probe(struct flash_bank *bank)
if (num_macros > 1)
snprintf(macros_txt, sizeof(macros_txt), " in %" PRIu32 " macros", num_macros);
- LOG_INFO("flash size = %" PRIu32 " kbytes%s", flash_size_in_kb, macros_txt);
+ LOG_INFO("flash size = %" PRIu32 " KiB%s", flash_size_in_kb, macros_txt);
/* calculate number of pages */
uint32_t num_rows = flash_size_in_kb * 1024 / row_size;
diff --git a/src/flash/nor/psoc5lp.c b/src/flash/nor/psoc5lp.c
index f383213..407efbc 100644
--- a/src/flash/nor/psoc5lp.c
+++ b/src/flash/nor/psoc5lp.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* PSoC 5LP flash driver
*
* Copyright (c) 2016 Andreas Färber
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
@@ -822,24 +811,8 @@ FLASH_BANK_COMMAND_HANDLER(psoc5lp_nvl_flash_bank_command)
return ERROR_OK;
}
-static const struct command_registration psoc5lp_nvl_exec_command_handlers[] = {
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration psoc5lp_nvl_command_handlers[] = {
- {
- .name = "psoc5lp_nvl",
- .mode = COMMAND_ANY,
- .help = "PSoC 5LP NV Latch command group",
- .usage = "",
- .chain = psoc5lp_nvl_exec_command_handlers,
- },
- COMMAND_REGISTRATION_DONE
-};
-
const struct flash_driver psoc5lp_nvl_flash = {
.name = "psoc5lp_nvl",
- .commands = psoc5lp_nvl_command_handlers,
.flash_bank_command = psoc5lp_nvl_flash_bank_command,
.info = psoc5lp_nvl_get_info_command,
.probe = psoc5lp_nvl_probe,
@@ -1021,24 +994,8 @@ FLASH_BANK_COMMAND_HANDLER(psoc5lp_eeprom_flash_bank_command)
return ERROR_OK;
}
-static const struct command_registration psoc5lp_eeprom_exec_command_handlers[] = {
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration psoc5lp_eeprom_command_handlers[] = {
- {
- .name = "psoc5lp_eeprom",
- .mode = COMMAND_ANY,
- .help = "PSoC 5LP EEPROM command group",
- .usage = "",
- .chain = psoc5lp_eeprom_exec_command_handlers,
- },
- COMMAND_REGISTRATION_DONE
-};
-
const struct flash_driver psoc5lp_eeprom_flash = {
.name = "psoc5lp_eeprom",
- .commands = psoc5lp_eeprom_command_handlers,
.flash_bank_command = psoc5lp_eeprom_flash_bank_command,
.info = psoc5lp_eeprom_get_info_command,
.probe = psoc5lp_eeprom_probe,
diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c
index c6166af..b7ba102 100644
--- a/src/flash/nor/psoc6.c
+++ b/src/flash/nor/psoc6.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* *
* Copyright (C) 2018 by Bohdan Tymkiv *
* bohdan.tymkiv@cypress.com bohdan200@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -602,8 +591,7 @@ static int psoc6_probe(struct flash_bank *bank)
unsigned int num_sectors = bank_size / row_sz;
bank->size = bank_size;
- bank->chip_width = 4;
- bank->bus_width = 4;
+
bank->erased_value = 0;
bank->default_padded_value = 0;
diff --git a/src/flash/nor/renesas_rpchf.c b/src/flash/nor/renesas_rpchf.c
index f99749f..6c51b8f 100644
--- a/src/flash/nor/renesas_rpchf.c
+++ b/src/flash/nor/renesas_rpchf.c
@@ -1,4 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Renesas RCar Gen3 RPC Hyperflash driver
* Based on U-Boot RPC Hyperflash driver
diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c
index fb34172..667498c 100644
--- a/src/flash/nor/rp2040.c
+++ b/src/flash/nor/rp2040.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/flash/nor/rsl10.c b/src/flash/nor/rsl10.c
new file mode 100644
index 0000000..d92c4b8
--- /dev/null
+++ b/src/flash/nor/rsl10.c
@@ -0,0 +1,843 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * Copyright (C) 2022 by Toms Stūrmanis *
+ * toms.sturmanis@gmail.com *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdint.h>
+
+#include <helper/binarybuffer.h>
+#include <helper/bits.h>
+
+#include <target/algorithm.h>
+#include <target/arm_adi_v5.h>
+#include <target/armv7m.h>
+#include <target/cortex_m.h>
+
+#include "imp.h"
+
+#define RSL10_FLASH_ADDRESS_MAIN 0x00100000
+#define RSL10_FLASH_ADDRESS_NVR1 0x00080000
+#define RSL10_FLASH_ADDRESS_NVR2 0x00080800
+#define RSL10_FLASH_ADDRESS_NVR3 0x00081000
+#define RSL10_FLASH_ADDRESS_NVR4 0x00081800
+#define RSL10_FLASH_ADDRESS_LOCK_INFO_SETTING 0x00081040
+
+#define RSL10_REG_ID 0x1FFFFFFC
+
+#define RSL10_FLASH_REG_MAIN_WRITE_UNLOCK 0x40000504
+#define RSL10_FLASH_REG_MAIN_CTRL 0x40000508
+#define RSL10_FLASH_REG_IF_STATUS 0x40000538
+#define RSL10_FLASH_REG_NVR_WRITE_UNLOCK 0x40000548
+#define RSL10_FLASH_REG_NVR_CTRL 0x4000054C
+
+#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY1 0x400000F0
+#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY2 0x400000F4
+#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY3 0x400000F8
+#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY4 0x400000FC
+
+#define RSL10_NVR3_USER_KEY_OFFSET 0x40
+
+#define RSL10_ID 0x09010106
+#define RSL10_FLASH_KEY_MAIN 0xDBC8264E
+#define RSL10_FLASH_KEY_NVR 0x71B371F5
+#define RSL10_KEY_DEBUG_LOCK 0x4C6F634B
+
+#define RSL10_FLASH_REG_MAIN_CTRL_LOW_W_ENABLE BIT(0)
+#define RSL10_FLASH_REG_MAIN_CTRL_MIDDLE_W_ENABLE BIT(1)
+#define RSL10_FLASH_REG_MAIN_CTRL_HIGH_W_ENABLE BIT(2)
+
+#define RSL10_FLASH_REG_NVR_CTRL_NVR1_W_ENABLE BIT(1)
+#define RSL10_FLASH_REG_NVR_CTRL_NVR2_W_ENABLE BIT(2)
+#define RSL10_FLASH_REG_NVR_CTRL_NVR3_W_ENABLE BIT(3)
+
+#define RSL10_FLASH_REG_STATUS_LOW_W_UNLOCKED BIT(0)
+#define RSL10_FLASH_REG_STATUS_MIDDLE_W_UNLOCKED BIT(1)
+#define RSL10_FLASH_REG_STATUS_HIGH_W_UNLOCKED BIT(2)
+#define RSL10_FLASH_REG_STATUS_NVR1_W_UNLOCKED BIT(4)
+#define RSL10_FLASH_REG_STATUS_NVR2_W_UNLOCKED BIT(5)
+#define RSL10_FLASH_REG_STATUS_NVR3_W_UNLOCKED BIT(6)
+
+#define RSL10_ROM_CMD_WRITE_WORD_PAIR 0x3C
+#define RSL10_ROM_CMD_WRITE_BUFFER 0x40
+#define RSL10_ROM_CMD_ERASE_SECTOR 0x44
+#define RSL10_ROM_CMD_ERASE_ALL 0x48
+
+#define FLASH_SECTOR_SIZE 0x2000
+
+#define RSL10_ROM_CMD_WRITE_BUFFER_MAX_SIZE FLASH_SECTOR_SIZE
+
+#define ALGO_STACK_POINTER_ADDR 0x20002000
+
+/* Used to launch flash related functions from ROM
+ * Params :
+ * r0-r2 = arguments
+ * r3 = target address in rom
+ */
+static const uint8_t rsl10_rom_launcher_code[] = {
+#include "../../../contrib/loaders/flash/rsl10/rom_launcher.inc"
+};
+
+enum rsl10_flash_status {
+ RSL10_FLASH_ERR_NONE = 0x0,
+ RSL10_FLASH_ERR_GENERAL_FAILURE = 0x1,
+ RSL10_FLASH_ERR_WRITE_NOT_ENABLED = 0x2,
+ RSL10_FLASH_ERR_BAD_ADDRESS = 0x3,
+ RSL10_FLASH_ERR_ERASE_FAILED = 0x4,
+ RSL10_FLASH_ERR_BAD_LENGTH = 0x5,
+ RSL10_FLASH_ERR_INACCESSIBLE = 0x6,
+ RSL10_FLASH_ERR_COPIER_BUSY = 0x7,
+ RSL10_FLASH_ERR_PROG_FAILED = 0x8,
+ RSL10_FLASH_MAX_ERR_CODES /* must be the last one */
+};
+
+static const char *const rsl10_error_list[] = {
+ [RSL10_FLASH_ERR_GENERAL_FAILURE] = "general failure",
+ [RSL10_FLASH_ERR_WRITE_NOT_ENABLED] = "write not enabled, protected",
+ [RSL10_FLASH_ERR_BAD_ADDRESS] = "bad address",
+ [RSL10_FLASH_ERR_ERASE_FAILED] = "erase failed",
+ [RSL10_FLASH_ERR_BAD_LENGTH] = "bad length",
+ [RSL10_FLASH_ERR_INACCESSIBLE] = "inaccessible: not powered up, or isolated",
+ [RSL10_FLASH_ERR_COPIER_BUSY] = "copier busy",
+ [RSL10_FLASH_ERR_PROG_FAILED] = "prog failed",
+};
+
+const char *rsl10_error(enum rsl10_flash_status x)
+{
+ if (x >= RSL10_FLASH_MAX_ERR_CODES || !rsl10_error_list[x])
+ return "unknown";
+ return rsl10_error_list[x];
+}
+
+const struct flash_driver rsl10_flash;
+
+struct rsl10_info {
+ unsigned int refcount;
+
+ struct rsl10_bank {
+ struct rsl10_info *chip;
+ bool probed;
+ } bank[5];
+ struct target *target;
+
+ unsigned int flash_size_kb;
+};
+
+static bool rsl10_bank_is_probed(const struct flash_bank *bank)
+{
+ struct rsl10_bank *nbank = bank->driver_priv;
+ assert(nbank);
+ return nbank->probed;
+}
+
+static int rsl10_probe(struct flash_bank *bank);
+
+static int rsl10_get_probed_chip_if_halted(struct flash_bank *bank, struct rsl10_info **chip)
+{
+ if (bank->target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ struct rsl10_bank *nbank = bank->driver_priv;
+ *chip = nbank->chip;
+
+ if (rsl10_bank_is_probed(bank))
+ return ERROR_OK;
+
+ return rsl10_probe(bank);
+}
+
+static int rsl10_protect_check(struct flash_bank *bank)
+{
+ struct rsl10_bank *nbank = bank->driver_priv;
+ struct rsl10_info *chip = nbank->chip;
+
+ assert(chip);
+
+ uint32_t status;
+
+ int retval = target_read_u32(bank->target, RSL10_FLASH_REG_IF_STATUS, &status);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (bank->base == RSL10_FLASH_ADDRESS_MAIN) {
+ for (unsigned int i = 0; i < bank->num_prot_blocks; i++)
+ bank->prot_blocks[i].is_protected = (status & (1 << i)) ? 0 : 1;
+
+ } else {
+ uint32_t test_bit = 0;
+ switch (bank->base) {
+ case RSL10_FLASH_ADDRESS_NVR1:
+ test_bit = RSL10_FLASH_REG_STATUS_NVR1_W_UNLOCKED;
+ break;
+ case RSL10_FLASH_ADDRESS_NVR2:
+ test_bit = RSL10_FLASH_REG_STATUS_NVR2_W_UNLOCKED;
+ break;
+ case RSL10_FLASH_ADDRESS_NVR3:
+ test_bit = RSL10_FLASH_REG_STATUS_NVR3_W_UNLOCKED;
+ break;
+ default:
+ break;
+ }
+
+ bank->sectors[0].is_protected = (status & test_bit) ? 0 : 1;
+ }
+ return ERROR_OK;
+}
+
+static int rsl10_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
+{
+
+ struct rsl10_info *chip;
+ int retval = rsl10_get_probed_chip_if_halted(bank, &chip);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (bank->base == RSL10_FLASH_ADDRESS_MAIN) {
+ uint32_t status;
+ retval = target_read_u32(bank->target, RSL10_FLASH_REG_MAIN_CTRL, &status);
+ if (retval != ERROR_OK)
+ return retval;
+
+ for (unsigned int i = first; i <= last; i++) {
+ if (set)
+ status &= ~(1 << i);
+ else
+ status |= (1 << i);
+ }
+
+ retval = target_write_u32(bank->target, RSL10_FLASH_REG_MAIN_CTRL, status);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(bank->target, RSL10_FLASH_REG_MAIN_WRITE_UNLOCK, RSL10_FLASH_KEY_MAIN);
+ if (retval != ERROR_OK)
+ return retval;
+ } else {
+ uint32_t bit = 0;
+ switch (bank->base) {
+ case RSL10_FLASH_ADDRESS_NVR1:
+ bit = RSL10_FLASH_REG_NVR_CTRL_NVR1_W_ENABLE;
+ break;
+ case RSL10_FLASH_ADDRESS_NVR2:
+ bit = RSL10_FLASH_REG_NVR_CTRL_NVR2_W_ENABLE;
+ break;
+ case RSL10_FLASH_ADDRESS_NVR3:
+ bit = RSL10_FLASH_REG_NVR_CTRL_NVR3_W_ENABLE;
+ break;
+ default:
+ break;
+ }
+
+ uint32_t status;
+ retval = target_read_u32(bank->target, RSL10_FLASH_REG_NVR_CTRL, &status);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (set)
+ status &= ~bit;
+ else
+ status |= bit;
+
+ retval = target_write_u32(bank->target, RSL10_FLASH_REG_NVR_CTRL, status);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(bank->target, RSL10_FLASH_REG_NVR_WRITE_UNLOCK, RSL10_FLASH_KEY_NVR);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ return ERROR_OK;
+}
+
+static int rsl10_check_device(struct flash_bank *bank)
+{
+ uint32_t configid;
+ int retval = target_read_u32(bank->target, RSL10_REG_ID, &configid);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (configid != RSL10_ID) {
+ LOG_ERROR("This is not supported (RSL10) device, use other flash driver!!!");
+ return ERROR_TARGET_INVALID;
+ }
+ return ERROR_OK;
+}
+
+static int rsl10_probe(struct flash_bank *bank)
+{
+ struct rsl10_bank *nbank = bank->driver_priv;
+ struct rsl10_info *chip = nbank->chip;
+
+ int retval = rsl10_check_device(bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ unsigned int bank_id;
+ unsigned int num_prot_blocks = 0;
+ switch (bank->base) {
+ case RSL10_FLASH_ADDRESS_MAIN:
+ bank_id = 0;
+ num_prot_blocks = 3;
+ break;
+ case RSL10_FLASH_ADDRESS_NVR1:
+ bank_id = 1;
+ break;
+ case RSL10_FLASH_ADDRESS_NVR2:
+ bank_id = 2;
+ break;
+ case RSL10_FLASH_ADDRESS_NVR3:
+ bank_id = 3;
+ break;
+ default:
+ return ERROR_FAIL;
+ }
+
+ uint32_t flash_page_size = 2048;
+
+ bank->write_start_alignment = 8;
+ bank->write_end_alignment = 8;
+
+ bank->num_sectors = bank->size / flash_page_size;
+ chip->flash_size_kb = bank->size / 1024;
+
+ free(bank->sectors);
+ bank->sectors = NULL;
+
+ bank->sectors = alloc_block_array(0, flash_page_size, bank->num_sectors);
+ if (!bank->sectors)
+ return ERROR_FAIL;
+
+ free(bank->prot_blocks);
+ bank->prot_blocks = NULL;
+
+ if (num_prot_blocks > 0) {
+ bank->num_prot_blocks = num_prot_blocks;
+ bank->prot_blocks = alloc_block_array(0, bank->num_sectors / 3 * flash_page_size, bank->num_prot_blocks);
+ if (!bank->prot_blocks)
+ return ERROR_FAIL;
+ }
+
+ chip->bank[bank_id].probed = true;
+ return ERROR_OK;
+}
+
+static int rsl10_auto_probe(struct flash_bank *bank)
+{
+ if (rsl10_bank_is_probed(bank))
+ return ERROR_OK;
+
+ return rsl10_probe(bank);
+}
+
+static int rsl10_ll_flash_erase(struct rsl10_info *chip, uint32_t address)
+{
+ struct target *target = chip->target;
+ struct working_area *write_algorithm;
+
+ LOG_DEBUG("erasing buffer flash address=0x%" PRIx32, address);
+
+ int retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size);
+ return ERROR_FAIL;
+ }
+
+ retval =
+ target_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code);
+ if (retval != ERROR_OK)
+ goto free_algorithm;
+
+ struct reg_param reg_params[3];
+ struct armv7m_algorithm armv7m_info;
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
+
+ init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* address */
+ init_reg_param(&reg_params[1], "r3", 32, PARAM_OUT); /* cmd */
+ init_reg_param(&reg_params[2], "sp", 32, PARAM_OUT); /* stack pointer */
+
+ buf_set_u32(reg_params[0].value, 0, 32, address);
+ uint32_t cmd;
+ retval = target_read_u32(target, RSL10_ROM_CMD_ERASE_SECTOR, &cmd);
+ if (retval != ERROR_OK)
+ goto free_reg_params;
+ buf_set_u32(reg_params[1].value, 0, 32, cmd);
+ buf_set_u32(reg_params[2].value, 0, 32, ALGO_STACK_POINTER_ADDR);
+
+ retval = target_run_algorithm(
+ target, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address,
+ write_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info
+ );
+ if (retval != ERROR_OK)
+ goto free_reg_params;
+
+ int algo_ret = buf_get_u32(reg_params[0].value, 0, 32);
+ if (algo_ret != RSL10_FLASH_ERR_NONE) {
+ LOG_ERROR("RSL10 ERASE ERROR: '%s' (%d)", rsl10_error(algo_ret), algo_ret);
+ retval = ERROR_FLASH_SECTOR_NOT_ERASED;
+ }
+
+free_reg_params:
+ for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)
+ destroy_reg_param(&reg_params[i]);
+
+free_algorithm:
+ target_free_working_area(target, write_algorithm);
+ return retval;
+}
+
+static int rsl10_ll_flash_write(struct rsl10_info *chip, uint32_t address, const uint8_t *buffer, uint32_t bytes)
+{
+ struct target *target = chip->target;
+ struct working_area *write_algorithm;
+
+ if (bytes == 8) {
+ uint32_t data;
+ data = buf_get_u32(buffer, 0, 32);
+ LOG_DEBUG("Writing 0x%" PRIx32 " to flash address=0x%" PRIx32 " bytes=0x%" PRIx32, data, address, bytes);
+ } else
+ LOG_DEBUG("Writing buffer to flash address=0x%" PRIx32 " bytes=0x%" PRIx32, address, bytes);
+
+ /* allocate working area with flash programming code */
+ int retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size);
+ return ERROR_FAIL;
+ }
+
+ retval =
+ target_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code);
+ if (retval != ERROR_OK)
+ goto free_algorithm;
+
+ /* memory buffer, rounded down, to be multiple of 8 */
+ uint32_t buffer_avail = target_get_working_area_avail(target) & ~7;
+ uint32_t buffer_size = MIN(RSL10_ROM_CMD_WRITE_BUFFER_MAX_SIZE, buffer_avail);
+ struct working_area *source;
+ retval = target_alloc_working_area(target, buffer_size, &source);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size);
+ goto free_algorithm;
+ }
+
+ struct reg_param reg_params[5];
+ struct armv7m_algorithm armv7m_info;
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
+
+ init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* start addr, return value */
+ init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* length */
+ init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* data */
+ init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* cmd */
+ init_reg_param(&reg_params[4], "sp", 32, PARAM_OUT); /* stack pointer */
+ buf_set_u32(reg_params[4].value, 0, 32, ALGO_STACK_POINTER_ADDR);
+
+ uint32_t cmd = 0;
+ uint32_t sent_bytes = 0;
+ uint32_t write_address = 0;
+ uint32_t bytes_to_send = 0;
+ uint32_t remaining_bytes = 0;
+
+ retval = target_read_u32(target, RSL10_ROM_CMD_WRITE_BUFFER, &cmd);
+ if (retval != ERROR_OK)
+ goto free_everything;
+
+ while (sent_bytes < bytes) {
+ remaining_bytes = bytes - sent_bytes;
+ bytes_to_send = remaining_bytes >= buffer_size ? buffer_size : remaining_bytes;
+
+ retval = target_write_buffer(target, source->address, bytes_to_send, buffer + sent_bytes);
+ if (retval != ERROR_OK)
+ goto free_everything;
+
+ write_address = address + sent_bytes;
+
+ LOG_DEBUG(
+ "write_address: 0x%" PRIx32 ", words: 0x%" PRIx32 ", source: 0x%" PRIx64 ", cmd: 0x%" PRIx32, write_address,
+ bytes_to_send / 4, source->address, cmd
+ );
+ buf_set_u32(reg_params[0].value, 0, 32, write_address);
+ buf_set_u32(reg_params[1].value, 0, 32, bytes_to_send / 4);
+ buf_set_u32(reg_params[2].value, 0, 32, source->address);
+ buf_set_u32(reg_params[3].value, 0, 32, cmd);
+
+ retval = target_run_algorithm(
+ target, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address,
+ write_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info
+ );
+ if (retval != ERROR_OK)
+ goto free_everything;
+
+ int algo_ret = buf_get_u32(reg_params[0].value, 0, 32);
+ if (algo_ret != RSL10_FLASH_ERR_NONE) {
+ LOG_ERROR("RSL10 WRITE ERROR: '%s' (%d)", rsl10_error(algo_ret), algo_ret);
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ goto free_everything;
+ }
+
+ sent_bytes += bytes_to_send;
+ }
+
+free_everything:
+ target_free_working_area(target, source);
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)
+ destroy_reg_param(&reg_params[i]);
+
+free_algorithm:
+ target_free_working_area(target, write_algorithm);
+
+ return retval;
+}
+
+static int rsl10_mass_erase(struct target *target)
+{
+ struct working_area *write_algorithm;
+
+ int retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size);
+ return ERROR_FAIL;
+ }
+
+ retval =
+ target_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code);
+ if (retval != ERROR_OK)
+ goto free_algorithm;
+
+ struct reg_param reg_params[3];
+ struct armv7m_algorithm armv7m_info;
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
+
+ init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* return value */
+ init_reg_param(&reg_params[1], "r3", 32, PARAM_OUT); /* cmd */
+ init_reg_param(&reg_params[2], "sp", 32, PARAM_OUT); /* stack pointer */
+
+ uint32_t cmd;
+ retval = target_read_u32(target, RSL10_ROM_CMD_ERASE_ALL, &cmd);
+ if (retval != ERROR_OK)
+ goto free_reg_params;
+ buf_set_u32(reg_params[1].value, 0, 32, cmd);
+ buf_set_u32(reg_params[2].value, 0, 32, ALGO_STACK_POINTER_ADDR);
+
+ retval = target_run_algorithm(
+ target, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address,
+ write_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info
+ );
+ if (retval != ERROR_OK)
+ goto free_reg_params;
+
+ int algo_ret = buf_get_u32(reg_params[0].value, 0, 32);
+ if (algo_ret != RSL10_FLASH_ERR_NONE) {
+ LOG_ERROR("RSL10 MASS ERASE ERROR: '%s' (%d)", rsl10_error(algo_ret), algo_ret);
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ }
+
+free_reg_params:
+ for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)
+ destroy_reg_param(&reg_params[i]);
+
+free_algorithm:
+ target_free_working_area(target, write_algorithm);
+ return retval;
+}
+
+static int rsl10_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
+{
+ struct rsl10_info *chip;
+
+ int retval = rsl10_get_probed_chip_if_halted(bank, &chip);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return rsl10_ll_flash_write(chip, bank->base + offset, buffer, count);
+}
+
+static int rsl10_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
+{
+ LOG_INFO("erase bank: %x, %x", first, last);
+ int retval;
+ struct rsl10_info *chip;
+
+ retval = rsl10_get_probed_chip_if_halted(bank, &chip);
+ if (retval != ERROR_OK)
+ return retval;
+
+ for (unsigned int i = first; i <= last; i++) {
+ retval = rsl10_ll_flash_erase(chip, bank->base + i * 0x800);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ return ERROR_OK;
+}
+
+static void rsl10_free_driver_priv(struct flash_bank *bank)
+{
+ struct rsl10_bank *nbank = bank->driver_priv;
+ struct rsl10_info *chip = nbank->chip;
+ if (!chip)
+ return;
+
+ chip->refcount--;
+ if (chip->refcount == 0) {
+ free(chip);
+ bank->driver_priv = NULL;
+ }
+}
+
+static struct rsl10_info *rsl10_get_chip(struct target *target)
+{
+ struct flash_bank *bank_iter;
+
+ /* iterate over rsl10 banks of same target */
+ for (bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) {
+ if (bank_iter->driver != &rsl10_flash)
+ continue;
+
+ if (bank_iter->target != target)
+ continue;
+
+ struct rsl10_bank *nbank = bank_iter->driver_priv;
+ if (!nbank)
+ continue;
+
+ if (nbank->chip)
+ return nbank->chip;
+ }
+ return NULL;
+}
+
+FLASH_BANK_COMMAND_HANDLER(rsl10_flash_bank_command)
+{
+ struct rsl10_info *chip = NULL;
+ struct rsl10_bank *nbank = NULL;
+ LOG_INFO("Creating flash @ " TARGET_ADDR_FMT, bank->base);
+
+ switch (bank->base) {
+ case RSL10_FLASH_ADDRESS_MAIN:
+ case RSL10_FLASH_ADDRESS_NVR1:
+ case RSL10_FLASH_ADDRESS_NVR2:
+ case RSL10_FLASH_ADDRESS_NVR3:
+ case RSL10_FLASH_ADDRESS_NVR4:
+ break;
+ default:
+ LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FAIL;
+ }
+
+ chip = rsl10_get_chip(bank->target);
+ if (!chip) {
+ chip = calloc(1, sizeof(*chip));
+ if (!chip)
+ return ERROR_FAIL;
+
+ chip->target = bank->target;
+ }
+
+ switch (bank->base) {
+ case RSL10_FLASH_ADDRESS_MAIN:
+ nbank = &chip->bank[0];
+ break;
+ case RSL10_FLASH_ADDRESS_NVR1:
+ nbank = &chip->bank[1];
+ break;
+ case RSL10_FLASH_ADDRESS_NVR2:
+ nbank = &chip->bank[2];
+ break;
+ case RSL10_FLASH_ADDRESS_NVR3:
+ nbank = &chip->bank[3];
+ break;
+ case RSL10_FLASH_ADDRESS_NVR4:
+ nbank = &chip->bank[4];
+ break;
+ }
+ assert(nbank);
+
+ chip->refcount++;
+ nbank->chip = chip;
+ nbank->probed = false;
+ bank->driver_priv = nbank;
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(rsl10_lock_command)
+{
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (CMD_ARGC != 4)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct flash_bank *bank;
+ int retval = get_flash_bank_by_addr(target, RSL10_FLASH_ADDRESS_NVR3, true, &bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ LOG_INFO("Keys used: %s %s %s %s", CMD_ARGV[0], CMD_ARGV[1], CMD_ARGV[2], CMD_ARGV[3]);
+
+ uint32_t user_key[4];
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], user_key[0]);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], user_key[1]);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], user_key[2]);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], user_key[3]);
+
+ uint8_t write_buffer[6 * 4];
+ target_buffer_set_u32(target, write_buffer, RSL10_KEY_DEBUG_LOCK);
+ target_buffer_set_u32_array(target, &write_buffer[4], 4, user_key);
+ /* pad the end to 64-bit word boundary */
+ memset(&write_buffer[5 * 4], bank->default_padded_value, 4);
+
+ retval = rsl10_erase(bank, 0, 0);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = rsl10_write(bank, write_buffer, RSL10_NVR3_USER_KEY_OFFSET, sizeof(write_buffer));
+ if (retval != ERROR_OK) {
+ /* erase sector, if write fails, otherwise it can lock debug with wrong keys */
+ return rsl10_erase(bank, 0, 0);
+ }
+
+ command_print(
+ CMD, "****** WARNING ******\n"
+ "rsl10 device has been successfully prepared to lock.\n"
+ "Debug port is locked after restart.\n"
+ "Unlock with 'rsl10_unlock key0 key1 key2 key3'\n"
+ "****** ....... ******\n"
+ );
+
+ return rsl10_protect(bank, true, 0, 0);
+}
+
+COMMAND_HANDLER(rsl10_unlock_command)
+{
+ if (CMD_ARGC != 4)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct target *target = get_current_target(CMD_CTX);
+ struct cortex_m_common *cortex_m = target_to_cm(target);
+
+ struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
+ struct adiv5_ap *ap = dap_get_ap(dap, 0);
+
+ uint32_t user_key[4];
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], user_key[0]);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], user_key[1]);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], user_key[2]);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], user_key[3]);
+
+ uint8_t write_buffer1[4 * 4];
+ target_buffer_set_u32_array(target, write_buffer1, 4, user_key);
+ int retval = mem_ap_write_buf(ap, write_buffer1, 4, 4, RSL10_FLASH_REG_DEBUG_UNLOCK_KEY1);
+ if (retval != ERROR_OK) {
+ dap_put_ap(ap);
+ return retval;
+ }
+
+ dap_put_ap(ap);
+
+ uint32_t key;
+ retval = mem_ap_read_atomic_u32(ap, RSL10_FLASH_ADDRESS_LOCK_INFO_SETTING, &key);
+ if (retval != ERROR_OK)
+ return retval;
+ LOG_INFO("mem read: 0x%08" PRIx32, key);
+
+ if (key == RSL10_KEY_DEBUG_LOCK) {
+ retval = command_run_line(CMD_CTX, "reset init");
+ if (retval != ERROR_OK)
+ return retval;
+
+ struct flash_bank *bank;
+ retval = get_flash_bank_by_addr(target, RSL10_FLASH_ADDRESS_NVR3, true, &bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = rsl10_protect(bank, false, 0, 0);
+ if (retval != ERROR_OK)
+ return retval;
+
+ uint8_t write_buffer2[4 * 2];
+ target_buffer_set_u32(target, write_buffer2, 0x1);
+ /* pad the end to 64-bit word boundary */
+ memset(&write_buffer2[4], bank->default_padded_value, 4);
+
+ /* let it fail, because sector is not erased, maybe just erase all? */
+ (void)rsl10_write(bank, write_buffer2, RSL10_NVR3_USER_KEY_OFFSET, sizeof(write_buffer2));
+ command_print(CMD, "Debug port is unlocked!");
+ }
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(rsl10_mass_erase_command)
+{
+ if (CMD_ARGC)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct target *target = get_current_target(CMD_CTX);
+
+ int retval = rsl10_mass_erase(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ command_print(CMD, "Mass erase was succesfull!");
+ return ERROR_OK;
+}
+
+static const struct command_registration rsl10_exec_command_handlers[] = {
+ {
+ .name = "lock",
+ .handler = rsl10_lock_command,
+ .mode = COMMAND_EXEC,
+ .help = "Lock rsl10 debug, with passed keys",
+ .usage = "key1 key2 key3 key4",
+ },
+ {
+ .name = "unlock",
+ .handler = rsl10_unlock_command,
+ .mode = COMMAND_EXEC,
+ .help = "Unlock rsl10 debug, with passed keys",
+ .usage = "key1 key2 key3 key4",
+ },
+ {
+ .name = "mass_erase",
+ .handler = rsl10_mass_erase_command,
+ .mode = COMMAND_EXEC,
+ .help = "Mass erase all unprotected flash areas",
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE};
+
+static const struct command_registration rsl10_command_handlers[] = {
+ {
+ .name = "rsl10",
+ .mode = COMMAND_ANY,
+ .help = "rsl10 flash command group",
+ .usage = "",
+ .chain = rsl10_exec_command_handlers,
+ },
+ COMMAND_REGISTRATION_DONE};
+
+const struct flash_driver rsl10_flash = {
+ .name = "rsl10",
+ .commands = rsl10_command_handlers,
+ .flash_bank_command = rsl10_flash_bank_command,
+ .erase = rsl10_erase,
+ .protect = rsl10_protect,
+ .write = rsl10_write,
+ .read = default_flash_read,
+ .probe = rsl10_probe,
+ .auto_probe = rsl10_auto_probe,
+ .erase_check = default_flash_blank_check,
+ .protect_check = rsl10_protect_check,
+ .free_driver_priv = rsl10_free_driver_priv,
+};
diff --git a/src/flash/nor/sfdp.c b/src/flash/nor/sfdp.c
index 88d3b96..5bfb541 100644
--- a/src/flash/nor/sfdp.c
+++ b/src/flash/nor/sfdp.c
@@ -1,17 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2019 by Andreas Bolsch <andreas.bolsch@mni.thm.de *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/sfdp.h b/src/flash/nor/sfdp.h
index f924a4e..1c9af32 100644
--- a/src/flash/nor/sfdp.h
+++ b/src/flash/nor/sfdp.h
@@ -1,17 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2019 by Andreas Bolsch <andreas.bolsch@mni.thm.de *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_SFDP_H
diff --git a/src/flash/nor/sh_qspi.c b/src/flash/nor/sh_qspi.c
index 02af17a..e8ca626 100644
--- a/src/flash/nor/sh_qspi.c
+++ b/src/flash/nor/sh_qspi.c
@@ -1,4 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0-only
+
/*
* SH QSPI (Quad SPI) driver
* Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com>
diff --git a/src/flash/nor/sim3x.c b/src/flash/nor/sim3x.c
index 8913838..42550d0 100644
--- a/src/flash/nor/sim3x.c
+++ b/src/flash/nor/sim3x.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2014 by Ladislav Bábel *
* ladababel@seznam.cz *
* *
* Copyright (C) 2015 by Andreas Bomholtz *
* andreas@seluxit.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -872,16 +861,23 @@ static int sim3x_flash_info(struct flash_bank *bank, struct command_invocation *
*/
static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
{
- int retval;
LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32, reg, value);
- retval = dap_queue_ap_write(dap_ap(dap, SIM3X_AP), reg, value);
+ struct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP);
+ if (!ap) {
+ LOG_DEBUG("DAP: failed to get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_queue_ap_write(ap, reg, value);
if (retval != ERROR_OK) {
LOG_DEBUG("DAP: failed to queue a write request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("DAP: dap_run failed");
return retval;
@@ -892,15 +888,21 @@ static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value
static int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
{
- int retval;
+ struct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP);
+ if (!ap) {
+ LOG_DEBUG("DAP: failed to get AP");
+ return ERROR_FAIL;
+ }
- retval = dap_queue_ap_read(dap_ap(dap, SIM3X_AP), reg, result);
+ int retval = dap_queue_ap_read(ap, reg, result);
if (retval != ERROR_OK) {
LOG_DEBUG("DAP: failed to queue a read request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("DAP: dap_run failed");
return retval;
diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c
index 627bb41..b269bd7 100644
--- a/src/flash/nor/spi.c
+++ b/src/flash/nor/spi.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Andreas Bolsch *
* andreas.bolsch@mni.thm.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2010 by Antonio Borneo *
* borneo.antonio@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/spi.h b/src/flash/nor/spi.h
index f8a0a65..807af12 100644
--- a/src/flash/nor/spi.h
+++ b/src/flash/nor/spi.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2018-2019 by Andreas Bolsch *
* andreas.bolsch@mni.thm.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2010 by Antonio Borneo *
* borneo.antonio@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_SPI_H
diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c
index 6135c95..3a78952 100644
--- a/src/flash/nor/stellaris.c
+++ b/src/flash/nor/stellaris.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Magnus Lundin *
* lundin@mlu.mine.nu *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/***************************************************************************
diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c
index b5b10af..292b66d 100644
--- a/src/flash/nor/stm32f1x.c
+++ b/src/flash/nor/stm32f1x.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2011 by Andreas Fritiofson *
* andreas.fritiofson@gmail.com *
- *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -1017,7 +1006,7 @@ static int stm32x_probe(struct flash_bank *bank)
flash_size_in_kb = stm32x_info->user_bank_size / 1024;
}
- LOG_INFO("flash size = %dkbytes", flash_size_in_kb);
+ LOG_INFO("flash size = %d KiB", flash_size_in_kb);
/* did we assign flash size? */
assert(flash_size_in_kb != 0xffff);
diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c
index 622ef34..36b7a0d 100644
--- a/src/flash/nor/stm32f2x.c
+++ b/src/flash/nor/stm32f2x.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2011 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -1136,7 +1125,7 @@ static int stm32x_probe(struct flash_bank *bank)
flash_size_in_kb = stm32x_info->user_bank_size / 1024;
}
- LOG_INFO("flash size = %" PRIu16 " kbytes", flash_size_in_kb);
+ LOG_INFO("flash size = %" PRIu16 " KiB", flash_size_in_kb);
/* did we assign flash size? */
assert(flash_size_in_kb != 0xffff);
diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c
index d2914eb..8be8037 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by STMicroelectronics *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index 0a9d59c..7a6ec3f 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by Uwe Bonnes *
* bon@elektron.ikp.physik.tu-darmstadt.de *
* *
* Copyright (C) 2019 by Tarek Bochkati for STMicroelectronics *
* tarek.bouchkati@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -300,7 +289,7 @@ static const struct stm32l4_rev stm32l45_l46xx_revs[] = {
{ 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" },
};
-static const struct stm32l4_rev stm32l41_L42xx_revs[] = {
+static const struct stm32l4_rev stm32l41_l42xx_revs[] = {
{ 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" },
};
@@ -431,8 +420,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
},
{
.id = DEVID_STM32L41_L42XX,
- .revs = stm32l41_L42xx_revs,
- .num_revs = ARRAY_SIZE(stm32l41_L42xx_revs),
+ .revs = stm32l41_l42xx_revs,
+ .num_revs = ARRAY_SIZE(stm32l41_l42xx_revs),
.device_str = "STM32L41/L42xx",
.max_flash_size_kb = 128,
.flags = F_NONE,
@@ -1827,7 +1816,7 @@ static int stm32l4_probe(struct flash_bank *bank)
flash_size_kb = stm32l4_info->user_bank_size / 1024;
}
- LOG_INFO("flash size = %dkbytes", flash_size_kb);
+ LOG_INFO("flash size = %d KiB", flash_size_kb);
/* did we assign a flash size? */
assert((flash_size_kb != 0xffff) && flash_size_kb);
diff --git a/src/flash/nor/stm32l4x.h b/src/flash/nor/stm32l4x.h
index 4458c08..06cc66d 100644
--- a/src/flash/nor/stm32l4x.h
+++ b/src/flash/nor/stm32l4x.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2015 by Uwe Bonnes *
* bon@elektron.ikp.physik.tu-darmstadt.de *
- *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_STM32L4X
diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c
index f6a8ffc..860bab3 100644
--- a/src/flash/nor/stm32lx.c
+++ b/src/flash/nor/stm32lx.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2011 by Clement Burin des Roziers *
* clement.burin-des-roziers@hikob.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -152,7 +141,7 @@ static const struct stm32lx_rev stm32_429_revs[] = {
{ 0x1000, "A" }, { 0x1018, "Z" },
};
static const struct stm32lx_rev stm32_436_revs[] = {
- { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" },
+ { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" }, { 0x1038, "X" },
};
static const struct stm32lx_rev stm32_437_revs[] = {
{ 0x1000, "A" },
diff --git a/src/flash/nor/stmqspi.c b/src/flash/nor/stmqspi.c
index 8278601..9c266e9 100644
--- a/src/flash/nor/stmqspi.c
+++ b/src/flash/nor/stmqspi.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2016 - 2019 by Andreas Bolsch *
* andreas.bolsch@mni.thm.de *
* *
* Copyright (C) 2010 by Antonio Borneo *
* borneo.antonio@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* STM QuadSPI (QSPI) and OctoSPI (OCTOSPI) controller are SPI bus controllers
@@ -765,13 +754,13 @@ COMMAND_HANDLER(stmqspi_handle_set)
bank->sectors = sectors;
stmqspi_info->dev.name = stmqspi_info->devname;
if (stmqspi_info->dev.size_in_bytes / 4096)
- LOG_INFO("flash \'%s\' id = unknown\nchip size = %" PRIu32 "kbytes,"
- " bank size = %" PRIu32 "kbytes", stmqspi_info->dev.name,
+ LOG_INFO("flash \'%s\' id = unknown\nchip size = %" PRIu32 " KiB,"
+ " bank size = %" PRIu32 " KiB", stmqspi_info->dev.name,
stmqspi_info->dev.size_in_bytes / 1024,
(stmqspi_info->dev.size_in_bytes / 1024) << dual);
else
- LOG_INFO("flash \'%s\' id = unknown\nchip size = %" PRIu32 "bytes,"
- " bank size = %" PRIu32 "bytes", stmqspi_info->dev.name,
+ LOG_INFO("flash \'%s\' id = unknown\nchip size = %" PRIu32 " B,"
+ " bank size = %" PRIu32 " B", stmqspi_info->dev.name,
stmqspi_info->dev.size_in_bytes,
stmqspi_info->dev.size_in_bytes << dual);
@@ -2217,10 +2206,10 @@ static int stmqspi_probe(struct flash_bank *bank)
memcpy(&stmqspi_info->dev, p, sizeof(stmqspi_info->dev));
if (p->size_in_bytes / 4096)
LOG_INFO("flash1 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32
- "kbytes", p->name, id1, p->size_in_bytes / 1024);
+ " KiB", p->name, id1, p->size_in_bytes / 1024);
else
LOG_INFO("flash1 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32
- "bytes", p->name, id1, p->size_in_bytes);
+ " B", p->name, id1, p->size_in_bytes);
break;
}
}
@@ -2239,7 +2228,7 @@ static int stmqspi_probe(struct flash_bank *bank)
if (retval == ERROR_OK) {
LOG_INFO("flash1 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32
- "kbytes", temp.name, id1, temp.size_in_bytes / 1024);
+ " KiB", temp.name, id1, temp.size_in_bytes / 1024);
/* save info and retrieved *good* id as spi_sfdp clears all info */
memcpy(&stmqspi_info->dev, &temp, sizeof(stmqspi_info->dev));
stmqspi_info->dev.device_id = id1;
@@ -2257,10 +2246,10 @@ static int stmqspi_probe(struct flash_bank *bank)
if (p->device_id == id2) {
if (p->size_in_bytes / 4096)
LOG_INFO("flash2 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32
- "kbytes", p->name, id2, p->size_in_bytes / 1024);
+ " KiB", p->name, id2, p->size_in_bytes / 1024);
else
LOG_INFO("flash2 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32
- "bytes", p->name, id2, p->size_in_bytes);
+ " B", p->name, id2, p->size_in_bytes);
if (!id1)
memcpy(&stmqspi_info->dev, p, sizeof(stmqspi_info->dev));
@@ -2297,7 +2286,7 @@ static int stmqspi_probe(struct flash_bank *bank)
if (retval == ERROR_OK)
LOG_INFO("flash2 \'%s\' id = 0x%06" PRIx32 " size = %" PRIu32
- "kbytes", temp.name, id2, temp.size_in_bytes / 1024);
+ " KiB", temp.name, id2, temp.size_in_bytes / 1024);
else {
/* even not identified by SFDP, then give up */
LOG_WARNING("Unknown flash2 device id = 0x%06" PRIx32
@@ -2403,22 +2392,22 @@ static int get_stmqspi_info(struct flash_bank *bank, struct command_invocation *
}
command_print_sameline(cmd, "flash%s%s \'%s\', device id = 0x%06" PRIx32
- ", flash size = %" PRIu32 "%sbytes\n(page size = %" PRIu32
+ ", flash size = %" PRIu32 "%s B\n(page size = %" PRIu32
", read = 0x%02" PRIx8 ", qread = 0x%02" PRIx8
", pprog = 0x%02" PRIx8 ", mass_erase = 0x%02" PRIx8
- ", sector size = %" PRIu32 "%sbytes, sector_erase = 0x%02" PRIx8 ")",
+ ", sector size = %" PRIu32 " %sB, sector_erase = 0x%02" PRIx8 ")",
((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) |
BIT(SPI_FSEL_FLASH))) != BIT(SPI_FSEL_FLASH)) ? "1" : "",
((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) |
BIT(SPI_FSEL_FLASH))) != 0) ? "2" : "",
stmqspi_info->dev.name, stmqspi_info->dev.device_id,
bank->size / 4096 ? bank->size / 1024 : bank->size,
- bank->size / 4096 ? "k" : "", stmqspi_info->dev.pagesize,
+ bank->size / 4096 ? "Ki" : "", stmqspi_info->dev.pagesize,
stmqspi_info->dev.read_cmd, stmqspi_info->dev.qread_cmd,
stmqspi_info->dev.pprog_cmd, stmqspi_info->dev.chip_erase_cmd,
stmqspi_info->dev.sectorsize / 4096 ?
stmqspi_info->dev.sectorsize / 1024 : stmqspi_info->dev.sectorsize,
- stmqspi_info->dev.sectorsize / 4096 ? "k" : "",
+ stmqspi_info->dev.sectorsize / 4096 ? "Ki" : "",
stmqspi_info->dev.erase_cmd);
return ERROR_OK;
diff --git a/src/flash/nor/stmqspi.h b/src/flash/nor/stmqspi.h
index 85da25f..245df40 100644
--- a/src/flash/nor/stmqspi.h
+++ b/src/flash/nor/stmqspi.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2016 - 2018 by Andreas Bolsch *
* andreas.bolsch@mni.thm.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_STMQSPI_H
diff --git a/src/flash/nor/stmsmi.c b/src/flash/nor/stmsmi.c
index 553bf29..1aa2447 100644
--- a/src/flash/nor/stmsmi.c
+++ b/src/flash/nor/stmsmi.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* STM Serial Memory Interface (SMI) controller is a SPI bus controller
diff --git a/src/flash/nor/str7x.c b/src/flash/nor/str7x.c
index 9b977bf..b91e22e 100644
--- a/src/flash/nor/str7x.c
+++ b/src/flash/nor/str7x.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2010 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c
index 8f39d75..1a26b83 100644
--- a/src/flash/nor/str9x.c
+++ b/src/flash/nor/str9x.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
*
* Copyright (C) 2008 by Oyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c
index da66a99..c39eb3a 100644
--- a/src/flash/nor/str9xpec.c
+++ b/src/flash/nor/str9xpec.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/swm050.c b/src/flash/nor/swm050.c
index be7452b..89e59ae 100644
--- a/src/flash/nor/swm050.c
+++ b/src/flash/nor/swm050.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2019 Icenowy Zheng <icenowy@aosc.io> *
* Copyright (C) 2019 Caleb Szalacinski <contact@skiboy.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c
index 05db314..0562906 100644
--- a/src/flash/nor/tcl.c
+++ b/src/flash/nor/tcl.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* Copyright (C) 2017-2018 Tomas Vanek <vanekt@fbl.cz> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/flash/nor/tms470.c b/src/flash/nor/tms470.c
index 37f0933..e01d2df 100644
--- a/src/flash/nor/tms470.c
+++ b/src/flash/nor/tms470.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007,2008 by Christopher Kilgour *
* techie |_at_| whiterocker |_dot_| com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -259,9 +248,6 @@ static int tms470_read_part_info(struct flash_bank *bank)
target_write_u32(target, 0xFFFFFFE4, 0x00000000);
target_write_u32(target, 0xFFFFFFE0, 0x00000000);
- bank->chip_width = 32;
- bank->bus_width = 32;
-
LOG_INFO("Identified %s, ver=%d, core=%s, nvmem=%s.",
part_name,
(int)(silicon_version),
diff --git a/src/flash/nor/virtual.c b/src/flash/nor/virtual.c
index 01a9247..c5e3338 100644
--- a/src/flash/nor/virtual.c
+++ b/src/flash/nor/virtual.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/w600.c b/src/flash/nor/w600.c
index cd2aa01..20968dc 100644
--- a/src/flash/nor/w600.c
+++ b/src/flash/nor/w600.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Simon Qian *
* SimonQian@SimonQian.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -323,7 +312,7 @@ static int w600_probe(struct flash_bank *bank)
flash_size = 1 << flash_size;
}
- LOG_INFO("flash size = %" PRIu32 "kbytes", flash_size / 1024);
+ LOG_INFO("flash size = %" PRIu32 " KiB", flash_size / 1024);
/* calculate numbers of pages */
size_t num_pages = flash_size / W600_FLASH_SECSIZE;
diff --git a/src/flash/nor/xcf.c b/src/flash/nor/xcf.c
index c6de1ac..2870725 100644
--- a/src/flash/nor/xcf.c
+++ b/src/flash/nor/xcf.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2016 by Uladzimir Pylinski aka barthess *
* barthess@yandex.ru *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/xmc1xxx.c b/src/flash/nor/xmc1xxx.c
index 9e5f0a3..6e30fc1 100644
--- a/src/flash/nor/xmc1xxx.c
+++ b/src/flash/nor/xmc1xxx.c
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* XMC1000 flash driver
*
* Copyright (c) 2016 Andreas Färber
- *
- * License: GPL-2.0+
*/
#ifdef HAVE_CONFIG_H
@@ -520,24 +520,8 @@ FLASH_BANK_COMMAND_HANDLER(xmc1xxx_flash_bank_command)
return ERROR_OK;
}
-static const struct command_registration xmc1xxx_exec_command_handlers[] = {
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration xmc1xxx_command_handlers[] = {
- {
- .name = "xmc1xxx",
- .mode = COMMAND_ANY,
- .help = "xmc1xxx flash command group",
- .usage = "",
- .chain = xmc1xxx_exec_command_handlers,
- },
- COMMAND_REGISTRATION_DONE
-};
-
const struct flash_driver xmc1xxx_flash = {
.name = "xmc1xxx",
- .commands = xmc1xxx_command_handlers,
.flash_bank_command = xmc1xxx_flash_bank_command,
.info = xmc1xxx_get_info_command,
.probe = xmc1xxx_probe,
diff --git a/src/flash/nor/xmc4xxx.c b/src/flash/nor/xmc4xxx.c
index 1668e89..54fd5a5 100644
--- a/src/flash/nor/xmc4xxx.c
+++ b/src/flash/nor/xmc4xxx.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/**************************************************************************
* Copyright (C) 2015 Jeff Ciesielski <jeffciesielski@gmail.com> *
-* *
-* This program is free software; you can redistribute it and/or modify *
-* it under the terms of the GNU General Public License as published by *
-* the Free Software Foundation; either version 2 of the License, or *
-* (at your option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, *
-* but WITHOUT ANY WARRANTY; without even the implied warranty of *
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-* GNU General Public License for more details. *
-* *
-* You should have received a copy of the GNU General Public License *
-* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl
index 16cbe19..654f201 100644
--- a/src/flash/startup.tcl
+++ b/src/flash/startup.tcl
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
# Defines basic Tcl procs for OpenOCD flash module
#
diff --git a/src/hello.c b/src/hello.c
index 9d078c0..4a4ce01 100644
--- a/src/hello.c
+++ b/src/hello.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/hello.h b/src/hello.h
index c88c89d..1a087b1 100644
--- a/src/hello.h
+++ b/src/hello.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELLO_H
diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am
index 822578a..0268694 100644
--- a/src/helper/Makefile.am
+++ b/src/helper/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libhelper.la
%C%_libhelper_la_SOURCES = \
diff --git a/src/helper/bin2char.sh b/src/helper/bin2char.sh
index 128ea9a..b89433d 100755
--- a/src/helper/bin2char.sh
+++ b/src/helper/bin2char.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
[ $# != 0 ] && {
echo "Usage: $0"
diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c
index e2dfa87..5f38b43 100644
--- a/src/helper/binarybuffer.c
+++ b/src/helper/binarybuffer.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2004, 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h
index 36d6adc..a8a5ef8 100644
--- a/src/helper/binarybuffer.h
+++ b/src/helper/binarybuffer.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2004, 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_BINARYBUFFER_H
diff --git a/src/helper/bits.h b/src/helper/bits.h
index 6151b33..4e2a345 100644
--- a/src/helper/bits.h
+++ b/src/helper/bits.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
* Author(s): Antonio Borneo <borneo.antonio@gmail.com> for STMicroelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
diff --git a/src/helper/command.c b/src/helper/command.c
index 1e769d7..6898e2d 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -10,19 +12,6 @@
* *
* part of this file is taken from libcli (libcli.sourceforge.net) *
* Copyright (C) David Parrish (david@dparrish.com) *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -713,14 +702,12 @@ static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
* This is necessary in order to avoid accidentally getting a non-empty
* string for tcl fn's.
*/
- bool save_poll = jtag_poll_get_enabled();
-
- jtag_poll_set_enabled(false);
+ bool save_poll_mask = jtag_poll_mask();
const char *str = Jim_GetString(argv[1], NULL);
int retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__);
- jtag_poll_set_enabled(save_poll);
+ jtag_poll_unmask(save_poll_mask);
command_log_capture_finish(state);
@@ -949,7 +936,19 @@ 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;
- target_call_timer_callbacks_now();
+ /*
+ * 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();
/*
* Black magic of overridden current target:
diff --git a/src/helper/command.h b/src/helper/command.h
index 796cd9d..478e5c8 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_COMMAND_H
diff --git a/src/helper/configuration.c b/src/helper/configuration.c
index 7e791d0..16732eb 100644
--- a/src/helper/configuration.c
+++ b/src/helper/configuration.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2004, 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -148,6 +137,10 @@ int parse_config_file(struct command_context *cmd_ctx)
char *get_home_dir(const char *append_path)
{
+#ifdef _WIN32
+ char homepath[MAX_PATH];
+#endif
+
char *home = getenv("HOME");
if (!home) {
@@ -156,8 +149,6 @@ char *get_home_dir(const char *append_path)
home = getenv("USERPROFILE");
if (!home) {
-
- char homepath[MAX_PATH];
char *drive = getenv("HOMEDRIVE");
char *path = getenv("HOMEPATH");
if (drive && path) {
diff --git a/src/helper/configuration.h b/src/helper/configuration.h
index cc28efc..295ea59 100644
--- a/src/helper/configuration.h
+++ b/src/helper/configuration.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2004, 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_CONFIGURATION_H
diff --git a/src/helper/fileio.c b/src/helper/fileio.c
index cec7dec..a290a5d 100644
--- a/src/helper/fileio.c
+++ b/src/helper/fileio.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/helper/fileio.h b/src/helper/fileio.h
index 16c1046..6b4be8e 100644
--- a/src/helper/fileio.h
+++ b/src/helper/fileio.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_FILEIO_H
diff --git a/src/helper/jep106.c b/src/helper/jep106.c
index 5cf769a..d422561 100644
--- a/src/helper/jep106.c
+++ b/src/helper/jep106.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 Andreas Fritiofson *
* andreas.fritiofson@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/helper/jep106.h b/src/helper/jep106.h
index 61b177a..c554dae 100644
--- a/src/helper/jep106.h
+++ b/src/helper/jep106.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2015 Andreas Fritiofson *
* andreas.fritiofson@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_JEP106_H
diff --git a/src/helper/jep106.inc b/src/helper/jep106.inc
index 41afdb8..01c3aac 100644
--- a/src/helper/jep106.inc
+++ b/src/helper/jep106.inc
@@ -1,9 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
- * Should be autogenerated with update_jep106.pl but latest
- * file from JEDEC is only available in PDF form. The PDF
- * also breaks the pdftotext flow due to embedded watermarks.
- * Created with a mix of scripts and manual editing.
+ * The manufacturer's standard identification code list appears in JEP106.
+ * Copyright (c) 2022 JEDEC. All rights reserved.
+ *
+ * JEP106 is regularly updated. For the current manufacturer's standard
+ * identification code list, please visit the JEDEC website at www.jedec.org .
*/
+
+/* This file is aligned to revision JEP106BE January 2022. */
+
[0][0x01 - 1] = "AMD",
[0][0x02 - 1] = "AMI",
[0][0x03 - 1] = "Fairchild",
@@ -1553,7 +1559,7 @@
[12][0x23 - 1] = "Tangem AG",
[12][0x24 - 1] = "FuturePath Technology (Shenzhen) Co",
[12][0x25 - 1] = "RC Module",
-[12][0x26 - 1] = "Team Research Inc",
+[12][0x26 - 1] = "Timetec International Inc",
[12][0x27 - 1] = "ICMAX Technologies Co Limited",
[12][0x28 - 1] = "Lynxi Technologies Ltd Co",
[12][0x29 - 1] = "Guangzhou Taisupanke Computer Equipment",
@@ -1571,7 +1577,7 @@
[12][0x35 - 1] = "Shenzhen Xinxinshun Technology Co",
[12][0x36 - 1] = "Galois Inc",
[12][0x37 - 1] = "Ubilite Inc",
-[12][0x38 - 1] = "Shenzhen Quanzing Technology Co Ltd",
+[12][0x38 - 1] = "Shenzhen Quanxing Technology Co Ltd",
[12][0x39 - 1] = "Group RZX Technology LTDA",
[12][0x3a - 1] = "Yottac Technology (XI'AN) Cooperation",
[12][0x3b - 1] = "Shenzhen RuiRen Technology Co Ltd",
@@ -1611,4 +1617,92 @@
[12][0x5d - 1] = "OLOy Technology",
[12][0x5e - 1] = "Wuhan P&S Semiconductor Co Ltd",
[12][0x5f - 1] = "Sitrus Technology",
+[12][0x60 - 1] = "AnHui Conner Storage Co Ltd",
+[12][0x61 - 1] = "Rochester Electronics",
+[12][0x62 - 1] = "Wuxi Petabyte Technologies Co Ltd",
+[12][0x63 - 1] = "Star Memory",
+[12][0x64 - 1] = "Agile Memory Technology Co Ltd",
+[12][0x65 - 1] = "MEJEC",
+[12][0x66 - 1] = "Rockchip Electronics Co Ltd",
+[12][0x67 - 1] = "Dongguan Guanma e-commerce Co Ltd",
+[12][0x68 - 1] = "Rayson Hi-Tech (SZ) Limited",
+[12][0x69 - 1] = "MINRES Technologies GmbH",
+[12][0x6a - 1] = "Himax Technologies Inc",
+[12][0x6b - 1] = "Shenzhen Cwinner Technology Co Ltd",
+[12][0x6c - 1] = "Tecmiyo",
+[12][0x6d - 1] = "Shenzhen Suhuicun Technology Co Ltd",
+[12][0x6e - 1] = "Vickter Electronics Co. Ltd.",
+[12][0x6f - 1] = "lowRISC",
+[12][0x70 - 1] = "EXEGate FZE",
+[12][0x71 - 1] = "Shenzhen 9 Chapter Technologies Co",
+[12][0x72 - 1] = "Addlink",
+[12][0x73 - 1] = "Starsway",
+[12][0x74 - 1] = "Pensando Systems Inc.",
+[12][0x75 - 1] = "AirDisk",
+[12][0x76 - 1] = "Shenzhen Speedmobile Technology Co",
+[12][0x77 - 1] = "PEZY Computing",
+[12][0x78 - 1] = "Extreme Engineering Solutions Inc",
+[12][0x79 - 1] = "Shangxin Technology Co Ltd",
+[12][0x7a - 1] = "Shanghai Zhaoxin Semiconductor Co",
+[12][0x7b - 1] = "Xsight Labs Ltd",
+[12][0x7c - 1] = "Hangzhou Hikstorage Technology Co",
+[12][0x7d - 1] = "Dell Technologies",
+[12][0x7e - 1] = "Guangdong StarFive Technology Co",
+[13][0x01 - 1] = "TECOTON",
+[13][0x02 - 1] = "Abko Co Ltd",
+[13][0x03 - 1] = "Shenzhen Feisrike Technology Co Ltd",
+[13][0x04 - 1] = "Shenzhen Sunhome Electronics Co Ltd",
+[13][0x05 - 1] = "Global Mixed-mode Technology Inc",
+[13][0x06 - 1] = "Shenzhen Weien Electronics Co. Ltd.",
+[13][0x07 - 1] = "Shenzhen Cooyes Technology Co Ltd",
+[13][0x08 - 1] = "Keymos Electronics Co., Limited",
+[13][0x09 - 1] = "E-Rockic Technology Company Limited",
+[13][0x0a - 1] = "Aerospace Science Memory Shenzhen",
+[13][0x0b - 1] = "Shenzhen Quanji Technology Co Ltd",
+[13][0x0c - 1] = "Dukosi",
+[13][0x0d - 1] = "Maxell Corporation of America",
+[13][0x0e - 1] = "Shenshen Xinxintao Electronics Co Ltd",
+[13][0x0f - 1] = "Zhuhai Sanxia Semiconductor Co Ltd",
+[13][0x10 - 1] = "Groq Inc",
+[13][0x11 - 1] = "AstraTek",
+[13][0x12 - 1] = "Shenzhen Xinyuze Technology Co Ltd",
+[13][0x13 - 1] = "All Bit Semiconductor",
+[13][0x14 - 1] = "ACFlow",
+[13][0x15 - 1] = "Shenzhen Sipeed Technology Co Ltd",
+[13][0x16 - 1] = "Linzhi Hong Kong Co Limited",
+[13][0x17 - 1] = "Supreme Wise Limited",
+[13][0x18 - 1] = "Blue Cheetah Analog Design Inc",
+[13][0x19 - 1] = "Hefei Laiku Technology Co Ltd",
+[13][0x1a - 1] = "Zord",
+[13][0x1b - 1] = "SBO Hearing A/S",
+[13][0x1c - 1] = "Regent Sharp International Limited",
+[13][0x1d - 1] = "Permanent Potential Limited",
+[13][0x1e - 1] = "Creative World International Limited",
+[13][0x1f - 1] = "Base Creation International Limited",
+[13][0x20 - 1] = "Shenzhen Zhixin Chuanglian Technology",
+[13][0x21 - 1] = "Protected Logic Corporation",
+[13][0x22 - 1] = "Sabrent",
+[13][0x23 - 1] = "Union Memory",
+[13][0x24 - 1] = "NEUCHIPS Corporation",
+[13][0x25 - 1] = "Ingenic Semiconductor Co Ltd",
+[13][0x26 - 1] = "SiPearl",
+[13][0x27 - 1] = "Shenzhen Actseno Information Technology",
+[13][0x28 - 1] = "RIVAI Technologies (Shenzhen) Co Ltd",
+[13][0x29 - 1] = "Shenzhen Sunny Technology Co Ltd",
+[13][0x2a - 1] = "Cott Electronics Ltd",
+[13][0x2b - 1] = "Shanghai Synsense Technologies Co Ltd",
+[13][0x2c - 1] = "Shenzhen Jintang Fuming Optoelectronics",
+[13][0x2d - 1] = "CloudBEAR LLC",
+[13][0x2e - 1] = "Emzior, LLC",
+[13][0x2f - 1] = "Ehiway Microelectronic Science Tech Co",
+[13][0x30 - 1] = "UNIM Innovation Technology (Wu XI)",
+[13][0x31 - 1] = "GDRAMARS",
+[13][0x32 - 1] = "Meminsights Technology",
+[13][0x33 - 1] = "Zhuzhou Hongda Electronics Corp Ltd",
+[13][0x34 - 1] = "Luminous Computing Inc",
+[13][0x35 - 1] = "PROXMEM",
+[13][0x36 - 1] = "Draper Labs",
+[13][0x37 - 1] = "ORICO Technologies Co. Ltd.",
+[13][0x38 - 1] = "Space Exploration Technologies Corp",
+[13][0x39 - 1] = "AONDEVICES Inc",
/* EOF */
diff --git a/src/helper/jim-nvp.c b/src/helper/jim-nvp.c
index 0409a83..e1ab64a 100644
--- a/src/helper/jim-nvp.c
+++ b/src/helper/jim-nvp.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: BSD-2-Clause-Views
+
/* Jim - A small embeddable Tcl interpreter
*
* Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
@@ -11,34 +13,7 @@
* Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>
* Copyright 2009 Zachary T Welch zw@superlucidity.net
* Copyright 2009 David Brownell
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of the Jim Tcl Project.
+ * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/helper/jim-nvp.h b/src/helper/jim-nvp.h
index 00e4af9..11824ca 100644
--- a/src/helper/jim-nvp.h
+++ b/src/helper/jim-nvp.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause-Views */
+
/* Jim - A small embeddable Tcl interpreter
*
* Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
@@ -11,34 +13,7 @@
* Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>
* Copyright 2009 Zachary T Welch zw@superlucidity.net
* Copyright 2009 David Brownell
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of the Jim Tcl Project.
+ * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved.
*/
#ifndef OPENOCD_HELPER_JIM_NVP_H
@@ -326,144 +301,4 @@ void jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *l
*/
int jim_getopt_enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere);
-/*
- * DEPRECATED API
- * Do not use these API anymore, as they do not comply with OpenOCD coding style
- * They are listed here to avoid breaking build after merge of patches already queued in gerrit
- */
-
-static inline __attribute__ ((deprecated))
-const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- return jim_debug_argv_string(interp, argc, argv);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_GetNvp(Jim_Interp *interp, Jim_Obj *objptr, const struct jim_nvp *nvp_table, const struct jim_nvp **result)
-{
- return jim_get_nvp(interp, objptr, nvp_table, result);
-}
-
-static inline __attribute__ ((deprecated))
-void Jim_GetOpt_Debug(struct jim_getopt_info *goi)
-{
- jim_getopt_debug(goi);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_GetOpt_Double(struct jim_getopt_info *goi, double *puthere)
-{
- return jim_getopt_double(goi, puthere);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_GetOpt_Enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere)
-{
- return jim_getopt_enum(goi, lookup, puthere);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_GetOpt_Nvp(struct jim_getopt_info *goi, const struct jim_nvp *lookup, struct jim_nvp **puthere)
-{
- return jim_getopt_nvp(goi, lookup, puthere);
-}
-
-static inline __attribute__ ((deprecated))
-void Jim_GetOpt_NvpUnknown(struct jim_getopt_info *goi, const struct jim_nvp *lookup, int hadprefix)
-{
- jim_getopt_nvp_unknown(goi, lookup, hadprefix);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_GetOpt_Obj(struct jim_getopt_info *goi, Jim_Obj **puthere)
-{
- return jim_getopt_obj(goi, puthere);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_GetOpt_Setup(struct jim_getopt_info *goi, Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- return jim_getopt_setup(goi, interp, argc, argv);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_GetOpt_String(struct jim_getopt_info *goi, const char **puthere, int *len)
-{
- return jim_getopt_string(goi, puthere, len);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_GetOpt_Wide(struct jim_getopt_info *goi, jim_wide *puthere)
-{
- return jim_getopt_wide(goi, puthere);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_Nvp_name2value(Jim_Interp *interp, const struct jim_nvp *nvp_table, const char *name, struct jim_nvp **result)
-{
- return jim_nvp_name2value(interp, nvp_table, name, result);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const struct jim_nvp *nvp_table, const char *name,
- struct jim_nvp **result)
-{
- return jim_nvp_name2value_nocase(interp, nvp_table, name, result);
-}
-
-static inline __attribute__ ((deprecated))
-struct jim_nvp *Jim_Nvp_name2value_nocase_simple(const struct jim_nvp *nvp_table, const char *name)
-{
- return jim_nvp_name2value_nocase_simple(nvp_table, name);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_Nvp_name2value_obj(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *name_obj,
- struct jim_nvp **result)
-{
- return jim_nvp_name2value_obj(interp, nvp_table, name_obj, result);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *name_obj,
- struct jim_nvp **result)
-{
- return jim_nvp_name2value_obj_nocase(interp, nvp_table, name_obj, result);
-}
-
-static inline __attribute__ ((deprecated))
-struct jim_nvp *Jim_Nvp_name2value_simple(const struct jim_nvp *nvp_table, const char *name)
-{
- return jim_nvp_name2value_simple(nvp_table, name);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_Nvp_value2name(Jim_Interp *interp, const struct jim_nvp *nvp_table, int value, struct jim_nvp **result)
-{
- return jim_nvp_value2name(interp, nvp_table, value, result);
-}
-
-static inline __attribute__ ((deprecated))
-int Jim_Nvp_value2name_obj(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *value_obj,
- struct jim_nvp **result)
-{
- return jim_nvp_value2name_obj(interp, nvp_table, value_obj, result);
-}
-
-static inline __attribute__ ((deprecated))
-struct jim_nvp *Jim_Nvp_value2name_simple(const struct jim_nvp *nvp_table, int v)
-{
- return jim_nvp_value2name_simple(nvp_table, v);
-}
-
-static inline __attribute__ ((deprecated))
-void Jim_SetResult_NvpUnknown(Jim_Interp *interp, Jim_Obj *param_name, Jim_Obj *param_value,
- const struct jim_nvp *nvp_table)
-{
- jim_set_result_nvp_unknown(interp, param_name, param_value, nvp_table);
-}
-
-typedef struct jim_getopt_info Jim_GetOptInfo __attribute__ ((deprecated));
-typedef struct jim_nvp Jim_Nvp __attribute__ ((deprecated));
-
#endif /* OPENOCD_HELPER_JIM_NVP_H */
diff --git a/src/helper/log.c b/src/helper/log.c
index 106d228..e6a70a3 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -306,12 +295,6 @@ void log_exit(void)
log_output = NULL;
}
-int set_log_output(struct command_context *cmd_ctx, FILE *output)
-{
- log_output = output;
- return ERROR_OK;
-}
-
/* add/remove log callback handler */
int log_add_callback(log_callback_fn fn, void *priv)
{
diff --git a/src/helper/log.h b/src/helper/log.h
index f0378ae..ee71bf0 100644
--- a/src/helper/log.h
+++ b/src/helper/log.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_LOG_H
@@ -73,7 +62,6 @@ __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6)));
*/
void log_init(void);
void log_exit(void);
-int set_log_output(struct command_context *cmd_ctx, FILE *output);
int log_register_commands(struct command_context *cmd_ctx);
diff --git a/src/helper/options.c b/src/helper/options.c
index 1996727..327c418 100644
--- a/src/helper/options.c
+++ b/src/helper/options.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2004, 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007-2010 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/helper/replacements.c b/src/helper/replacements.c
index c34b17e..b30dbd5 100644
--- a/src/helper/replacements.c
+++ b/src/helper/replacements.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* DANGER!!!! These must be defined *BEFORE* replacements.h and the malloc() macro!!!! */
diff --git a/src/helper/replacements.h b/src/helper/replacements.h
index 4d70d9c..9eac4d2 100644
--- a/src/helper/replacements.h
+++ b/src/helper/replacements.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_REPLACEMENTS_H
diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index 6389262..5a0d479 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
# Defines basic Tcl procs that must exist for OpenOCD scripts to work.
#
# Embedded into OpenOCD executable
diff --git a/src/helper/system.h b/src/helper/system.h
index 0d8be64..bd96d62 100644
--- a/src/helper/system.h
+++ b/src/helper/system.h
@@ -1,21 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007-2008 by Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_SYSTEM_H
diff --git a/src/helper/time_support.c b/src/helper/time_support.c
index 861889e..dda3cb3 100644
--- a/src/helper/time_support.c
+++ b/src/helper/time_support.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/helper/time_support.h b/src/helper/time_support.h
index b83c0ac..c984296 100644
--- a/src/helper/time_support.h
+++ b/src/helper/time_support.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_TIME_SUPPORT_H
diff --git a/src/helper/time_support_common.c b/src/helper/time_support_common.c
index b733c27..9d17a31 100644
--- a/src/helper/time_support_common.c
+++ b/src/helper/time_support_common.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/helper/types.h b/src/helper/types.h
index 010529f..b99ece1 100644
--- a/src/helper/types.h
+++ b/src/helper/types.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2004, 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_TYPES_H
diff --git a/src/helper/update_jep106.pl b/src/helper/update_jep106.pl
index 561e04b..60472e3 100755
--- a/src/helper/update_jep106.pl
+++ b/src/helper/update_jep106.pl
@@ -1,4 +1,6 @@
#!/usr/bin/perl
+# SPDX-License-Identifier: GPL-2.0-or-later
+
use strict;
use warnings;
use File::Basename;
diff --git a/src/helper/util.c b/src/helper/util.c
index be163b2..bf18f8e 100644
--- a/src/helper/util.c
+++ b/src/helper/util.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Øyvind Harboe *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* this file contains various functionality useful to standalone systems */
diff --git a/src/helper/util.h b/src/helper/util.h
index c9a11dd..3ccdc4f 100644
--- a/src/helper/util.h
+++ b/src/helper/util.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2010 by Øyvind Harboe *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_HELPER_UTIL_H
diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am
index 23424f5..43c6f8b 100644
--- a/src/jtag/Makefile.am
+++ b/src/jtag/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libjtag.la
%C%_libjtag_la_LIBADD =
diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c
index 1c34a26..58d97d3 100644
--- a/src/jtag/adapter.c
+++ b/src/jtag/adapter.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>
* Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com>
@@ -32,6 +32,8 @@ enum adapter_clk_mode {
CLOCK_MODE_RCLK
};
+#define DEFAULT_CLOCK_SPEED_KHZ 100U
+
/**
* Adapter configuration
*/
@@ -42,13 +44,74 @@ static struct {
enum adapter_clk_mode clock_mode;
int speed_khz;
int rclk_fallback_speed_khz;
+ struct adapter_gpio_config gpios[ADAPTER_GPIO_IDX_NUM];
+ bool gpios_initialized; /* Initialization of GPIOs to their unset values performed at run time */
} adapter_config;
+static const struct gpio_map {
+ const char *name;
+ enum adapter_gpio_direction direction;
+ bool permit_drive_option;
+ bool permit_init_state_option;
+} gpio_map[ADAPTER_GPIO_IDX_NUM] = {
+ [ADAPTER_GPIO_IDX_TDO] = { "tdo", ADAPTER_GPIO_DIRECTION_INPUT, false, true, },
+ [ADAPTER_GPIO_IDX_TDI] = { "tdi", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
+ [ADAPTER_GPIO_IDX_TMS] = { "tms", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
+ [ADAPTER_GPIO_IDX_TCK] = { "tck", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
+ [ADAPTER_GPIO_IDX_SWDIO] = { "swdio", ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL, true, true, },
+ [ADAPTER_GPIO_IDX_SWDIO_DIR] = { "swdio_dir", ADAPTER_GPIO_DIRECTION_OUTPUT, true, false, },
+ [ADAPTER_GPIO_IDX_SWCLK] = { "swclk", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
+ [ADAPTER_GPIO_IDX_TRST] = { "trst", ADAPTER_GPIO_DIRECTION_OUTPUT, false, true, },
+ [ADAPTER_GPIO_IDX_SRST] = { "srst", ADAPTER_GPIO_DIRECTION_OUTPUT, false, true, },
+ [ADAPTER_GPIO_IDX_LED] = { "led", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
+};
+
bool is_adapter_initialized(void)
{
return adapter_config.adapter_initialized;
}
+/* For convenience of the bit-banging drivers keep the gpio_config drive
+ * settings for srst and trst in sync with values set by the "adapter
+ * reset_config" command.
+ */
+static void sync_adapter_reset_with_gpios(void)
+{
+ enum reset_types cfg = jtag_get_reset_config();
+ if (cfg & RESET_SRST_PUSH_PULL)
+ adapter_config.gpios[ADAPTER_GPIO_IDX_SRST].drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL;
+ else
+ adapter_config.gpios[ADAPTER_GPIO_IDX_SRST].drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN;
+ if (cfg & RESET_TRST_OPEN_DRAIN)
+ adapter_config.gpios[ADAPTER_GPIO_IDX_TRST].drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN;
+ else
+ adapter_config.gpios[ADAPTER_GPIO_IDX_TRST].drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL;
+}
+
+static void adapter_driver_gpios_init(void)
+{
+ if (adapter_config.gpios_initialized)
+ return;
+
+ for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) {
+ adapter_config.gpios[i].gpio_num = -1;
+ adapter_config.gpios[i].chip_num = -1;
+ if (gpio_map[i].direction == ADAPTER_GPIO_DIRECTION_INPUT)
+ adapter_config.gpios[i].init_state = ADAPTER_GPIO_INIT_STATE_INPUT;
+ }
+
+ /* Drivers assume active low, and this is the normal behaviour for reset
+ * lines so should be the default. */
+ adapter_config.gpios[ADAPTER_GPIO_IDX_SRST].active_low = true;
+ adapter_config.gpios[ADAPTER_GPIO_IDX_TRST].active_low = true;
+ sync_adapter_reset_with_gpios();
+
+ /* JTAG GPIOs should be inactive except for tms */
+ adapter_config.gpios[ADAPTER_GPIO_IDX_TMS].init_state = ADAPTER_GPIO_INIT_STATE_ACTIVE;
+
+ adapter_config.gpios_initialized = true;
+}
+
/**
* Do low-level setup like initializing registers, output signals,
* and clocking.
@@ -65,7 +128,21 @@ int adapter_init(struct command_context *cmd_ctx)
return ERROR_JTAG_INVALID_INTERFACE;
}
+ adapter_driver_gpios_init();
+
int retval;
+
+ if (adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) {
+ LOG_WARNING("An adapter speed is not selected in the init scripts."
+ " OpenOCD will try to run the adapter at the low speed (%d kHz)",
+ DEFAULT_CLOCK_SPEED_KHZ);
+ LOG_WARNING("To remove this warnings and achieve reasonable communication speed with the target,"
+ " set \"adapter speed\" or \"jtag_rclk\" in the init scripts.");
+ retval = adapter_config_khz(DEFAULT_CLOCK_SPEED_KHZ);
+ if (retval != ERROR_OK)
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
retval = adapter_driver->init();
if (retval != ERROR_OK)
return retval;
@@ -76,12 +153,6 @@ int adapter_init(struct command_context *cmd_ctx)
return ERROR_OK;
}
- if (adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) {
- LOG_ERROR("An adapter speed is not selected in the init script."
- " Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed.");
- return ERROR_JTAG_INIT_FAILED;
- }
-
int requested_khz = adapter_get_speed_khz();
int actual_khz = requested_khz;
int speed_var = 0;
@@ -528,6 +599,8 @@ next:
old_cfg &= ~mask;
new_cfg |= old_cfg;
jtag_set_reset_config(new_cfg);
+ sync_adapter_reset_with_gpios();
+
} else
new_cfg = jtag_get_reset_config();
@@ -758,6 +831,218 @@ COMMAND_HANDLER(handle_adapter_reset_de_assert)
(srst == VALUE_DEASSERT) ? SRST_DEASSERT : SRST_ASSERT);
}
+static int get_gpio_index(const char *signal_name)
+{
+ for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) {
+ if (strcmp(gpio_map[i].name, signal_name) == 0)
+ return i;
+ }
+ return -1;
+}
+
+static COMMAND_HELPER(helper_adapter_gpio_print_config, enum adapter_gpio_config_index gpio_idx)
+{
+ struct adapter_gpio_config *gpio_config = &adapter_config.gpios[gpio_idx];
+ const char *active_state = gpio_config->active_low ? "low" : "high";
+ const char *dir = "";
+ const char *drive = "";
+ const char *pull = "";
+ const char *init_state = "";
+
+ switch (gpio_map[gpio_idx].direction) {
+ case ADAPTER_GPIO_DIRECTION_INPUT:
+ dir = "input";
+ break;
+ case ADAPTER_GPIO_DIRECTION_OUTPUT:
+ dir = "output";
+ break;
+ case ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL:
+ dir = "bidirectional";
+ break;
+ }
+
+ if (gpio_map[gpio_idx].permit_drive_option) {
+ switch (gpio_config->drive) {
+ case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:
+ drive = ", push-pull";
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:
+ drive = ", open-drain";
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
+ drive = ", open-source";
+ break;
+ }
+ }
+
+ switch (gpio_config->pull) {
+ case ADAPTER_GPIO_PULL_NONE:
+ pull = ", pull-none";
+ break;
+ case ADAPTER_GPIO_PULL_UP:
+ pull = ", pull-up";
+ break;
+ case ADAPTER_GPIO_PULL_DOWN:
+ pull = ", pull-down";
+ break;
+ }
+
+ if (gpio_map[gpio_idx].permit_init_state_option) {
+ switch (gpio_config->init_state) {
+ case ADAPTER_GPIO_INIT_STATE_INACTIVE:
+ init_state = ", init-state inactive";
+ break;
+ case ADAPTER_GPIO_INIT_STATE_ACTIVE:
+ init_state = ", init-state active";
+ break;
+ case ADAPTER_GPIO_INIT_STATE_INPUT:
+ init_state = ", init-state input";
+ break;
+ }
+ }
+
+ command_print(CMD, "adapter gpio %s (%s): num %d, chip %d, active-%s%s%s%s",
+ gpio_map[gpio_idx].name, dir, gpio_config->gpio_num, gpio_config->chip_num, active_state,
+ drive, pull, init_state);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(helper_adapter_gpio_print_all_configs)
+{
+ for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i)
+ CALL_COMMAND_HANDLER(helper_adapter_gpio_print_config, i);
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(adapter_gpio_config_handler)
+{
+ unsigned int i = 1;
+ struct adapter_gpio_config *gpio_config;
+
+ adapter_driver_gpios_init();
+
+ if (CMD_ARGC == 0) {
+ CALL_COMMAND_HANDLER(helper_adapter_gpio_print_all_configs);
+ return ERROR_OK;
+ }
+
+ int gpio_idx = get_gpio_index(CMD_ARGV[0]);
+ if (gpio_idx == -1) {
+ LOG_ERROR("adapter has no gpio named %s", CMD_ARGV[0]);
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ if (CMD_ARGC == 1) {
+ CALL_COMMAND_HANDLER(helper_adapter_gpio_print_config, gpio_idx);
+ return ERROR_OK;
+ }
+
+ gpio_config = &adapter_config.gpios[gpio_idx];
+ while (i < CMD_ARGC) {
+ LOG_DEBUG("Processing %s", CMD_ARGV[i]);
+
+ if (isdigit(*CMD_ARGV[i])) {
+ int gpio_num; /* Use a meaningful output parameter for more helpful error messages */
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[i], gpio_num);
+ gpio_config->gpio_num = gpio_num;
+ ++i;
+ continue;
+ }
+
+ if (strcmp(CMD_ARGV[i], "-chip") == 0) {
+ if (CMD_ARGC - i < 2) {
+ LOG_ERROR("-chip option requires a parameter");
+ return ERROR_FAIL;
+ }
+ LOG_DEBUG("-chip arg is %s", CMD_ARGV[i + 1]);
+ int chip_num; /* Use a meaningful output parameter for more helpful error messages */
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[i + 1], chip_num);
+ gpio_config->chip_num = chip_num;
+ i += 2;
+ continue;
+ }
+
+ if (strcmp(CMD_ARGV[i], "-active-high") == 0) {
+ ++i;
+ gpio_config->active_low = false;
+ continue;
+ }
+ if (strcmp(CMD_ARGV[i], "-active-low") == 0) {
+ ++i;
+ gpio_config->active_low = true;
+ continue;
+ }
+
+ if (gpio_map[gpio_idx].permit_drive_option) {
+ if (strcmp(CMD_ARGV[i], "-push-pull") == 0) {
+ ++i;
+ gpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL;
+ continue;
+ }
+ if (strcmp(CMD_ARGV[i], "-open-drain") == 0) {
+ ++i;
+ gpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN;
+ continue;
+ }
+ if (strcmp(CMD_ARGV[i], "-open-source") == 0) {
+ ++i;
+ gpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE;
+ continue;
+ }
+ }
+
+ if (strcmp(CMD_ARGV[i], "-pull-none") == 0) {
+ ++i;
+ gpio_config->pull = ADAPTER_GPIO_PULL_NONE;
+ continue;
+ }
+ if (strcmp(CMD_ARGV[i], "-pull-up") == 0) {
+ ++i;
+ gpio_config->pull = ADAPTER_GPIO_PULL_UP;
+ continue;
+ }
+ if (strcmp(CMD_ARGV[i], "-pull-down") == 0) {
+ ++i;
+ gpio_config->pull = ADAPTER_GPIO_PULL_DOWN;
+ continue;
+ }
+
+ if (gpio_map[gpio_idx].permit_init_state_option) {
+ if (strcmp(CMD_ARGV[i], "-init-inactive") == 0) {
+ ++i;
+ gpio_config->init_state = ADAPTER_GPIO_INIT_STATE_INACTIVE;
+ continue;
+ }
+ if (strcmp(CMD_ARGV[i], "-init-active") == 0) {
+ ++i;
+ gpio_config->init_state = ADAPTER_GPIO_INIT_STATE_ACTIVE;
+ continue;
+ }
+
+ if (gpio_map[gpio_idx].direction == ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL &&
+ strcmp(CMD_ARGV[i], "-init-input") == 0) {
+ ++i;
+ gpio_config->init_state = ADAPTER_GPIO_INIT_STATE_INPUT;
+ continue;
+ }
+ }
+
+ LOG_ERROR("illegal option for adapter %s %s: %s",
+ CMD_NAME, gpio_map[gpio_idx].name, CMD_ARGV[i]);
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ /* Force swdio_dir init state to be compatible with swdio init state */
+ if (gpio_idx == ADAPTER_GPIO_IDX_SWDIO)
+ adapter_config.gpios[ADAPTER_GPIO_IDX_SWDIO_DIR].init_state =
+ (gpio_config->init_state == ADAPTER_GPIO_INIT_STATE_INPUT) ?
+ ADAPTER_GPIO_INIT_STATE_INACTIVE :
+ ADAPTER_GPIO_INIT_STATE_ACTIVE;
+
+ return ERROR_OK;
+}
+
#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
COMMAND_HANDLER(handle_usb_location_command)
{
@@ -875,6 +1160,19 @@ static const struct command_registration adapter_command_handlers[] = {
.help = "Controls SRST and TRST lines.",
.usage = "|assert [srst|trst [deassert|assert srst|trst]]",
},
+ {
+ .name = "gpio",
+ .handler = adapter_gpio_config_handler,
+ .mode = COMMAND_CONFIG,
+ .help = "gpio adapter command group",
+ .usage = "[ tdo|tdi|tms|tck|trst|swdio|swdio_dir|swclk|srst|led"
+ "[gpio_number] "
+ "[-chip chip_number] "
+ "[-active-high|-active-low] "
+ "[-push-pull|-open-drain|-open-source] "
+ "[-pull-none|-pull-up|-pull-down]"
+ "[-init-inactive|-init-active|-init-input] ]",
+ },
COMMAND_REGISTRATION_DONE
};
@@ -911,3 +1209,14 @@ int adapter_register_commands(struct command_context *ctx)
{
return register_commands(ctx, NULL, interface_command_handlers);
}
+
+const char *adapter_gpio_get_name(enum adapter_gpio_config_index idx)
+{
+ return gpio_map[idx].name;
+}
+
+/* Allow drivers access to the GPIO configuration */
+const struct adapter_gpio_config *adapter_gpio_get_config(void)
+{
+ return adapter_config.gpios;
+}
diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h
index 300769c..682fc10 100644
--- a/src/jtag/adapter.h
+++ b/src/jtag/adapter.h
@@ -11,6 +11,59 @@
#include <stddef.h>
#include <stdint.h>
+/** Supported output drive modes for adaptor GPIO */
+enum adapter_gpio_drive_mode {
+ ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL,
+ ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN,
+ ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE,
+};
+
+/** Supported GPIO directions */
+enum adapter_gpio_direction {
+ ADAPTER_GPIO_DIRECTION_INPUT,
+ ADAPTER_GPIO_DIRECTION_OUTPUT,
+ ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL,
+};
+
+/** Supported initial states for GPIO */
+enum adapter_gpio_init_state {
+ ADAPTER_GPIO_INIT_STATE_INACTIVE, /* Should be zero so it is the default state */
+ ADAPTER_GPIO_INIT_STATE_ACTIVE,
+ ADAPTER_GPIO_INIT_STATE_INPUT,
+};
+
+/** Supported pull directions for GPIO */
+enum adapter_gpio_pull {
+ ADAPTER_GPIO_PULL_NONE,
+ ADAPTER_GPIO_PULL_UP,
+ ADAPTER_GPIO_PULL_DOWN,
+};
+
+/** Adapter GPIO */
+enum adapter_gpio_config_index {
+ ADAPTER_GPIO_IDX_TDO,
+ ADAPTER_GPIO_IDX_TDI,
+ ADAPTER_GPIO_IDX_TMS,
+ ADAPTER_GPIO_IDX_TCK,
+ ADAPTER_GPIO_IDX_TRST,
+ ADAPTER_GPIO_IDX_SWDIO,
+ ADAPTER_GPIO_IDX_SWDIO_DIR,
+ ADAPTER_GPIO_IDX_SWCLK,
+ ADAPTER_GPIO_IDX_SRST,
+ ADAPTER_GPIO_IDX_LED,
+ ADAPTER_GPIO_IDX_NUM, /* must be the last item */
+};
+
+/** Configuration options for a single GPIO */
+struct adapter_gpio_config {
+ int gpio_num;
+ int chip_num;
+ enum adapter_gpio_drive_mode drive; /* For outputs only */
+ enum adapter_gpio_init_state init_state;
+ bool active_low;
+ enum adapter_gpio_pull pull;
+};
+
struct command_context;
/** Register the adapter's commands */
@@ -58,4 +111,14 @@ unsigned int adapter_get_speed_khz(void);
/** Retrieves the serial number set with command 'adapter serial' */
const char *adapter_get_required_serial(void);
+/**
+ * Retrieves gpio name
+ */
+const char *adapter_gpio_get_name(enum adapter_gpio_config_index idx);
+
+/**
+ * Retrieves gpio configuration set with command "adapter gpio <signal_name>"
+ */
+const struct adapter_gpio_config *adapter_gpio_get_config(void);
+
#endif /* OPENOCD_JTAG_ADAPTER_H */
diff --git a/src/jtag/aice/Makefile.am b/src/jtag/aice/Makefile.am
index b6a7ba9..bc5dac1 100644
--- a/src/jtag/aice/Makefile.am
+++ b/src/jtag/aice/Makefile.am
@@ -1,3 +1,5 @@
+# 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)
diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c
index cb126c6..89f82a0 100644
--- a/src/jtag/aice/aice_interface.c
+++ b/src/jtag/aice/aice_interface.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/aice/aice_interface.h b/src/jtag/aice/aice_interface.h
index 3bddfa3..615e90f 100644
--- a/src/jtag/aice/aice_interface.h
+++ b/src/jtag/aice/aice_interface.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_AICE_AICE_INTERFACE_H
diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c
index e464b86..d2befde 100644
--- a/src/jtag/aice/aice_pipe.c
+++ b/src/jtag/aice/aice_pipe.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/jtag/aice/aice_pipe.h b/src/jtag/aice/aice_pipe.h
index 467ad0a..5a1f410 100644
--- a/src/jtag/aice/aice_pipe.h
+++ b/src/jtag/aice/aice_pipe.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_AICE_AICE_PIPE_H
diff --git a/src/jtag/aice/aice_port.c b/src/jtag/aice/aice_port.c
index 2fa346c..ac38cec 100644
--- a/src/jtag/aice/aice_port.c
+++ b/src/jtag/aice/aice_port.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/jtag/aice/aice_port.h b/src/jtag/aice/aice_port.h
index 1593688..fb914d8 100644
--- a/src/jtag/aice/aice_port.h
+++ b/src/jtag/aice/aice_port.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_AICE_AICE_PORT_H
diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c
index 2f2542e..49f899d 100644
--- a/src/jtag/aice/aice_transport.c
+++ b/src/jtag/aice/aice_transport.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/aice/aice_transport.h b/src/jtag/aice/aice_transport.h
index 3af8bc2..b000031 100644
--- a/src/jtag/aice/aice_transport.h
+++ b/src/jtag/aice/aice_transport.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_AICE_AICE_TRANSPORT_H
diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c
index fc46e37..ef0ac63 100644
--- a/src/jtag/aice/aice_usb.c
+++ b/src/jtag/aice/aice_usb.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/jtag/aice/aice_usb.h b/src/jtag/aice/aice_usb.h
index 04021de..d85d25f 100644
--- a/src/jtag/aice/aice_usb.h
+++ b/src/jtag/aice/aice_usb.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 by Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_AICE_AICE_USB_H
diff --git a/src/jtag/commands.c b/src/jtag/commands.c
index 206c5e8..43cda8a 100644
--- a/src/jtag/commands.c
+++ b/src/jtag/commands.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -11,19 +13,6 @@
* *
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/commands.h b/src/jtag/commands.h
index c037596..a8c7ffd 100644
--- a/src/jtag/commands.h
+++ b/src/jtag/commands.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_COMMANDS_H
diff --git a/src/jtag/core.c b/src/jtag/core.c
index bbc9877..5748011 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
@@ -11,19 +13,6 @@
* *
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -147,14 +136,19 @@ int jtag_error_clear(void)
/************/
-static bool jtag_poll = 1;
+static bool jtag_poll = true;
+static bool jtag_poll_en = true;
bool is_jtag_poll_safe(void)
{
/* Polling can be disabled explicitly with set_enabled(false).
+ * It can also be masked with mask().
* It is also implicitly disabled while TRST is active and
* while SRST is gating the JTAG clock.
*/
+ if (!jtag_poll_en)
+ return false;
+
if (!transport_is_jtag())
return jtag_poll;
@@ -173,6 +167,18 @@ void jtag_poll_set_enabled(bool value)
jtag_poll = value;
}
+bool jtag_poll_mask(void)
+{
+ bool retval = jtag_poll_en;
+ jtag_poll_en = false;
+ return retval;
+}
+
+void jtag_poll_unmask(bool saved)
+{
+ jtag_poll_en = saved;
+}
+
/************/
struct jtag_tap *jtag_all_taps(void)
diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am
index d05b7b9..6410f37 100644
--- a/src/jtag/drivers/Makefile.am
+++ b/src/jtag/drivers/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libocdjtagdrivers.la
%C%_libocdjtagdrivers_la_LIBADD =
@@ -106,6 +108,9 @@ endif
if PRESTO
DRIVERFILES += %D%/presto.c
endif
+if ESP_USB_JTAG
+DRIVERFILES += %D%/esp_usb_jtag.c
+endif
if USBPROG
DRIVERFILES += %D%/usbprog.c
endif
diff --git a/src/jtag/drivers/Makefile.rlink b/src/jtag/drivers/Makefile.rlink
index 6168332..538228d 100644
--- a/src/jtag/drivers/Makefile.rlink
+++ b/src/jtag/drivers/Makefile.rlink
@@ -1,20 +1,9 @@
-#***************************************************************************
-#* Copyright (C) 2008 Lou Deluxe *
-#* lou.openocd012@fixit.nospammail.net *
-#* *
-#* This program is free software; you can redistribute it and/or modify *
-#* it under the terms of the GNU General Public License as published by *
-#* the Free Software Foundation; either version 2 of the License, or *
-#* (at your option) any later version. *
-#* *
-#* This program is distributed in the hope that it will be useful, *
-#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
-#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-#* GNU General Public License for more details. *
-#* *
-#* You should have received a copy of the GNU General Public License *
-#* along with this program. If not, see <http://www.gnu.org/licenses/>. *
-#***************************************************************************
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+#
+# Copyright (C) 2008 Lou Deluxe
+# lou.openocd012@fixit.nospammail.net
+#
TOP = ../../..
INTERFACE_NAME = rlink
diff --git a/src/jtag/drivers/OpenULINK/Makefile b/src/jtag/drivers/OpenULINK/Makefile
index 9f6acc6..d65edcb 100644
--- a/src/jtag/drivers/OpenULINK/Makefile
+++ b/src/jtag/drivers/OpenULINK/Makefile
@@ -1,20 +1,9 @@
-############################################################################
-# Copyright (C) 2011 by Martin Schmoelzer #
-# <martin.schmoelzer@student.tuwien.ac.at> #
-# #
-# This program is free software; you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation; either version 2 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
-# GNU General Public License for more details. #
-# #
-# You should have received a copy of the GNU General Public License #
-# along with this program. If not, see <http://www.gnu.org/licenses/>. #
-############################################################################
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+#
+# Copyright (C) 2011 by Martin Schmoelzer
+# <martin.schmoelzer@student.tuwien.ac.at>
+#
# Define the name of our tools. Some distributions (e. g. Fedora) prefix
# the SDCC executables, change this accordingly!
diff --git a/src/jtag/drivers/OpenULINK/include/common.h b/src/jtag/drivers/OpenULINK/include/common.h
index 56222fe..8f41fd0 100644
--- a/src/jtag/drivers/OpenULINK/include/common.h
+++ b/src/jtag/drivers/OpenULINK/include/common.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef __COMMON_H
diff --git a/src/jtag/drivers/OpenULINK/include/delay.h b/src/jtag/drivers/OpenULINK/include/delay.h
index ed454be..be0d762 100644
--- a/src/jtag/drivers/OpenULINK/include/delay.h
+++ b/src/jtag/drivers/OpenULINK/include/delay.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef __DELAY_H
diff --git a/src/jtag/drivers/OpenULINK/include/io.h b/src/jtag/drivers/OpenULINK/include/io.h
index 497c235..1330ebd 100644
--- a/src/jtag/drivers/OpenULINK/include/io.h
+++ b/src/jtag/drivers/OpenULINK/include/io.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef __IO_H
diff --git a/src/jtag/drivers/OpenULINK/include/jtag.h b/src/jtag/drivers/OpenULINK/include/jtag.h
index fa492b9..1b5c3af 100644
--- a/src/jtag/drivers/OpenULINK/include/jtag.h
+++ b/src/jtag/drivers/OpenULINK/include/jtag.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef __JTAG_H
diff --git a/src/jtag/drivers/OpenULINK/include/main.h b/src/jtag/drivers/OpenULINK/include/main.h
index 9e7dd5a..d399c33 100644
--- a/src/jtag/drivers/OpenULINK/include/main.h
+++ b/src/jtag/drivers/OpenULINK/include/main.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef __MAIN_H
diff --git a/src/jtag/drivers/OpenULINK/include/msgtypes.h b/src/jtag/drivers/OpenULINK/include/msgtypes.h
index f761a84..ae61ddb 100644
--- a/src/jtag/drivers/OpenULINK/include/msgtypes.h
+++ b/src/jtag/drivers/OpenULINK/include/msgtypes.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
diff --git a/src/jtag/drivers/OpenULINK/include/protocol.h b/src/jtag/drivers/OpenULINK/include/protocol.h
index 0b6a7d6..91b5640 100644
--- a/src/jtag/drivers/OpenULINK/include/protocol.h
+++ b/src/jtag/drivers/OpenULINK/include/protocol.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef __PROTOCOL_H
diff --git a/src/jtag/drivers/OpenULINK/include/reg_ezusb.h b/src/jtag/drivers/OpenULINK/include/reg_ezusb.h
index 4988367..6c38ab6 100644
--- a/src/jtag/drivers/OpenULINK/include/reg_ezusb.h
+++ b/src/jtag/drivers/OpenULINK/include/reg_ezusb.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef REG_EZUSB_H
diff --git a/src/jtag/drivers/OpenULINK/include/usb.h b/src/jtag/drivers/OpenULINK/include/usb.h
index 9a261fe..30968b3 100644
--- a/src/jtag/drivers/OpenULINK/include/usb.h
+++ b/src/jtag/drivers/OpenULINK/include/usb.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef __USB_H
diff --git a/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 b/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51
index f10ad48..f62508b 100644
--- a/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51
+++ b/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51
@@ -1,20 +1,9 @@
-;--------------------------------------------------------------------------;
-; Copyright (C) 2011-2013 by Martin Schmoelzer ;
-; <martin.schmoelzer@student.tuwien.ac.at> ;
-; ;
-; This program is free software; you can redistribute it and/or modify ;
-; it under the terms of the GNU General Public License as published by ;
-; the Free Software Foundation; either version 2 of the License, or ;
-; (at your option) any later version. ;
-; ;
-; This program is distributed in the hope that it will be useful, ;
-; but WITHOUT ANY WARRANTY; without even the implied warranty of ;
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
-; GNU General Public License for more details. ;
-; ;
-; You should have received a copy of the GNU General Public License ;
-; along with this program. If not, see <http://www.gnu.org/licenses/>. ;
-;--------------------------------------------------------------------------;
+; SPDX-License-Identifier: GPL-2.0-or-later
+
+;
+; Copyright (C) 2011-2013 by Martin Schmoelzer
+; <martin.schmoelzer@student.tuwien.ac.at>
+;
.module JUMPTABLE
.globl USB_AutoVector
diff --git a/src/jtag/drivers/OpenULINK/src/delay.c b/src/jtag/drivers/OpenULINK/src/delay.c
index 3260567..b68e814 100644
--- a/src/jtag/drivers/OpenULINK/src/delay.c
+++ b/src/jtag/drivers/OpenULINK/src/delay.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "delay.h"
diff --git a/src/jtag/drivers/OpenULINK/src/jtag.c b/src/jtag/drivers/OpenULINK/src/jtag.c
index c76f034..c9253a3 100644
--- a/src/jtag/drivers/OpenULINK/src/jtag.c
+++ b/src/jtag/drivers/OpenULINK/src/jtag.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "jtag.h"
diff --git a/src/jtag/drivers/OpenULINK/src/main.c b/src/jtag/drivers/OpenULINK/src/main.c
index f331c9e..51d3a3b 100644
--- a/src/jtag/drivers/OpenULINK/src/main.c
+++ b/src/jtag/drivers/OpenULINK/src/main.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "main.h"
diff --git a/src/jtag/drivers/OpenULINK/src/protocol.c b/src/jtag/drivers/OpenULINK/src/protocol.c
index f8f84ed..b3d5622 100644
--- a/src/jtag/drivers/OpenULINK/src/protocol.c
+++ b/src/jtag/drivers/OpenULINK/src/protocol.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "protocol.h"
diff --git a/src/jtag/drivers/OpenULINK/src/usb.c b/src/jtag/drivers/OpenULINK/src/usb.c
index 032b23b..408e212 100644
--- a/src/jtag/drivers/OpenULINK/src/usb.c
+++ b/src/jtag/drivers/OpenULINK/src/usb.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011-2013 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
diff --git a/src/jtag/drivers/am335xgpio.c b/src/jtag/drivers/am335xgpio.c
index e04c44c..e641a4f 100644
--- a/src/jtag/drivers/am335xgpio.c
+++ b/src/jtag/drivers/am335xgpio.c
@@ -1,43 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2022 by Steve Marple, stevemarple@googlemail.com *
* *
* Based on bcm2835gpio.c and linuxgpiod.c *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include <jtag/adapter.h>
#include <jtag/interface.h>
#include <transport/transport.h>
#include "bitbang.h"
#include <sys/mman.h>
-/*
- * GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara
+/* GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara
* Processors Technical Reference Manual", Chapter 2 Memory Map.
*/
-#define AM335XGPIO_NUM_GPIO_PORTS 4
+#define AM335XGPIO_NUM_GPIO_PER_CHIP 32
+#define AM335XGPIO_NUM_GPIO_CHIPS 4
#define AM335XGPIO_GPIO0_HW_ADDR 0x44E07000
#define AM335XGPIO_GPIO1_HW_ADDR 0x4804C000
#define AM335XGPIO_GPIO2_HW_ADDR 0x481AC000
#define AM335XGPIO_GPIO3_HW_ADDR 0x481AE000
-/* 32-bit offsets from GPIO port base address. Values taken from "AM335x and
+/* 32-bit offsets from GPIO chip base address. Values taken from "AM335x and
* AMIC110 Sitara Processors Technical Reference Manual", Chapter 25
* General-Purpose Input/Output.
*/
@@ -47,34 +37,34 @@
#define AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET (0x190 / 4)
#define AM335XGPIO_GPIO_SETDATAOUT_OFFSET (0x194 / 4)
-/* GPIOs are integer values; need to map to a port module, and the pin within
- * that module. GPIOs 0 to 31 map to GPIO0, 32 to 63 to GPIO1 etc. This scheme
- * matches that used by Linux on the BeagleBone.
- */
-#define AM335XGPIO_PORT_NUM(gpio_num) ((gpio_num) / 32)
-#define AM335XGPIO_BIT_NUM(gpio_num) ((gpio_num) % 32)
-#define AM335XGPIO_BIT_MASK(gpio_num) BIT(AM335XGPIO_BIT_NUM(gpio_num))
+#define AM335XGPIO_READ_REG(chip_num, offset) \
+ (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)))
-#define AM335XGPIO_READ_REG(gpio_num, offset) \
- (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)))
+#define AM335XGPIO_WRITE_REG(chip_num, offset, value) \
+ (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) = (value))
-#define AM335XGPIO_WRITE_REG(gpio_num, offset, value) \
- (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) = (value))
+#define AM335XGPIO_SET_REG_BITS(chip_num, offset, bit_mask) \
+ (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) |= (bit_mask))
-#define AM335XGPIO_SET_REG_BITS(gpio_num, offset, bit_mask) \
- (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) |= (bit_mask))
+#define AM335XGPIO_CLEAR_REG_BITS(chip_num, offset, bit_mask) \
+ (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) &= ~(bit_mask))
-#define AM335XGPIO_CLEAR_REG_BITS(gpio_num, offset, bit_mask) \
- (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) &= ~(bit_mask))
+#define AM335XGPIO_SET_INPUT(gpio_config) \
+ AM335XGPIO_SET_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))
+#define AM335XGPIO_SET_OUTPUT(gpio_config) \
+ AM335XGPIO_CLEAR_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))
+#define AM335XGPIO_SET_HIGH(gpio_config) \
+ AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))
+#define AM335XGPIO_SET_LOW(gpio_config) \
+ AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))
-enum amx335gpio_gpio_mode {
+enum amx335gpio_initial_gpio_mode {
AM335XGPIO_GPIO_MODE_INPUT,
- AM335XGPIO_GPIO_MODE_OUTPUT, /* To set output mode but not state */
AM335XGPIO_GPIO_MODE_OUTPUT_LOW,
AM335XGPIO_GPIO_MODE_OUTPUT_HIGH,
};
-static const uint32_t am335xgpio_gpio_port_hw_addr[AM335XGPIO_NUM_GPIO_PORTS] = {
+static const uint32_t am335xgpio_gpio_chip_hw_addr[AM335XGPIO_NUM_GPIO_CHIPS] = {
AM335XGPIO_GPIO0_HW_ADDR,
AM335XGPIO_GPIO1_HW_ADDR,
AM335XGPIO_GPIO2_HW_ADDR,
@@ -82,117 +72,151 @@ static const uint32_t am335xgpio_gpio_port_hw_addr[AM335XGPIO_NUM_GPIO_PORTS] =
};
/* Memory-mapped address pointers */
-static volatile uint32_t *am335xgpio_gpio_port_mmap_addr[AM335XGPIO_NUM_GPIO_PORTS];
+static volatile uint32_t *am335xgpio_gpio_chip_mmap_addr[AM335XGPIO_NUM_GPIO_CHIPS];
static int dev_mem_fd;
-
-/* GPIO numbers for each signal. Negative values are invalid */
-static int tck_gpio = -1;
-static enum amx335gpio_gpio_mode tck_gpio_mode;
-static int tms_gpio = -1;
-static enum amx335gpio_gpio_mode tms_gpio_mode;
-static int tdi_gpio = -1;
-static enum amx335gpio_gpio_mode tdi_gpio_mode;
-static int tdo_gpio = -1;
-static enum amx335gpio_gpio_mode tdo_gpio_mode;
-static int trst_gpio = -1;
-static enum amx335gpio_gpio_mode trst_gpio_mode;
-static int srst_gpio = -1;
-static enum amx335gpio_gpio_mode srst_gpio_mode;
-static int swclk_gpio = -1;
-static enum amx335gpio_gpio_mode swclk_gpio_mode;
-static int swdio_gpio = -1;
-static enum amx335gpio_gpio_mode swdio_gpio_mode;
-static int swdio_dir_gpio = -1;
-static enum amx335gpio_gpio_mode swdio_dir_gpio_mode;
-static int led_gpio = -1;
-static enum amx335gpio_gpio_mode led_gpio_mode = -1;
-
-static bool swdio_dir_is_active_high = true; /* Active state means output */
-static bool led_is_active_high = true;
+static enum amx335gpio_initial_gpio_mode initial_gpio_mode[ADAPTER_GPIO_IDX_NUM];
/* Transition delay coefficients */
static int speed_coeff = 600000;
static int speed_offset = 575;
static unsigned int jtag_delay;
-static int is_gpio_valid(int gpio_num)
-{
- return gpio_num >= 0 && gpio_num < (32 * AM335XGPIO_NUM_GPIO_PORTS);
-}
+static const struct adapter_gpio_config *adapter_gpio_config;
-static int get_gpio_value(int gpio_num)
+static bool is_gpio_config_valid(const struct adapter_gpio_config *gpio_config)
{
- unsigned int shift = AM335XGPIO_BIT_NUM(gpio_num);
- return (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_DATAIN_OFFSET) >> shift) & 1;
+ return gpio_config->chip_num >= 0
+ && gpio_config->chip_num < AM335XGPIO_NUM_GPIO_CHIPS
+ && gpio_config->gpio_num >= 0
+ && gpio_config->gpio_num < AM335XGPIO_NUM_GPIO_PER_CHIP;
}
-static void set_gpio_value(int gpio_num, int value)
+static int get_gpio_value(const struct adapter_gpio_config *gpio_config)
{
- if (value)
- AM335XGPIO_WRITE_REG(gpio_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num));
- else
- AM335XGPIO_WRITE_REG(gpio_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num));
+ unsigned int shift = gpio_config->gpio_num;
+ uint32_t value = AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAIN_OFFSET);
+ value = (value >> shift) & 1;
+ return value ^ (gpio_config->active_low ? 1 : 0);
}
-static enum amx335gpio_gpio_mode get_gpio_mode(int gpio_num)
+static void set_gpio_value(const struct adapter_gpio_config *gpio_config, int value)
{
- if (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_OE_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) {
- return AM335XGPIO_GPIO_MODE_INPUT;
- } else {
- /* Return output level too so that pin mode can be fully restored */
- if (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num))
- return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH;
+ value = value ^ (gpio_config->active_low ? 1 : 0);
+ switch (gpio_config->drive) {
+ case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:
+ if (value)
+ AM335XGPIO_SET_HIGH(gpio_config);
else
- return AM335XGPIO_GPIO_MODE_OUTPUT_LOW;
+ AM335XGPIO_SET_LOW(gpio_config);
+ /* For performance reasons assume the GPIO is already set as an output
+ * and therefore the call can be omitted here.
+ */
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:
+ if (value) {
+ AM335XGPIO_SET_INPUT(gpio_config);
+ } else {
+ AM335XGPIO_SET_LOW(gpio_config);
+ AM335XGPIO_SET_OUTPUT(gpio_config);
+ }
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
+ if (value) {
+ AM335XGPIO_SET_HIGH(gpio_config);
+ AM335XGPIO_SET_OUTPUT(gpio_config);
+ } else {
+ AM335XGPIO_SET_INPUT(gpio_config);
+ }
+ break;
}
}
-static void set_gpio_mode(int gpio_num, enum amx335gpio_gpio_mode gpio_mode)
+static enum amx335gpio_initial_gpio_mode get_gpio_mode(const struct adapter_gpio_config *gpio_config)
{
- if (gpio_mode == AM335XGPIO_GPIO_MODE_INPUT) {
- AM335XGPIO_SET_REG_BITS(gpio_num, AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num));
- return;
- }
-
- if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW)
- set_gpio_value(gpio_num, 0);
- if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH)
- set_gpio_value(gpio_num, 1);
+ if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_OE_OFFSET) & BIT(gpio_config->gpio_num))
+ return AM335XGPIO_GPIO_MODE_INPUT;
- if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT ||
- gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW ||
- gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH) {
- AM335XGPIO_CLEAR_REG_BITS(gpio_num, AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num));
- }
+ /* Return output level too so that pin mode can be fully restored */
+ if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & BIT(gpio_config->gpio_num))
+ return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH;
+ return AM335XGPIO_GPIO_MODE_OUTPUT_LOW;
}
-static const char *get_gpio_mode_name(enum amx335gpio_gpio_mode gpio_mode)
+static const char *get_gpio_mode_name(enum amx335gpio_initial_gpio_mode gpio_mode)
{
switch (gpio_mode) {
case AM335XGPIO_GPIO_MODE_INPUT:
return "input";
- case AM335XGPIO_GPIO_MODE_OUTPUT:
- return "output";
case AM335XGPIO_GPIO_MODE_OUTPUT_LOW:
return "output (low)";
case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH:
return "output (high)";
- default:
- return "unknown";
+ }
+ return "unknown";
+}
+
+static void initialize_gpio(enum adapter_gpio_config_index idx)
+{
+ if (!is_gpio_config_valid(&adapter_gpio_config[idx]))
+ return;
+
+ initial_gpio_mode[idx] = get_gpio_mode(&adapter_gpio_config[idx]);
+ LOG_DEBUG("saved GPIO mode for %s (GPIO %d %d): %s",
+ adapter_gpio_get_name(idx), adapter_gpio_config[idx].chip_num, adapter_gpio_config[idx].gpio_num,
+ get_gpio_mode_name(initial_gpio_mode[idx]));
+
+ if (adapter_gpio_config[idx].pull != ADAPTER_GPIO_PULL_NONE) {
+ LOG_WARNING("am335xgpio does not support pull-up or pull-down settings (signal %s)",
+ adapter_gpio_get_name(idx));
+ }
+
+ switch (adapter_gpio_config[idx].init_state) {
+ case ADAPTER_GPIO_INIT_STATE_INACTIVE:
+ set_gpio_value(&adapter_gpio_config[idx], 0);
+ break;
+ case ADAPTER_GPIO_INIT_STATE_ACTIVE:
+ set_gpio_value(&adapter_gpio_config[idx], 1);
+ break;
+ case ADAPTER_GPIO_INIT_STATE_INPUT:
+ AM335XGPIO_SET_INPUT(&adapter_gpio_config[idx]);
+ break;
+ }
+
+ /* Direction for non push-pull is already set by set_gpio_value() */
+ if (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL)
+ AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);
+}
+
+static void restore_gpio(enum adapter_gpio_config_index idx)
+{
+ if (is_gpio_config_valid(&adapter_gpio_config[idx])) {
+ switch (initial_gpio_mode[idx]) {
+ case AM335XGPIO_GPIO_MODE_INPUT:
+ AM335XGPIO_SET_INPUT(&adapter_gpio_config[idx]);
+ break;
+ case AM335XGPIO_GPIO_MODE_OUTPUT_LOW:
+ AM335XGPIO_SET_LOW(&adapter_gpio_config[idx]);
+ AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);
+ break;
+ case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH:
+ AM335XGPIO_SET_HIGH(&adapter_gpio_config[idx]);
+ AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);
+ break;
+ }
}
}
static bb_value_t am335xgpio_read(void)
{
- return get_gpio_value(tdo_gpio) ? BB_HIGH : BB_LOW;
+ return get_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDO]) ? BB_HIGH : BB_LOW;
}
static int am335xgpio_write(int tck, int tms, int tdi)
{
- set_gpio_value(tdi_gpio, tdi);
- set_gpio_value(tms_gpio, tms);
- set_gpio_value(tck_gpio, tck); /* Write clock last */
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDI], tdi);
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TMS], tms);
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TCK], tck); /* Write clock last */
for (unsigned int i = 0; i < jtag_delay; ++i)
asm volatile ("");
@@ -202,8 +226,8 @@ static int am335xgpio_write(int tck, int tms, int tdi)
static int am335xgpio_swd_write(int swclk, int swdio)
{
- set_gpio_value(swdio_gpio, swdio);
- set_gpio_value(swclk_gpio, swclk); /* Write clock last */
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO], swdio);
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */
for (unsigned int i = 0; i < jtag_delay; ++i)
asm volatile ("");
@@ -214,49 +238,45 @@ static int am335xgpio_swd_write(int swclk, int swdio)
/* (1) assert or (0) deassert reset lines */
static int am335xgpio_reset(int trst, int srst)
{
- /* assume active low */
- if (is_gpio_valid(srst_gpio)) {
- if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL)
- set_gpio_mode(srst_gpio, srst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH);
- else
- set_gpio_mode(srst_gpio, srst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_INPUT);
- }
+ /* As the "adapter reset_config" command keeps the srst and trst gpio drive
+ * mode settings in sync we can use our standard set_gpio_value() function
+ * that honours drive mode and active low.
+ */
+ if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST]))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST], srst);
- /* assume active low */
- if (is_gpio_valid(trst_gpio)) {
- if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN)
- set_gpio_mode(trst_gpio, trst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_INPUT);
- else
- set_gpio_mode(trst_gpio, trst ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH);
- }
+ if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST]))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST], trst);
- LOG_DEBUG("am335xgpio_reset(%d, %d), trst_gpio: %d (%s), srst_gpio: %d (%s)",
+ LOG_DEBUG("am335xgpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d",
trst, srst,
- trst_gpio, get_gpio_mode_name(get_gpio_mode(trst_gpio)),
- srst_gpio, get_gpio_mode_name(get_gpio_mode(srst_gpio)));
+ adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].gpio_num,
+ adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].gpio_num);
return ERROR_OK;
}
static void am335xgpio_swdio_drive(bool is_output)
{
if (is_output) {
- set_gpio_value(swdio_dir_gpio, swdio_dir_is_active_high ? 1 : 0);
- set_gpio_mode(swdio_gpio, AM335XGPIO_GPIO_MODE_OUTPUT);
+ if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR]))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);
+ AM335XGPIO_SET_OUTPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);
} else {
- set_gpio_mode(swdio_gpio, AM335XGPIO_GPIO_MODE_INPUT);
- set_gpio_value(swdio_dir_gpio, swdio_dir_is_active_high ? 0 : 1);
+ AM335XGPIO_SET_INPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);
+ if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR]))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);
}
}
static int am335xgpio_swdio_read(void)
{
- return get_gpio_value(swdio_gpio);
+ return get_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);
}
static int am335xgpio_blink(int on)
{
- if (is_gpio_valid(led_gpio))
- set_gpio_value(led_gpio, (!on ^ led_is_active_high) ? 1 : 0);
+ if (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED]))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED], on);
return ERROR_OK;
}
@@ -294,144 +314,6 @@ static int am335xgpio_speed(int speed)
return ERROR_OK;
}
-COMMAND_HANDLER(am335xgpio_handle_jtag_gpionums)
-{
- if (CMD_ARGC == 4) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);
- } else if (CMD_ARGC != 0) {
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- command_print(CMD, "AM335x GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d",
- tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tck)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
-
- command_print(CMD, "AM335x GPIO config: tck = %d", tck_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tms)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);
-
- command_print(CMD, "AM335x GPIO config: tms = %d", tms_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tdo)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);
-
- command_print(CMD, "AM335x GPIO config: tdo = %d", tdo_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_tdi)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);
-
- command_print(CMD, "AM335x GPIO config: tdi = %d", tdi_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_srst)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);
-
- command_print(CMD, "AM335x GPIO config: srst = %d", srst_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_jtag_gpionum_trst)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);
-
- command_print(CMD, "AM335x GPIO config: trst = %d", trst_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_swd_gpionums)
-{
- if (CMD_ARGC == 2) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio);
- } else if (CMD_ARGC != 0) {
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- command_print(CMD, "AM335x GPIO config: swclk = %d, swdio = %d", swclk_gpio, swdio_gpio);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_swd_gpionum_swclk)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
-
- command_print(CMD, "AM335x GPIO config: swclk = %d", swclk_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_swd_gpionum_swdio)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio);
-
- command_print(CMD, "AM335x GPIO config: swdio = %d", swdio_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_swd_gpionum_swdio_dir)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_dir_gpio);
-
- command_print(CMD, "AM335x GPIO config: swdio_dir = %d", swdio_dir_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_swd_dir_output_state)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_BOOL(CMD_ARGV[0], swdio_dir_is_active_high, "high", "low");
-
- command_print(CMD, "AM335x GPIO config: swdio_dir_output_state = %s", swdio_dir_is_active_high ? "high" : "low");
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_gpionum_led)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], led_gpio);
-
- command_print(CMD, "AM335x GPIO config: led = %d", led_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_led_on_state)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_BOOL(CMD_ARGV[0], led_is_active_high, "high", "low");
-
- command_print(CMD, "AM335x GPIO config: led_on_state = %s", led_is_active_high ? "high" : "low");
- return ERROR_OK;
-}
-
COMMAND_HANDLER(am335xgpio_handle_speed_coeffs)
{
if (CMD_ARGC == 2) {
@@ -446,104 +328,6 @@ COMMAND_HANDLER(am335xgpio_handle_speed_coeffs)
static const struct command_registration am335xgpio_subcommand_handlers[] = {
{
- .name = "jtag_nums",
- .handler = am335xgpio_handle_jtag_gpionums,
- .mode = COMMAND_CONFIG,
- .help = "gpio numbers for tck, tms, tdi, tdo (in that order).",
- .usage = "[tck tms tdi tdo]",
- },
- {
- .name = "tck_num",
- .handler = am335xgpio_handle_jtag_gpionum_tck,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for tck.",
- .usage = "[tck]",
- },
- {
- .name = "tms_num",
- .handler = am335xgpio_handle_jtag_gpionum_tms,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for tms.",
- .usage = "[tms]",
- },
- {
- .name = "tdo_num",
- .handler = am335xgpio_handle_jtag_gpionum_tdo,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for tdo.",
- .usage = "[tdo]",
- },
- {
- .name = "tdi_num",
- .handler = am335xgpio_handle_jtag_gpionum_tdi,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for tdi.",
- .usage = "[tdi]",
- },
- {
- .name = "swd_nums",
- .handler = am335xgpio_handle_swd_gpionums,
- .mode = COMMAND_CONFIG,
- .help = "gpio numbers for swclk, swdio (in that order).",
- .usage = "[swclk swdio]",
- },
- {
- .name = "swclk_num",
- .handler = am335xgpio_handle_swd_gpionum_swclk,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for swclk.",
- .usage = "[swclk]",
- },
- {
- .name = "swdio_num",
- .handler = am335xgpio_handle_swd_gpionum_swdio,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for swdio.",
- .usage = "[swdio]",
- },
- {
- .name = "swdio_dir_num",
- .handler = am335xgpio_handle_swd_gpionum_swdio_dir,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for swdio direction control pin.",
- .usage = "[swdio_dir]",
- },
- {
- .name = "swdio_dir_output_state",
- .handler = am335xgpio_handle_swd_dir_output_state,
- .mode = COMMAND_CONFIG,
- .help = "required state for swdio_dir pin to select SWDIO buffer to be output.",
- .usage = "['off'|'on']",
- },
- {
- .name = "srst_num",
- .handler = am335xgpio_handle_jtag_gpionum_srst,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for srst.",
- .usage = "[srst]",
- },
- {
- .name = "trst_num",
- .handler = am335xgpio_handle_jtag_gpionum_trst,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for trst.",
- .usage = "[trst]",
- },
- {
- .name = "led_num",
- .handler = am335xgpio_handle_gpionum_led,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for led.",
- .usage = "[led]",
- },
- {
- .name = "led_on_state",
- .handler = am335xgpio_handle_led_on_state,
- .mode = COMMAND_CONFIG,
- .help = "required state for led pin to turn on LED.",
- .usage = "['off'|'on']",
- },
- {
.name = "speed_coeffs",
.handler = am335xgpio_handle_speed_coeffs,
.mode = COMMAND_CONFIG,
@@ -573,32 +357,40 @@ static struct jtag_interface am335xgpio_interface = {
static bool am335xgpio_jtag_mode_possible(void)
{
- if (!is_gpio_valid(tck_gpio))
+ if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TCK]))
return false;
- if (!is_gpio_valid(tms_gpio))
+ if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TMS]))
return false;
- if (!is_gpio_valid(tdi_gpio))
+ if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDI]))
return false;
- if (!is_gpio_valid(tdo_gpio))
+ if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDO]))
return false;
return true;
}
static bool am335xgpio_swd_mode_possible(void)
{
- if (!is_gpio_valid(swclk_gpio))
+ if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK]))
return false;
- if (!is_gpio_valid(swdio_gpio))
+ if (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]))
return false;
return true;
}
-static int am335xgpio_init(void)
+static void am335xgpio_munmap(void)
{
- bitbang_interface = &am335xgpio_bitbang;
+ for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_CHIPS && am335xgpio_gpio_chip_mmap_addr[i] != MAP_FAILED; ++i)
+ if (munmap((void *)am335xgpio_gpio_chip_mmap_addr[i], sysconf(_SC_PAGE_SIZE)) < 0)
+ LOG_ERROR("Cannot unmap GPIO memory for chip %d: %s", i, strerror(errno));
+}
+static int am335xgpio_init(void)
+{
LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver");
+ bitbang_interface = &am335xgpio_bitbang;
+ adapter_gpio_config = adapter_gpio_get_config();
+
if (transport_is_jtag() && !am335xgpio_jtag_mode_possible()) {
LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
return ERROR_JTAG_INIT_FAILED;
@@ -619,99 +411,81 @@ static int am335xgpio_init(void)
return ERROR_JTAG_INIT_FAILED;
}
- for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_PORTS; ++i) {
- am335xgpio_gpio_port_mmap_addr[i] = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
- MAP_SHARED, dev_mem_fd, am335xgpio_gpio_port_hw_addr[i]);
+ for (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_CHIPS; ++i) {
+ am335xgpio_gpio_chip_mmap_addr[i] = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
+ MAP_SHARED, dev_mem_fd, am335xgpio_gpio_chip_hw_addr[i]);
- if (am335xgpio_gpio_port_mmap_addr[i] == MAP_FAILED) {
+ if (am335xgpio_gpio_chip_mmap_addr[i] == MAP_FAILED) {
LOG_ERROR("mmap: %s", strerror(errno));
+ am335xgpio_munmap();
close(dev_mem_fd);
return ERROR_JTAG_INIT_FAILED;
}
}
+ close(dev_mem_fd);
- /*
- * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST as outputs.
- * Drive TDI and TCK low, and TMS high.
+ /* Configure JTAG/SWD signals. Default directions and initial states are handled
+ * by adapter.c and "adapter gpio" command.
*/
if (transport_is_jtag()) {
- tdo_gpio_mode = get_gpio_mode(tdo_gpio);
- tdi_gpio_mode = get_gpio_mode(tdi_gpio);
- tck_gpio_mode = get_gpio_mode(tck_gpio);
- tms_gpio_mode = get_gpio_mode(tms_gpio);
- LOG_DEBUG("saved GPIO mode for tdo (GPIO #%d): %s", tdo_gpio, get_gpio_mode_name(tdo_gpio_mode));
- LOG_DEBUG("saved GPIO mode for tdi (GPIO #%d): %s", tdi_gpio, get_gpio_mode_name(tdi_gpio_mode));
- LOG_DEBUG("saved GPIO mode for tck (GPIO #%d): %s", tck_gpio, get_gpio_mode_name(tck_gpio_mode));
- LOG_DEBUG("saved GPIO mode for tms (GPIO #%d): %s", tms_gpio, get_gpio_mode_name(tms_gpio_mode));
-
- set_gpio_mode(tdo_gpio, AM335XGPIO_GPIO_MODE_INPUT);
- set_gpio_mode(tdi_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
- set_gpio_mode(tms_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_HIGH);
- set_gpio_mode(tck_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
-
- if (is_gpio_valid(trst_gpio)) {
- trst_gpio_mode = get_gpio_mode(trst_gpio);
- LOG_DEBUG("saved GPIO mode for trst (GPIO #%d): %s", trst_gpio, get_gpio_mode_name(trst_gpio_mode));
- }
+ initialize_gpio(ADAPTER_GPIO_IDX_TDO);
+ initialize_gpio(ADAPTER_GPIO_IDX_TDI);
+ initialize_gpio(ADAPTER_GPIO_IDX_TMS);
+ initialize_gpio(ADAPTER_GPIO_IDX_TCK);
+ initialize_gpio(ADAPTER_GPIO_IDX_TRST);
}
if (transport_is_swd()) {
- swclk_gpio_mode = get_gpio_mode(swclk_gpio);
- swdio_gpio_mode = get_gpio_mode(swdio_gpio);
- LOG_DEBUG("saved GPIO mode for swclk (GPIO #%d): %s", swclk_gpio, get_gpio_mode_name(swclk_gpio_mode));
- LOG_DEBUG("saved GPIO mode for swdio (GPIO #%d): %s", swdio_gpio, get_gpio_mode_name(swdio_gpio_mode));
- if (is_gpio_valid(swdio_dir_gpio)) {
- swdio_dir_gpio_mode = get_gpio_mode(swdio_dir_gpio);
- LOG_DEBUG("saved GPIO mode for swdio_dir (GPIO #%d): %s",
- swdio_dir_gpio, get_gpio_mode_name(swdio_dir_gpio_mode));
- set_gpio_mode(swdio_dir_gpio,
- swdio_dir_is_active_high ? AM335XGPIO_GPIO_MODE_OUTPUT_HIGH : AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
-
+ /* swdio and its buffer should be initialized in the order that prevents
+ * two outputs from being connected together. This will occur if the
+ * swdio GPIO of the AM335x is configured as an output while its
+ * external buffer is configured to send the swdio signal from the
+ * target to the AM335x.
+ */
+ if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) {
+ initialize_gpio(ADAPTER_GPIO_IDX_SWDIO);
+ initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ } else {
+ initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ initialize_gpio(ADAPTER_GPIO_IDX_SWDIO);
}
- set_gpio_mode(swdio_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
- set_gpio_mode(swclk_gpio, AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
- }
- if (is_gpio_valid(srst_gpio)) {
- srst_gpio_mode = get_gpio_mode(srst_gpio);
- LOG_DEBUG("saved GPIO mode for srst (GPIO #%d): %s", srst_gpio, get_gpio_mode_name(srst_gpio_mode));
+ initialize_gpio(ADAPTER_GPIO_IDX_SWCLK);
}
- if (is_gpio_valid(led_gpio)) {
- led_gpio_mode = get_gpio_mode(led_gpio);
- LOG_DEBUG("saved GPIO mode for led (GPIO #%d): %s", led_gpio, get_gpio_mode_name(led_gpio_mode));
- set_gpio_mode(led_gpio,
- led_is_active_high ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH);
- }
+ initialize_gpio(ADAPTER_GPIO_IDX_SRST);
+ initialize_gpio(ADAPTER_GPIO_IDX_LED);
- /* Set GPIO modes for TRST and SRST and make both inactive */
- am335xgpio_reset(0, 0);
return ERROR_OK;
}
static int am335xgpio_quit(void)
{
if (transport_is_jtag()) {
- set_gpio_mode(tdo_gpio, tdo_gpio_mode);
- set_gpio_mode(tdi_gpio, tdi_gpio_mode);
- set_gpio_mode(tck_gpio, tck_gpio_mode);
- set_gpio_mode(tms_gpio, tms_gpio_mode);
- if (is_gpio_valid(trst_gpio))
- set_gpio_mode(trst_gpio, trst_gpio_mode);
+ restore_gpio(ADAPTER_GPIO_IDX_TDO);
+ restore_gpio(ADAPTER_GPIO_IDX_TDI);
+ restore_gpio(ADAPTER_GPIO_IDX_TMS);
+ restore_gpio(ADAPTER_GPIO_IDX_TCK);
+ restore_gpio(ADAPTER_GPIO_IDX_TRST);
}
if (transport_is_swd()) {
- set_gpio_mode(swclk_gpio, swclk_gpio_mode);
- set_gpio_mode(swdio_gpio, swdio_gpio_mode);
- if (is_gpio_valid(swdio_dir_gpio))
- set_gpio_mode(swdio_dir_gpio, swdio_dir_gpio_mode);
+ /* Restore swdio/swdio_dir to their initial modes, even if that means
+ * connecting two outputs. Begin by making swdio an input so that the
+ * current and final states of swdio and swdio_dir do not have to be
+ * considered to calculate the safe restoration order.
+ */
+ AM335XGPIO_SET_INPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);
+ restore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ restore_gpio(ADAPTER_GPIO_IDX_SWDIO);
+
+ restore_gpio(ADAPTER_GPIO_IDX_SWCLK);
}
- if (is_gpio_valid(srst_gpio))
- set_gpio_mode(srst_gpio, srst_gpio_mode);
+ restore_gpio(ADAPTER_GPIO_IDX_SRST);
+ restore_gpio(ADAPTER_GPIO_IDX_LED);
- if (is_gpio_valid(led_gpio))
- set_gpio_mode(led_gpio, led_gpio_mode);
+ am335xgpio_munmap();
return ERROR_OK;
}
diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c
index c204f23..a4c8f32 100644
--- a/src/jtag/drivers/amt_jtagaccel.c
+++ b/src/jtag/drivers/amt_jtagaccel.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c
index 7033789..a3e9e17 100644
--- a/src/jtag/drivers/arm-jtag-ew.c
+++ b/src/jtag/drivers/arm-jtag-ew.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Dimitar Dimitrov <dinuxbg@gmail.com> *
* based on Dominic Rath's and Benedikt Sauter's usbprog.c *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/at91rm9200.c b/src/jtag/drivers/at91rm9200.c
index 7bb5d85..08daa00 100644
--- a/src/jtag/drivers/at91rm9200.c
+++ b/src/jtag/drivers/at91rm9200.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Anders Larsen *
* al@alarsen.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c
index 22d237f..bd44fca 100644
--- a/src/jtag/drivers/bcm2835gpio.c
+++ b/src/jtag/drivers/bcm2835gpio.c
@@ -1,28 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Paul Fertser, fercerpav@gmail.com *
* *
* Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au *
* Based on at91rm9200.c (c) Anders Larsen *
* and RPi GPIO examples by Gert van Loo & Dom *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include <jtag/adapter.h>
#include <jtag/interface.h>
#include <transport/transport.h>
#include "bitbang.h"
@@ -35,79 +25,142 @@ uint32_t bcm2835_peri_base = 0x20000000;
#define BCM2835_PADS_GPIO_0_27 (bcm2835_peri_base + 0x100000)
#define BCM2835_PADS_GPIO_0_27_OFFSET (0x2c / 4)
+/* See "GPIO Function Select Registers (GPFSELn)" in "Broadcom BCM2835 ARM Peripherals" datasheet. */
+#define BCM2835_GPIO_MODE_INPUT 0
+#define BCM2835_GPIO_MODE_OUTPUT 1
+
/* GPIO setup macros */
#define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7)
#define INP_GPIO(g) do { *(pio_base+((g)/10)) &= ~(7<<(((g)%10)*3)); } while (0)
#define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \
INP_GPIO(g); \
*(pio_base+((g)/10)) |= ((m)<<(((g)%10)*3)); } while (0)
-#define OUT_GPIO(g) SET_MODE_GPIO(g, 1)
+#define OUT_GPIO(g) SET_MODE_GPIO(g, BCM2835_GPIO_MODE_OUTPUT)
#define GPIO_SET (*(pio_base+7)) /* sets bits which are 1, ignores bits which are 0 */
#define GPIO_CLR (*(pio_base+10)) /* clears bits which are 1, ignores bits which are 0 */
#define GPIO_LEV (*(pio_base+13)) /* current level of the pin */
static int dev_mem_fd;
-static volatile uint32_t *pio_base;
-
-static bb_value_t bcm2835gpio_read(void);
-static int bcm2835gpio_write(int tck, int tms, int tdi);
-
-static int bcm2835_swdio_read(void);
-static void bcm2835_swdio_drive(bool is_output);
-static int bcm2835gpio_swd_write(int swclk, int swdio);
-
-static int bcm2835gpio_init(void);
-static int bcm2835gpio_quit(void);
-
-static struct bitbang_interface bcm2835gpio_bitbang = {
- .read = bcm2835gpio_read,
- .write = bcm2835gpio_write,
- .swdio_read = bcm2835_swdio_read,
- .swdio_drive = bcm2835_swdio_drive,
- .swd_write = bcm2835gpio_swd_write,
- .blink = NULL
-};
-
-/* GPIO numbers for each signal. Negative values are invalid */
-static int tck_gpio = -1;
-static int tck_gpio_mode;
-static int tms_gpio = -1;
-static int tms_gpio_mode;
-static int tdi_gpio = -1;
-static int tdi_gpio_mode;
-static int tdo_gpio = -1;
-static int tdo_gpio_mode;
-static int trst_gpio = -1;
-static int trst_gpio_mode;
-static int srst_gpio = -1;
-static int srst_gpio_mode;
-static int swclk_gpio = -1;
-static int swclk_gpio_mode;
-static int swdio_gpio = -1;
-static int swdio_gpio_mode;
-static int swdio_dir_gpio = -1;
-static int swdio_dir_gpio_mode;
+static volatile uint32_t *pio_base = MAP_FAILED;
+static volatile uint32_t *pads_base = MAP_FAILED;
/* Transition delay coefficients */
static int speed_coeff = 113714;
static int speed_offset = 28;
static unsigned int jtag_delay;
-static int is_gpio_valid(int gpio)
+static const struct adapter_gpio_config *adapter_gpio_config;
+static struct initial_gpio_state {
+ unsigned int mode;
+ unsigned int output_level;
+} initial_gpio_state[ADAPTER_GPIO_IDX_NUM];
+static uint32_t initial_drive_strength_etc;
+
+static bool is_gpio_config_valid(enum adapter_gpio_config_index idx)
+{
+ /* Only chip 0 is supported, accept unset value (-1) too */
+ return adapter_gpio_config[idx].chip_num >= -1
+ && adapter_gpio_config[idx].chip_num <= 0
+ && adapter_gpio_config[idx].gpio_num >= 0
+ && adapter_gpio_config[idx].gpio_num <= 31;
+}
+
+static void set_gpio_value(const struct adapter_gpio_config *gpio_config, int value)
+{
+ value = value ^ (gpio_config->active_low ? 1 : 0);
+ switch (gpio_config->drive) {
+ case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:
+ if (value)
+ GPIO_SET = 1 << gpio_config->gpio_num;
+ else
+ GPIO_CLR = 1 << gpio_config->gpio_num;
+ /* For performance reasons assume the GPIO is already set as an output
+ * and therefore the call can be omitted here.
+ */
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:
+ if (value) {
+ INP_GPIO(gpio_config->gpio_num);
+ } else {
+ GPIO_CLR = 1 << gpio_config->gpio_num;
+ OUT_GPIO(gpio_config->gpio_num);
+ }
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
+ if (value) {
+ GPIO_SET = 1 << gpio_config->gpio_num;
+ OUT_GPIO(gpio_config->gpio_num);
+ } else {
+ INP_GPIO(gpio_config->gpio_num);
+ }
+ break;
+ }
+}
+
+static void restore_gpio(enum adapter_gpio_config_index idx)
+{
+ if (is_gpio_config_valid(idx)) {
+ SET_MODE_GPIO(adapter_gpio_config[idx].gpio_num, initial_gpio_state[idx].mode);
+ if (initial_gpio_state[idx].mode == BCM2835_GPIO_MODE_OUTPUT) {
+ if (initial_gpio_state[idx].output_level)
+ GPIO_SET = 1 << adapter_gpio_config[idx].gpio_num;
+ else
+ GPIO_CLR = 1 << adapter_gpio_config[idx].gpio_num;
+ }
+ }
+}
+
+static void initialize_gpio(enum adapter_gpio_config_index idx)
{
- return gpio >= 0 && gpio <= 31;
+ if (!is_gpio_config_valid(idx))
+ return;
+
+ initial_gpio_state[idx].mode = MODE_GPIO(adapter_gpio_config[idx].gpio_num);
+ unsigned int shift = adapter_gpio_config[idx].gpio_num;
+ initial_gpio_state[idx].output_level = (GPIO_LEV >> shift) & 1;
+ LOG_DEBUG("saved GPIO mode for %s (GPIO %d %d): %d",
+ adapter_gpio_get_name(idx), adapter_gpio_config[idx].chip_num, adapter_gpio_config[idx].gpio_num,
+ initial_gpio_state[idx].mode);
+
+ if (adapter_gpio_config[idx].pull != ADAPTER_GPIO_PULL_NONE) {
+ LOG_WARNING("BCM2835 GPIO does not support pull-up or pull-down settings (signal %s)",
+ adapter_gpio_get_name(idx));
+ }
+
+ switch (adapter_gpio_config[idx].init_state) {
+ case ADAPTER_GPIO_INIT_STATE_INACTIVE:
+ set_gpio_value(&adapter_gpio_config[idx], 0);
+ break;
+ case ADAPTER_GPIO_INIT_STATE_ACTIVE:
+ set_gpio_value(&adapter_gpio_config[idx], 1);
+ break;
+ case ADAPTER_GPIO_INIT_STATE_INPUT:
+ INP_GPIO(adapter_gpio_config[idx].gpio_num);
+ break;
+ }
+
+ /* 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);
}
static bb_value_t bcm2835gpio_read(void)
{
- return (GPIO_LEV & 1<<tdo_gpio) ? BB_HIGH : BB_LOW;
+ unsigned int shift = adapter_gpio_config[ADAPTER_GPIO_IDX_TDO].gpio_num;
+ uint32_t value = (GPIO_LEV >> shift) & 1;
+ return value ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_TDO].active_low ? BB_HIGH : BB_LOW);
+
}
static int bcm2835gpio_write(int tck, int tms, int tdi)
{
- uint32_t set = tck<<tck_gpio | tms<<tms_gpio | tdi<<tdi_gpio;
- uint32_t clear = !tck<<tck_gpio | !tms<<tms_gpio | !tdi<<tdi_gpio;
+ uint32_t set = tck << adapter_gpio_config[ADAPTER_GPIO_IDX_TCK].gpio_num |
+ tms << adapter_gpio_config[ADAPTER_GPIO_IDX_TMS].gpio_num |
+ tdi << adapter_gpio_config[ADAPTER_GPIO_IDX_TDI].gpio_num;
+ uint32_t clear = !tck << adapter_gpio_config[ADAPTER_GPIO_IDX_TCK].gpio_num |
+ !tms << adapter_gpio_config[ADAPTER_GPIO_IDX_TMS].gpio_num |
+ !tdi << adapter_gpio_config[ADAPTER_GPIO_IDX_TDI].gpio_num;
GPIO_SET = set;
GPIO_CLR = clear;
@@ -118,10 +171,16 @@ static int bcm2835gpio_write(int tck, int tms, int tdi)
return ERROR_OK;
}
-static int bcm2835gpio_swd_write(int swclk, int swdio)
+/* Requires push-pull drive mode for swclk and swdio */
+static int bcm2835gpio_swd_write_fast(int swclk, int swdio)
{
- uint32_t set = swclk << swclk_gpio | swdio << swdio_gpio;
- uint32_t clear = !swclk << swclk_gpio | !swdio << swdio_gpio;
+ swclk = swclk ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].active_low ? 1 : 0);
+ swdio = swdio ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].active_low ? 1 : 0);
+
+ uint32_t set = swclk << adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].gpio_num |
+ swdio << adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num;
+ uint32_t clear = !swclk << adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].gpio_num |
+ !swdio << adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num;
GPIO_SET = set;
GPIO_CLR = clear;
@@ -132,55 +191,62 @@ static int bcm2835gpio_swd_write(int swclk, int swdio)
return ERROR_OK;
}
-/* (1) assert or (0) deassert reset lines */
-static int bcm2835gpio_reset(int trst, int srst)
+/* Generic mode that works for open-drain/open-source drive modes, but slower */
+static int bcm2835gpio_swd_write_generic(int swclk, int swdio)
{
- uint32_t set = 0;
- uint32_t clear = 0;
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO], swdio);
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */
- if (is_gpio_valid(trst_gpio)) {
- set |= !trst<<trst_gpio;
- clear |= trst<<trst_gpio;
- }
+ for (unsigned int i = 0; i < jtag_delay; ++i)
+ asm volatile ("");
- if (is_gpio_valid(srst_gpio)) {
- set |= !srst<<srst_gpio;
- clear |= srst<<srst_gpio;
- }
+ return ERROR_OK;
+}
- GPIO_SET = set;
- GPIO_CLR = clear;
+/* (1) assert or (0) deassert reset lines */
+static int bcm2835gpio_reset(int trst, int srst)
+{
+ /* As the "adapter reset_config" command keeps the srst and trst gpio drive
+ * mode settings in sync we can use our standard set_gpio_value() function
+ * that honours drive mode and active low.
+ */
+ if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SRST))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST], srst);
+ if (is_gpio_config_valid(ADAPTER_GPIO_IDX_TRST))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST], trst);
+
+ LOG_DEBUG("BCM2835 GPIO: bcm2835gpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d",
+ trst, srst,
+ adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].gpio_num,
+ adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].gpio_num);
return ERROR_OK;
}
static void bcm2835_swdio_drive(bool is_output)
{
- if (is_gpio_valid(swdio_dir_gpio)) {
- if (is_output) {
- GPIO_SET = 1 << swdio_dir_gpio;
- OUT_GPIO(swdio_gpio);
- } else {
- INP_GPIO(swdio_gpio);
- GPIO_CLR = 1 << swdio_dir_gpio;
- }
+ if (is_output) {
+ if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);
+ OUT_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);
} else {
- if (is_output)
- OUT_GPIO(swdio_gpio);
- else
- INP_GPIO(swdio_gpio);
+ INP_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);
+ if (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);
}
}
static int bcm2835_swdio_read(void)
{
- return !!(GPIO_LEV & 1 << swdio_gpio);
+ unsigned int shift = adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num;
+ uint32_t value = (GPIO_LEV >> shift) & 1;
+ return value ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].active_low ? 1 : 0);
}
static int bcm2835gpio_khz(int khz, int *jtag_speed)
{
if (!khz) {
- LOG_DEBUG("RCLK not supported");
+ LOG_DEBUG("BCM2835 GPIO: RCLK not supported");
return ERROR_FAIL;
}
*jtag_speed = speed_coeff/khz - speed_offset;
@@ -201,121 +267,6 @@ static int bcm2835gpio_speed(int speed)
return ERROR_OK;
}
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionums)
-{
- if (CMD_ARGC == 4) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);
- } else if (CMD_ARGC != 0) {
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- command_print(CMD,
- "BCM2835 GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d",
- tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tck)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
-
- command_print(CMD, "BCM2835 GPIO config: tck = %d", tck_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tms)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);
-
- command_print(CMD, "BCM2835 GPIO config: tms = %d", tms_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdo)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);
-
- command_print(CMD, "BCM2835 GPIO config: tdo = %d", tdo_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdi)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);
-
- command_print(CMD, "BCM2835 GPIO config: tdi = %d", tdi_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_srst)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);
-
- command_print(CMD, "BCM2835 GPIO config: srst = %d", srst_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_trst)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);
-
- command_print(CMD, "BCM2835 GPIO config: trst = %d", trst_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionums)
-{
- if (CMD_ARGC == 2) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio);
- } else if (CMD_ARGC != 0) {
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- command_print(CMD,
- "BCM2835 GPIO nums: swclk = %d, swdio = %d",
- swclk_gpio, swdio_gpio);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swclk)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
-
- command_print(CMD, "BCM2835 num: swclk = %d", swclk_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swdio)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio);
-
- command_print(CMD, "BCM2835 num: swdio = %d", swdio_gpio);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(bcm2835gpio_handle_swd_dir_gpionum_swdio)
-{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_dir_gpio);
-
- command_print(CMD, "BCM2835 num: swdio_dir = %d", swdio_dir_gpio);
- return ERROR_OK;
-}
-
COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs)
{
if (CMD_ARGC == 2) {
@@ -340,83 +291,6 @@ COMMAND_HANDLER(bcm2835gpio_handle_peripheral_base)
static const struct command_registration bcm2835gpio_subcommand_handlers[] = {
{
- .name = "jtag_nums",
- .handler = &bcm2835gpio_handle_jtag_gpionums,
- .mode = COMMAND_CONFIG,
- .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)",
- .usage = "[tck tms tdi tdo]",
- },
- {
- .name = "tck_num",
- .handler = &bcm2835gpio_handle_jtag_gpionum_tck,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for tck.",
- .usage = "[tck]",
- },
- {
- .name = "tms_num",
- .handler = &bcm2835gpio_handle_jtag_gpionum_tms,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for tms.",
- .usage = "[tms]",
- },
- {
- .name = "tdo_num",
- .handler = &bcm2835gpio_handle_jtag_gpionum_tdo,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for tdo.",
- .usage = "[tdo]",
- },
- {
- .name = "tdi_num",
- .handler = &bcm2835gpio_handle_jtag_gpionum_tdi,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for tdi.",
- .usage = "[tdi]",
- },
- {
- .name = "swd_nums",
- .handler = &bcm2835gpio_handle_swd_gpionums,
- .mode = COMMAND_CONFIG,
- .help = "gpio numbers for swclk, swdio. (in that order)",
- .usage = "[swclk swdio]",
- },
- {
- .name = "swclk_num",
- .handler = &bcm2835gpio_handle_swd_gpionum_swclk,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for swclk.",
- .usage = "[swclk]",
- },
- {
- .name = "swdio_num",
- .handler = &bcm2835gpio_handle_swd_gpionum_swdio,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for swdio.",
- .usage = "[swdio]",
- },
- {
- .name = "swdio_dir_num",
- .handler = &bcm2835gpio_handle_swd_dir_gpionum_swdio,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for swdio direction control pin (set=output mode, clear=input mode)",
- .usage = "[swdio_dir]",
- },
- {
- .name = "srst_num",
- .handler = &bcm2835gpio_handle_jtag_gpionum_srst,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for srst.",
- .usage = "[srst]",
- },
- {
- .name = "trst_num",
- .handler = &bcm2835gpio_handle_jtag_gpionum_trst,
- .mode = COMMAND_CONFIG,
- .help = "gpio number for trst.",
- .usage = "[trst]",
- },
- {
.name = "speed_coeffs",
.handler = &bcm2835gpio_handle_speed_coeffs,
.mode = COMMAND_CONFIG,
@@ -445,57 +319,65 @@ static const struct command_registration bcm2835gpio_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
-static const char * const bcm2835_transports[] = { "jtag", "swd", NULL };
-
-static struct jtag_interface bcm2835gpio_interface = {
- .supported = DEBUG_CAP_TMS_SEQ,
- .execute_queue = bitbang_execute_queue,
-};
-
-struct adapter_driver bcm2835gpio_adapter_driver = {
- .name = "bcm2835gpio",
- .transports = bcm2835_transports,
- .commands = bcm2835gpio_command_handlers,
-
- .init = bcm2835gpio_init,
- .quit = bcm2835gpio_quit,
- .reset = bcm2835gpio_reset,
- .speed = bcm2835gpio_speed,
- .khz = bcm2835gpio_khz,
- .speed_div = bcm2835gpio_speed_div,
-
- .jtag_ops = &bcm2835gpio_interface,
- .swd_ops = &bitbang_swd,
-};
-
static bool bcm2835gpio_jtag_mode_possible(void)
{
- if (!is_gpio_valid(tck_gpio))
- return 0;
- if (!is_gpio_valid(tms_gpio))
- return 0;
- if (!is_gpio_valid(tdi_gpio))
- return 0;
- if (!is_gpio_valid(tdo_gpio))
- return 0;
- return 1;
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK))
+ return false;
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS))
+ return false;
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI))
+ return false;
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO))
+ return false;
+ return true;
}
static bool bcm2835gpio_swd_mode_possible(void)
{
- if (!is_gpio_valid(swclk_gpio))
- return 0;
- if (!is_gpio_valid(swdio_gpio))
- return 0;
- return 1;
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK))
+ return false;
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO))
+ return false;
+ return true;
}
-static int bcm2835gpio_init(void)
+static void bcm2835gpio_munmap(void)
{
- bitbang_interface = &bcm2835gpio_bitbang;
+ if (pio_base != MAP_FAILED) {
+ munmap((void *)pio_base, sysconf(_SC_PAGE_SIZE));
+ pio_base = MAP_FAILED;
+ }
+
+ if (pads_base != MAP_FAILED) {
+ munmap((void *)pads_base, sysconf(_SC_PAGE_SIZE));
+ pads_base = MAP_FAILED;
+ }
+}
+
+static int bcm2835gpio_blink(int on)
+{
+ if (is_gpio_config_valid(ADAPTER_GPIO_IDX_LED))
+ set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED], on);
+
+ return ERROR_OK;
+}
+
+static struct bitbang_interface bcm2835gpio_bitbang = {
+ .read = bcm2835gpio_read,
+ .write = bcm2835gpio_write,
+ .swdio_read = bcm2835_swdio_read,
+ .swdio_drive = bcm2835_swdio_drive,
+ .swd_write = bcm2835gpio_swd_write_generic,
+ .blink = bcm2835gpio_blink,
+};
+static int bcm2835gpio_init(void)
+{
LOG_INFO("BCM2835 GPIO JTAG/SWD bitbang driver");
+ bitbang_interface = &bcm2835gpio_bitbang;
+ adapter_gpio_config = adapter_gpio_get_config();
+
if (transport_is_jtag() && !bcm2835gpio_jtag_mode_possible()) {
LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
return ERROR_JTAG_INIT_FAILED;
@@ -525,71 +407,62 @@ static int bcm2835gpio_init(void)
return ERROR_JTAG_INIT_FAILED;
}
- static volatile uint32_t *pads_base;
pads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
MAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27);
if (pads_base == MAP_FAILED) {
LOG_ERROR("mmap: %s", strerror(errno));
+ bcm2835gpio_munmap();
close(dev_mem_fd);
return ERROR_JTAG_INIT_FAILED;
}
+ close(dev_mem_fd);
+
/* set 4mA drive strength, slew rate limited, hysteresis on */
+ initial_drive_strength_etc = pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] & 0x1f;
pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
- /*
- * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
- * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
+ /* Configure JTAG/SWD signals. Default directions and initial states are handled
+ * by adapter.c and "adapter gpio" command.
*/
if (transport_is_jtag()) {
- tdo_gpio_mode = MODE_GPIO(tdo_gpio);
- tdi_gpio_mode = MODE_GPIO(tdi_gpio);
- tck_gpio_mode = MODE_GPIO(tck_gpio);
- tms_gpio_mode = MODE_GPIO(tms_gpio);
-
- INP_GPIO(tdo_gpio);
-
- GPIO_CLR = 1<<tdi_gpio | 1<<tck_gpio;
- GPIO_SET = 1<<tms_gpio;
-
- OUT_GPIO(tdi_gpio);
- OUT_GPIO(tck_gpio);
- OUT_GPIO(tms_gpio);
-
- if (is_gpio_valid(trst_gpio)) {
- trst_gpio_mode = MODE_GPIO(trst_gpio);
- GPIO_SET = 1 << trst_gpio;
- OUT_GPIO(trst_gpio);
- }
+ initialize_gpio(ADAPTER_GPIO_IDX_TDO);
+ initialize_gpio(ADAPTER_GPIO_IDX_TDI);
+ initialize_gpio(ADAPTER_GPIO_IDX_TMS);
+ initialize_gpio(ADAPTER_GPIO_IDX_TCK);
+ initialize_gpio(ADAPTER_GPIO_IDX_TRST);
}
if (transport_is_swd()) {
- /* Make buffer an output before the GPIO connected to it */
- if (is_gpio_valid(swdio_dir_gpio)) {
- swdio_dir_gpio_mode = MODE_GPIO(swdio_dir_gpio);
- GPIO_SET = 1 << swdio_dir_gpio;
- OUT_GPIO(swdio_dir_gpio);
+ /* swdio and its buffer should be initialized in the order that prevents
+ * two outputs from being connected together. This will occur if the
+ * swdio GPIO of the AM335x is configured as an output while its
+ * external buffer is configured to send the swdio signal from the
+ * target to the AM335x.
+ */
+ if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) {
+ initialize_gpio(ADAPTER_GPIO_IDX_SWDIO);
+ initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ } else {
+ initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ initialize_gpio(ADAPTER_GPIO_IDX_SWDIO);
}
- swclk_gpio_mode = MODE_GPIO(swclk_gpio);
- swdio_gpio_mode = MODE_GPIO(swdio_gpio);
-
- GPIO_CLR = 1<<swdio_gpio | 1<<swclk_gpio;
-
- OUT_GPIO(swclk_gpio);
- OUT_GPIO(swdio_gpio);
- }
+ initialize_gpio(ADAPTER_GPIO_IDX_SWCLK);
- if (is_gpio_valid(srst_gpio)) {
- srst_gpio_mode = MODE_GPIO(srst_gpio);
- GPIO_SET = 1 << srst_gpio;
- OUT_GPIO(srst_gpio);
+ if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL &&
+ adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL) {
+ LOG_DEBUG("BCM2835 GPIO using fast mode for SWD write");
+ bcm2835gpio_bitbang.swd_write = bcm2835gpio_swd_write_fast;
+ } else {
+ LOG_DEBUG("BCM2835 GPIO using generic mode for SWD write");
+ bcm2835gpio_bitbang.swd_write = bcm2835gpio_swd_write_generic;
+ }
}
- LOG_DEBUG("saved pinmux settings: tck %d tms %d tdi %d "
- "tdo %d trst %d srst %d", tck_gpio_mode, tms_gpio_mode,
- tdi_gpio_mode, tdo_gpio_mode, trst_gpio_mode, srst_gpio_mode);
+ initialize_gpio(ADAPTER_GPIO_IDX_SRST);
+ initialize_gpio(ADAPTER_GPIO_IDX_LED);
return ERROR_OK;
}
@@ -597,24 +470,54 @@ static int bcm2835gpio_init(void)
static int bcm2835gpio_quit(void)
{
if (transport_is_jtag()) {
- SET_MODE_GPIO(tdo_gpio, tdo_gpio_mode);
- SET_MODE_GPIO(tdi_gpio, tdi_gpio_mode);
- SET_MODE_GPIO(tck_gpio, tck_gpio_mode);
- SET_MODE_GPIO(tms_gpio, tms_gpio_mode);
- if (is_gpio_valid(trst_gpio))
- SET_MODE_GPIO(trst_gpio, trst_gpio_mode);
+ restore_gpio(ADAPTER_GPIO_IDX_TDO);
+ restore_gpio(ADAPTER_GPIO_IDX_TDI);
+ restore_gpio(ADAPTER_GPIO_IDX_TCK);
+ restore_gpio(ADAPTER_GPIO_IDX_TMS);
+ restore_gpio(ADAPTER_GPIO_IDX_TRST);
}
if (transport_is_swd()) {
- SET_MODE_GPIO(swclk_gpio, swclk_gpio_mode);
- SET_MODE_GPIO(swdio_gpio, swdio_gpio_mode);
+ /* Restore swdio/swdio_dir to their initial modes, even if that means
+ * connecting two outputs. Begin by making swdio an input so that the
+ * current and final states of swdio and swdio_dir do not have to be
+ * considered to calculate the safe restoration order.
+ */
+ INP_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);
+ restore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ restore_gpio(ADAPTER_GPIO_IDX_SWDIO);
+ restore_gpio(ADAPTER_GPIO_IDX_SWCLK);
}
- if (is_gpio_valid(srst_gpio))
- SET_MODE_GPIO(srst_gpio, srst_gpio_mode);
+ restore_gpio(ADAPTER_GPIO_IDX_SRST);
+ restore_gpio(ADAPTER_GPIO_IDX_LED);
- if (is_gpio_valid(swdio_dir_gpio))
- SET_MODE_GPIO(swdio_dir_gpio, swdio_dir_gpio_mode);
+ /* Restore drive strength. MSB is password ("5A") */
+ pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5A000000 | initial_drive_strength_etc;
+ bcm2835gpio_munmap();
return ERROR_OK;
}
+
+
+static const char * const bcm2835_transports[] = { "jtag", "swd", NULL };
+
+static struct jtag_interface bcm2835gpio_interface = {
+ .supported = DEBUG_CAP_TMS_SEQ,
+ .execute_queue = bitbang_execute_queue,
+};
+struct adapter_driver bcm2835gpio_adapter_driver = {
+ .name = "bcm2835gpio",
+ .transports = bcm2835_transports,
+ .commands = bcm2835gpio_command_handlers,
+
+ .init = bcm2835gpio_init,
+ .quit = bcm2835gpio_quit,
+ .reset = bcm2835gpio_reset,
+ .speed = bcm2835gpio_speed,
+ .khz = bcm2835gpio_khz,
+ .speed_div = bcm2835gpio_speed_div,
+
+ .jtag_ops = &bcm2835gpio_interface,
+ .swd_ops = &bitbang_swd,
+};
diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c
index 78dcb29..d49e16f 100644
--- a/src/jtag/drivers/bitbang.c
+++ b/src/jtag/drivers/bitbang.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* 2014-12: Addition of the SWD protocol support is based on the initial work
diff --git a/src/jtag/drivers/bitbang.h b/src/jtag/drivers/bitbang.h
index bc2c506..4ea1cc0 100644
--- a/src/jtag/drivers/bitbang.h
+++ b/src/jtag/drivers/bitbang.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_BITBANG_H
diff --git a/src/jtag/drivers/bitq.c b/src/jtag/drivers/bitq.c
index 04fc78b..59e4f35 100644
--- a/src/jtag/drivers/bitq.c
+++ b/src/jtag/drivers/bitq.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Pavel Chromy *
* chromy@asix.cz *
-* *
-* This program is free software; you can redistribute it and/or modify *
-* it under the terms of the GNU General Public License as published by *
-* the Free Software Foundation; either version 2 of the License, or *
-* (at your option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, *
-* but WITHOUT ANY WARRANTY; without even the implied warranty of *
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-* GNU General Public License for more details. *
-* *
-* You should have received a copy of the GNU General Public License *
-* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/bitq.h b/src/jtag/drivers/bitq.h
index df6a08d..8e06fcf 100644
--- a/src/jtag/drivers/bitq.h
+++ b/src/jtag/drivers/bitq.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Pavel Chromy *
* chromy@asix.cz *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_BITQ_H
diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c
index 51ace61..03b48e6 100644
--- a/src/jtag/drivers/buspirate.c
+++ b/src/jtag/drivers/buspirate.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Michal Demin *
* based on usbprog.c and arm-jtag-ew.c *
* Several fixes by R. Diez in 2013. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index eaa65ab..e708d52 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2021 by Adrian Negreanu *
* groleo@gmail.com *
@@ -19,19 +21,6 @@
* *
* Copyright (C) 2013 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h
index 7c64d49..cf929b0 100644
--- a/src/jtag/drivers/cmsis_dap.h
+++ b/src/jtag/drivers/cmsis_dap.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
#ifndef OPENOCD_JTAG_DRIVERS_CMSIS_DAP_H
#define OPENOCD_JTAG_DRIVERS_CMSIS_DAP_H
diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c
index 819596b..a738200 100644
--- a/src/jtag/drivers/cmsis_dap_usb_bulk.c
+++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Mickaël Thomas *
* mickael9@gmail.com *
@@ -16,19 +18,6 @@
* *
* Copyright (C) 2013 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/cmsis_dap_usb_hid.c b/src/jtag/drivers/cmsis_dap_usb_hid.c
index 912ba39..592eb09 100644
--- a/src/jtag/drivers/cmsis_dap_usb_hid.c
+++ b/src/jtag/drivers/cmsis_dap_usb_hid.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Mickaël Thomas *
* mickael9@gmail.com *
@@ -16,19 +18,6 @@
* *
* Copyright (C) 2013 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c
index dbe3b08..409b800 100644
--- a/src/jtag/drivers/driver.c
+++ b/src/jtag/drivers/driver.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -11,19 +13,6 @@
* *
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c
index e66cb6b..1b1e573 100644
--- a/src/jtag/drivers/dummy.c
+++ b/src/jtag/drivers/dummy.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 by Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/ep93xx.c b/src/jtag/drivers/ep93xx.c
index 94d6550..393fc7e 100644
--- a/src/jtag/drivers/ep93xx.c
+++ b/src/jtag/drivers/ep93xx.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -35,7 +24,7 @@
static uint8_t output_value;
static int dev_mem_fd;
-static void *gpio_controller;
+static uint8_t *gpio_controller;
static volatile uint8_t *gpio_data_register;
static volatile uint8_t *gpio_data_direction_register;
@@ -121,19 +110,16 @@ static int ep93xx_reset(int trst, int srst)
static int set_gonk_mode(void)
{
- void *syscon;
- uint32_t devicecfg;
-
- syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
+ void *syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, dev_mem_fd, 0x80930000);
if (syscon == MAP_FAILED) {
LOG_ERROR("mmap: %s", strerror(errno));
return ERROR_JTAG_INIT_FAILED;
}
- devicecfg = *((volatile int *)(syscon + 0x80));
- *((volatile int *)(syscon + 0xc0)) = 0xaa;
- *((volatile int *)(syscon + 0x80)) = devicecfg | 0x08000000;
+ uint32_t devicecfg = *((volatile uint32_t *)((uintptr_t)syscon + 0x80));
+ *((volatile uint32_t *)((uintptr_t)syscon + 0xc0)) = 0xaa;
+ *((volatile uint32_t *)((uintptr_t)syscon + 0x80)) = devicecfg | 0x08000000;
munmap(syscon, 4096);
diff --git a/src/jtag/drivers/esp_usb_jtag.c b/src/jtag/drivers/esp_usb_jtag.c
new file mode 100644
index 0000000..65293ee
--- /dev/null
+++ b/src/jtag/drivers/esp_usb_jtag.c
@@ -0,0 +1,796 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * Espressif USB to Jtag adapter *
+ * Copyright (C) 2020 Espressif Systems (Shanghai) Co. Ltd. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <jtag/adapter.h>
+#include <jtag/interface.h>
+#include <helper/time_support.h>
+#include <helper/bits.h>
+#include "bitq.h"
+#include "libusb_helper.h"
+
+#define __packed __attribute__((packed))
+
+/*
+Holy Crap, it's protocol documentation, and it's even vendor-provided!
+
+A device that speaks this protocol has two endpoints intended for JTAG debugging: one
+OUT for the host to send encoded commands to, one IN from which the host can read any read
+TDO bits. The device will also respond to vendor-defined interface requests on ep0.
+
+The main communication method is over the IN/OUT endpoints. The commands that are expected
+on the OUT endpoint are one nibble wide and are processed high-nibble-first, low-nibble-second,
+and in the order the bytes come in. Commands are defined as follows:
+
+ bit 3 2 1 0
+CMD_CLK [ 0 cap tdi tms ]
+CMD_RST [ 1 0 0 srst ]
+CMD_FLUSH [ 1 0 1 0 ]
+CMD_RSV [ 1 0 1 1 ]
+CMD_REP [ 1 1 R1 R0 ]
+
+CMD_CLK sets the TDI and TMS lines to the value of `tdi` and `tms` and lowers, then raises, TCK. If
+`cap` is 1, the value of TDO is captured and can be retrieved over the IN endpoint. The bytes read from
+the IN endpoint specifically are these bits, with the lowest it in every byte captured first and the
+bytes returned in the order the data in them was captured. The durations of TCK being high / low can
+be set using the VEND_JTAG_SETDIV vendor-specific interface request.
+
+CMD_RST controls the SRST line; as soon as the command is processed, the SRST line will be set
+to the value of `srst`.
+
+CMD_FLUSH flushes the IN endpoint; zeroes will be added to the amount of bits in the endpoint until
+the payload is a multiple of bytes, and the data is offered to the host. If the IN endpoint has
+no data, this effectively becomes a no-op; the endpoint won't send any 0-byte payloads.
+
+CMD_RSV is reserved for future use.
+
+CMD_REP repeats the last command that is not CMD_REP. The amount of times a CMD_REP command will
+re-execute this command is (r1*2+r0)<<(2*n), where n is the amount of previous repeat commands executed
+since the command to be repeated.
+
+An example for CMD_REP: Say the host queues:
+1. CMD_CLK - This will execute one CMD_CLK.
+2. CMD_REP with r1=0 and r0=1 - This will execute 1. another (0*2+1)<<(2*0)=1 time.
+3. CMD_REP with r1=1 and r0=0 - This will execute 1. another (1*2+0)<<(2*1)=4 times.
+4. CMD_REP with r1=0 and r0=1 - This will execute 1. another (0*2+1)<<(2*2)=8 time.
+5. CMD_FLUSH - This will flush the IN pipeline.
+6. CMD_CLK - This will execute one CMD_CLK
+7. CMD_REP with r1=1 and r0=0 - This will execute 6. another (1*2+0)<<(2*0)=2 times.
+8. CMD_FLUSH - This will flush the IN pipeline.
+
+Note that the net effect of the repetitions is that command 1 is executed (1+1+4+8=) 14 times and
+command 6 is executed (1+2=) 3 times.
+
+Note that the device only has a fairly limited amount of endpoint RAM. It's probably best to keep
+an eye on the amount of bytes that are supposed to be in the IN endpoint and grab those before stuffing
+more commands into the OUT endpoint: the OUT endpoint will not accept any more commands (writes will
+time out) when the IN endpoint buffers are all filled up.
+
+The device also supports some vendor-specific interface requests. These requests are sent as control
+transfers on endpoint 0 to the JTAG endpoint. Note that these commands bypass the data in the OUT
+endpoint; if timing is important, it's important that this endpoint is empty. This can be done by
+e.g sending one CMD_CLK capturing TDI, then one CMD_FLUSH, then waiting until the bit appears on the
+IN endpoint.
+
+bmRequestType bRequest wValue wIndex wLength Data
+01000000b VEND_JTAG_SETDIV [divide] interface 0 None
+01000000b VEND_JTAG_SETIO [iobits] interface 0 None
+11000000b VEND_JTAG_GETTDO 0 interface 1 [iostate]
+10000000b GET_DESCRIPTOR(6) 0x2000 0 256 [jtag cap desc]
+
+VEND_JTAG_SETDIV indirectly controls the speed of the TCK clock. The value written here is the length
+of a TCK cycle, in ticks of the adapters base clock. Both the base clock value as well as the
+minimum and maximum divider can be read from the jtag capabilities descriptor, as explained
+below. Note that this should not be set to a value outside of the range described there,
+otherwise results are undefined.
+
+VEND_JTAG_SETIO can be controlled to directly set the IO pins. The format of [iobits] normally is
+{11'b0, srst, trst, tck, tms, tdi}
+Note that the first 11 0 bits are reserved for future use, current hardware ignores them.
+
+VEND_JTAG_GETTDO returns one byte, of which bit 0 indicates the current state of the TDO input.
+Note that other bits are reserved for future use and should be ignored.
+
+To describe the capabilities of the JTAG adapter, a specific descriptor (0x20) can be retrieved.
+The format of the descriptor documented below. The descriptor works in the same fashion as USB
+descriptors: a header indicating the version and total length followed by descriptors with a
+specific type and size. Forward compatibility is guaranteed as software can skip over an unknown
+descriptor.
+
+*/
+
+#define JTAG_PROTO_CAPS_VER 1 /* Version field. At the moment, only version 1 is defined. */
+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;
+
+/* start of the descriptor headers */
+#define JTAG_BUILTIN_DESCR_START_OFF 0 /* Devices with builtin usb jtag */
+/*
+* ESP USB Bridge https://github.com/espressif/esp-usb-bridge uses string descriptor.
+* Skip 1 byte length and 1 byte descriptor type
+*/
+#define JTAG_EUB_DESCR_START_OFF 2 /* ESP USB Bridge */
+
+/*
+Note: At the moment, there is only a speed_caps version indicating the base speed of the JTAG
+hardware is derived from the APB bus speed of the SoC. If later on, there are standalone
+converters using the protocol, we should define e.g. JTAG_PROTO_CAPS_SPEED_FIXED_TYPE to distinguish
+between the two.
+
+Note: If the JTAG device has larger buffers than endpoint-size-plus-a-bit, we should have some kind
+of caps header to assume this. If no such caps exist, assume a minimum (in) buffer of endpoint size + 4.
+*/
+
+struct jtag_gen_hdr {
+ uint8_t type;
+ uint8_t length;
+} __packed;
+
+struct jtag_proto_caps_speed_apb {
+ uint8_t type; /* Type, always JTAG_PROTO_CAPS_SPEED_APB_TYPE */
+ uint8_t length; /* Length of this */
+ 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;
+
+#define JTAG_PROTO_CAPS_DATA_LEN 255
+#define JTAG_PROTO_CAPS_SPEED_APB_TYPE 1
+
+#define VEND_DESCR_BUILTIN_JTAG_CAPS 0x2000
+
+#define VEND_JTAG_SETDIV 0
+#define VEND_JTAG_SETIO 1
+#define VEND_JTAG_GETTDO 2
+#define VEND_JTAG_SET_CHIPID 3
+
+#define VEND_JTAG_SETIO_TDI BIT(0)
+#define VEND_JTAG_SETIO_TMS BIT(1)
+#define VEND_JTAG_SETIO_TCK BIT(2)
+#define VEND_JTAG_SETIO_TRST BIT(3)
+#define VEND_JTAG_SETIO_SRST BIT(4)
+
+#define CMD_CLK(cap, tdi, tms) ((cap ? BIT(2) : 0) | (tms ? BIT(1) : 0) | (tdi ? BIT(0) : 0))
+#define CMD_RST(srst) (0x8 | (srst ? BIT(0) : 0))
+#define CMD_FLUSH 0xA
+#define CMD_RSVD 0xB
+#define CMD_REP(r) (0xC + ((r) & 3))
+
+/* The internal repeats register is 10 bits, which means we can have 5 repeat commands in a
+ *row at max. This translates to ('b1111111111+1=)1024 reps max. */
+#define CMD_REP_MAX_REPS 1024
+
+/* Currently we only support one USB device. */
+#define USB_CONFIGURATION 0
+
+/* Buffer size; is equal to the endpoint size. In bytes
+ * TODO for future adapters: read from device configuration? */
+#define OUT_EP_SZ 64
+/* Out data can be buffered for longer without issues (as long as the in buffer does not overflow),
+ * so we'll use an out buffer that is much larger than the out ep size. */
+#define OUT_BUF_SZ (OUT_EP_SZ * 32)
+/* The in buffer cannot be larger than the device can offer, though. */
+#define IN_BUF_SZ 64
+
+/* Because a series of out commands can lead to a multitude of IN_BUF_SZ-sized in packets
+ *to be read, we have multiple buffers to store those before the bitq interface reads them out. */
+#define IN_BUF_CT 8
+
+#define ESP_USB_INTERFACE 1
+
+/* Private data */
+struct esp_usb_jtag {
+ struct libusb_device_handle *usb_device;
+ uint32_t base_speed_khz;
+ uint16_t div_min;
+ uint16_t div_max;
+ uint8_t out_buf[OUT_BUF_SZ];
+ unsigned int out_buf_pos_nibbles; /* write position in out_buf */
+
+ uint8_t in_buf[IN_BUF_CT][IN_BUF_SZ];
+ unsigned int in_buf_size_bits[IN_BUF_CT]; /* size in bits of the data stored in an in_buf */
+ unsigned int cur_in_buf_rd, cur_in_buf_wr; /* read/write index */
+ unsigned int in_buf_pos_bits; /* which bit in the in buf needs to be returned to bitq next */
+
+ unsigned int read_ep;
+ unsigned int write_ep;
+
+ unsigned int prev_cmd; /* previous command, stored here for RLEing. */
+ int prev_cmd_repct; /* Amount of repetitions of that command we have seen until now */
+
+ /* This is the total number of in bits we need to read, including in unsent commands */
+ unsigned int pending_in_bits;
+
+ unsigned int hw_in_fifo_len;
+
+ struct bitq_interface bitq_interface;
+};
+
+/* For now, we only use one static private struct. Technically, we can re-work this, but I don't think
+ * OpenOCD supports multiple JTAG adapters anyway. */
+static struct esp_usb_jtag esp_usb_jtag_priv;
+static struct esp_usb_jtag *priv = &esp_usb_jtag_priv;
+
+static int esp_usb_vid;
+static int esp_usb_pid;
+static int esp_usb_jtag_caps;
+static int esp_usb_target_chip_id;
+
+static int esp_usb_jtag_init(void);
+static int esp_usb_jtag_quit(void);
+
+/* Try to receive from USB endpoint into the current priv->in_buf */
+static int esp_usb_jtag_recv_buf(void)
+{
+ if (priv->in_buf_size_bits[priv->cur_in_buf_wr] != 0)
+ LOG_ERROR("esp_usb_jtag: IN buffer overflow! (%d, size %d)",
+ priv->cur_in_buf_wr,
+ priv->in_buf_size_bits[priv->cur_in_buf_wr]);
+
+ unsigned int recvd = 0, ct = (priv->pending_in_bits + 7) / 8;
+ if (ct > IN_BUF_SZ)
+ ct = IN_BUF_SZ;
+ if (ct == 0) {
+ /* Note that the adapters IN EP specifically does *not* usually generate 0-byte in
+ * packets if there has been no data since the last flush.
+ * As such, we don't need (and shouldn't) try to read it. */
+ return ERROR_OK;
+ }
+
+ priv->in_buf_size_bits[priv->cur_in_buf_wr] = 0;
+ while (recvd < ct) {
+ unsigned int tr;
+ int ret = jtag_libusb_bulk_read(priv->usb_device,
+ priv->read_ep,
+ (char *)priv->in_buf[priv->cur_in_buf_wr] + recvd,
+ ct,
+ LIBUSB_TIMEOUT_MS, /*ms*/
+ (int *)&tr);
+ if (ret != ERROR_OK || tr == 0) {
+ /* Sometimes the hardware returns 0 bytes instead of NAKking the transaction. Ignore this. */
+ return ERROR_FAIL;
+ }
+
+ if (tr != ct) {
+ /* Huh, short read? */
+ LOG_DEBUG("esp_usb_jtag: usb received only %d out of %d bytes.", tr, ct);
+ }
+ /* Adjust the amount of bits we still expect to read from the USB device after this. */
+ unsigned int bits_in_buf = priv->pending_in_bits; /* initially assume we read
+ * everything that was pending */
+ if (bits_in_buf > tr * 8)
+ bits_in_buf = tr * 8; /* ...but correct that if that was not the case. */
+ priv->pending_in_bits -= bits_in_buf;
+ priv->in_buf_size_bits[priv->cur_in_buf_wr] += bits_in_buf;
+ recvd += tr;
+ }
+ /* next in buffer for the next time. */
+ priv->cur_in_buf_wr++;
+ if (priv->cur_in_buf_wr == IN_BUF_CT)
+ priv->cur_in_buf_wr = 0;
+ LOG_DEBUG_IO("esp_usb_jtag: In ep: received %d bytes; %d bytes (%d bits) left.", recvd,
+ (priv->pending_in_bits + 7) / 8, priv->pending_in_bits);
+ return ERROR_OK;
+}
+
+/* Sends priv->out_buf to the USB device. */
+static int esp_usb_jtag_send_buf(void)
+{
+ unsigned int ct = priv->out_buf_pos_nibbles / 2;
+ unsigned int written = 0;
+
+ while (written < ct) {
+ int tr = 0, ret = jtag_libusb_bulk_write(priv->usb_device,
+ priv->write_ep,
+ (char *)priv->out_buf + written,
+ ct - written,
+ LIBUSB_TIMEOUT_MS, /*ms*/
+ &tr);
+ LOG_DEBUG_IO("esp_usb_jtag: sent %d bytes.", tr);
+ if (written + tr != ct) {
+ LOG_DEBUG("esp_usb_jtag: usb sent only %d out of %d bytes.",
+ written + tr,
+ ct);
+ }
+ if (ret != ERROR_OK)
+ return ret;
+ written += tr;
+ }
+ priv->out_buf_pos_nibbles = 0;
+
+ /* If there's more than a bufferful of data queuing up in the jtag adapters IN endpoint, empty
+ * all but one buffer. */
+ while (priv->pending_in_bits > (IN_BUF_SZ + priv->hw_in_fifo_len - 1) * 8)
+ esp_usb_jtag_recv_buf();
+
+ return ERROR_OK;
+}
+
+/* Simply adds a command to the buffer. Is called by the RLE encoding mechanism.
+ *Also sends the intermediate buffer if there's enough to go into one USB packet. */
+static int esp_usb_jtag_command_add_raw(unsigned int cmd)
+{
+ int ret = ERROR_OK;
+
+ if ((priv->out_buf_pos_nibbles & 1) == 0)
+ priv->out_buf[priv->out_buf_pos_nibbles / 2] = (cmd << 4);
+ else
+ priv->out_buf[priv->out_buf_pos_nibbles / 2] |= cmd;
+ priv->out_buf_pos_nibbles++;
+
+ if (priv->out_buf_pos_nibbles == OUT_BUF_SZ * 2)
+ ret = esp_usb_jtag_send_buf();
+ if (ret == ERROR_OK && priv->out_buf_pos_nibbles % (OUT_EP_SZ * 2) == 0) {
+ if (priv->pending_in_bits > (IN_BUF_SZ + priv->hw_in_fifo_len - 1) * 8)
+ ret = esp_usb_jtag_send_buf();
+ }
+ return ret;
+}
+
+/* Writes a command stream equivalent to writing `cmd` `ct` times. */
+static int esp_usb_jtag_write_rlestream(unsigned int cmd, int ct)
+{
+ /* Special case: stacking flush commands does not make sense (and may not make the hardware very happy) */
+ if (cmd == CMD_FLUSH)
+ ct = 1;
+ /* Output previous command and repeat commands */
+ int ret = esp_usb_jtag_command_add_raw(cmd);
+ if (ret != ERROR_OK)
+ return ret;
+ ct--; /* as the previous line already executes the command one time */
+ while (ct > 0) {
+ ret = esp_usb_jtag_command_add_raw(CMD_REP(ct & 3));
+ if (ret != ERROR_OK)
+ return ret;
+ ct >>= 2;
+ }
+ return ERROR_OK;
+}
+
+/* Adds a command to the buffer of things to be sent. Transparently handles RLE compression using
+ * the CMD_REP_x commands */
+static int esp_usb_jtag_command_add(unsigned int cmd)
+{
+ if (cmd == priv->prev_cmd && priv->prev_cmd_repct < CMD_REP_MAX_REPS) {
+ priv->prev_cmd_repct++;
+ } else {
+ /* We can now write out the previous command plus repeat count. */
+ if (priv->prev_cmd_repct) {
+ int ret = esp_usb_jtag_write_rlestream(priv->prev_cmd, priv->prev_cmd_repct);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ /* Ready for new command. */
+ priv->prev_cmd = cmd;
+ priv->prev_cmd_repct = 1;
+ }
+ return ERROR_OK;
+}
+
+/* Called by bitq interface to output a bit on tdi and perhaps read a bit from tdo */
+static int esp_usb_jtag_out(int tms, int tdi, int tdo_req)
+{
+ int ret = esp_usb_jtag_command_add(CMD_CLK(tdo_req, tdi, tms));
+ if (ret != ERROR_OK)
+ return ret;
+ if (tdo_req)
+ priv->pending_in_bits++;
+ return ERROR_OK;
+}
+
+/* Called by bitq interface to flush all output commands and get returned data ready to read */
+static int esp_usb_jtag_flush(void)
+{
+ int ret;
+ /*Make sure last command is written */
+ if (priv->prev_cmd_repct) {
+ ret = esp_usb_jtag_write_rlestream(priv->prev_cmd, priv->prev_cmd_repct);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ priv->prev_cmd_repct = 0;
+ /* Flush in buffer */
+ ret = esp_usb_jtag_command_add_raw(CMD_FLUSH);
+ if (ret != ERROR_OK)
+ return ret;
+ /* Make sure we have an even amount of commands, as we can't write a nibble by itself. */
+ if (priv->out_buf_pos_nibbles & 1) {
+ /*If not, pad with an extra FLUSH */
+ ret = esp_usb_jtag_command_add_raw(CMD_FLUSH);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ LOG_DEBUG_IO("esp_usb_jtag: Flush!");
+ /* Send off the buffer. */
+ ret = esp_usb_jtag_send_buf();
+ if (ret != ERROR_OK)
+ return ret;
+
+ /* Immediately fetch the response bits. */
+ while (priv->pending_in_bits > 0)
+ esp_usb_jtag_recv_buf();
+
+ return ERROR_OK;
+}
+
+/* Called by bitq interface to sleep for a determined amount of time */
+static int esp_usb_jtag_sleep(unsigned long us)
+{
+ esp_usb_jtag_flush();
+ /* TODO: we can sleep more precisely (for small amounts of sleep at least) by sending dummy
+ * commands to the adapter. */
+ jtag_sleep(us);
+ return 0;
+}
+
+/* Called by the bitq interface to set the various resets */
+static int esp_usb_jtag_reset(int trst, int srst)
+{
+ /* TODO: handle trst using setup commands. Kind-of superfluous, however, as we can also do
+ * a tap reset using tms, and it's also not implemented on other ESP32 chips with external JTAG. */
+ return esp_usb_jtag_command_add(CMD_RST(srst));
+}
+
+/* Called by bitq to see if the IN data already is returned to the host. */
+static int esp_usb_jtag_in_rdy(void)
+{
+ /* We read all bits in the flush() routine, so if we're here, we have bits or are at EOF. */
+ return 1;
+}
+
+/* Read one bit from the IN data */
+static int esp_usb_jtag_in(void)
+{
+ if (!esp_usb_jtag_in_rdy()) {
+ LOG_ERROR("esp_usb_jtag: Eeek! bitq asked us for in data while not ready!");
+ return -1;
+ }
+ if (priv->cur_in_buf_rd == priv->cur_in_buf_wr &&
+ priv->in_buf_size_bits[priv->cur_in_buf_rd] == 0)
+ return -1;
+
+ /* Extract the bit */
+ int r = (priv->in_buf[priv->cur_in_buf_rd][priv->in_buf_pos_bits / 8] &
+ BIT(priv->in_buf_pos_bits & 7)) ? 1 : 0;
+ /* Move to next bit. */
+ priv->in_buf_pos_bits++;
+ if (priv->in_buf_pos_bits == priv->in_buf_size_bits[priv->cur_in_buf_rd]) {
+ /* No more bits in this buffer; mark as re-usable and move to next buffer. */
+ priv->in_buf_pos_bits = 0;
+ priv->in_buf_size_bits[priv->cur_in_buf_rd] = 0;/*indicate it is free again */
+ priv->cur_in_buf_rd++;
+ if (priv->cur_in_buf_rd == IN_BUF_CT)
+ priv->cur_in_buf_rd = 0;
+ }
+ return r;
+}
+
+static int esp_usb_jtag_init(void)
+{
+ memset(priv, 0, sizeof(struct esp_usb_jtag));
+
+ const uint16_t vids[] = { esp_usb_vid, 0 }; /* must be null terminated */
+ const uint16_t pids[] = { esp_usb_pid, 0 }; /* must be null terminated */
+
+ bitq_interface = &priv->bitq_interface;
+ bitq_interface->out = esp_usb_jtag_out;
+ bitq_interface->flush = esp_usb_jtag_flush;
+ bitq_interface->sleep = esp_usb_jtag_sleep;
+ bitq_interface->reset = esp_usb_jtag_reset;
+ bitq_interface->in_rdy = esp_usb_jtag_in_rdy;
+ bitq_interface->in = esp_usb_jtag_in;
+
+ int r = jtag_libusb_open(vids, pids, &priv->usb_device, NULL);
+ if (r != ERROR_OK) {
+ LOG_ERROR("esp_usb_jtag: could not find or open device!");
+ goto out;
+ }
+
+ jtag_libusb_set_configuration(priv->usb_device, USB_CONFIGURATION);
+
+ r = jtag_libusb_choose_interface(priv->usb_device, &priv->read_ep, &priv->write_ep,
+ LIBUSB_CLASS_VENDOR_SPEC, LIBUSB_CLASS_VENDOR_SPEC, ESP_USB_INTERFACE, LIBUSB_TRANSFER_TYPE_BULK);
+ if (r != ERROR_OK) {
+ LOG_ERROR("esp_usb_jtag: error finding/claiming JTAG interface on device!");
+ goto out;
+ }
+
+ /* TODO: This is not proper way to get caps data. Two requests can be done.
+ * 1- With the minimum size required to get to know the total length of that struct,
+ * 2- Then exactly the length of that struct. */
+ uint8_t jtag_caps_desc[JTAG_PROTO_CAPS_DATA_LEN];
+ int jtag_caps_read_len = jtag_libusb_control_transfer(priv->usb_device,
+ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
+ LIBUSB_REQUEST_GET_DESCRIPTOR, esp_usb_jtag_caps, 0,
+ (char *)jtag_caps_desc, JTAG_PROTO_CAPS_DATA_LEN, LIBUSB_TIMEOUT_MS);
+ if (jtag_caps_read_len <= 0) {
+ LOG_ERROR("esp_usb_jtag: could not retrieve jtag_caps descriptor!");
+ goto out;
+ }
+
+ /* defaults for values we normally get from the jtag caps descriptor */
+ priv->base_speed_khz = UINT32_MAX;
+ priv->div_min = 1;
+ priv->div_max = 1;
+
+ int p = esp_usb_jtag_caps ==
+ VEND_DESCR_BUILTIN_JTAG_CAPS ? JTAG_BUILTIN_DESCR_START_OFF : JTAG_EUB_DESCR_START_OFF;
+
+ if (p + sizeof(struct jtag_proto_caps_hdr) > (unsigned int)jtag_caps_read_len) {
+ LOG_ERROR("esp_usb_jtag: not enough data to get header");
+ goto out;
+ }
+
+ struct jtag_proto_caps_hdr *hdr = (struct jtag_proto_caps_hdr *)&jtag_caps_desc[p];
+ if (hdr->proto_ver != JTAG_PROTO_CAPS_VER) {
+ LOG_ERROR("esp_usb_jtag: unknown jtag_caps descriptor version 0x%X!",
+ hdr->proto_ver);
+ goto out;
+ }
+ if (hdr->length > jtag_caps_read_len) {
+ LOG_ERROR("esp_usb_jtag: header length (%d) bigger then max read bytes (%d)",
+ hdr->length, jtag_caps_read_len);
+ goto out;
+ }
+
+ p += sizeof(struct jtag_proto_caps_hdr);
+
+ while (p + sizeof(struct jtag_gen_hdr) < hdr->length) {
+ struct jtag_gen_hdr *dhdr = (struct jtag_gen_hdr *)&jtag_caps_desc[p];
+ if (dhdr->type == JTAG_PROTO_CAPS_SPEED_APB_TYPE) {
+ if (p + sizeof(struct jtag_proto_caps_speed_apb) < hdr->length) {
+ LOG_ERROR("esp_usb_jtag: not enough data to get caps speed");
+ goto out;
+ }
+ struct jtag_proto_caps_speed_apb *spcap = (struct jtag_proto_caps_speed_apb *)dhdr;
+ /* base speed always is half APB speed */
+ priv->base_speed_khz = le_to_h_u16(spcap->apb_speed_10khz) * 10 / 2;
+ priv->div_min = le_to_h_u16(spcap->div_min);
+ priv->div_max = le_to_h_u16(spcap->div_max);
+ /* TODO: mark in priv that this is apb-derived and as such may change if apb
+ * ever changes? */
+ } else {
+ LOG_WARNING("esp_usb_jtag: unknown caps type 0x%X", dhdr->type);
+ }
+ p += dhdr->length;
+ }
+ if (priv->base_speed_khz == UINT32_MAX) {
+ LOG_WARNING("esp_usb_jtag: No speed caps found... using sane-ish defaults.");
+ priv->base_speed_khz = 1000;
+ }
+ LOG_INFO("esp_usb_jtag: Device found. Base speed %dKHz, div range %d to %d",
+ priv->base_speed_khz, priv->div_min, priv->div_max);
+
+ /* TODO: grab from (future) descriptor if we ever have a device with larger IN buffers */
+ priv->hw_in_fifo_len = 4;
+
+ /* inform bridge board about the connected target chip for the specific operations
+ * it is also safe to send this info to chips that have builtin usb jtag */
+ jtag_libusb_control_transfer(priv->usb_device,
+ LIBUSB_REQUEST_TYPE_VENDOR,
+ VEND_JTAG_SET_CHIPID,
+ esp_usb_target_chip_id,
+ 0,
+ NULL,
+ 0,
+ LIBUSB_TIMEOUT_MS);
+
+ return ERROR_OK;
+
+out:
+ if (priv->usb_device)
+ jtag_libusb_close(priv->usb_device);
+ bitq_interface = NULL;
+ priv->usb_device = NULL;
+ return ERROR_FAIL;
+}
+
+static int esp_usb_jtag_quit(void)
+{
+ if (!priv->usb_device)
+ return ERROR_OK;
+ jtag_libusb_close(priv->usb_device);
+ bitq_cleanup();
+ bitq_interface = NULL;
+ return ERROR_OK;
+}
+
+static int esp_usb_jtag_speed_div(int divisor, int *khz)
+{
+ *khz = priv->base_speed_khz / divisor;
+ return ERROR_OK;
+}
+
+static int esp_usb_jtag_khz(int khz, int *divisor)
+{
+ if (khz == 0) {
+ LOG_WARNING("esp_usb_jtag: RCLK not supported");
+ return ERROR_FAIL;
+ }
+
+ *divisor = priv->base_speed_khz / khz;
+ LOG_DEBUG("Divisor for %d KHz with base clock of %d khz is %d",
+ khz,
+ priv->base_speed_khz,
+ *divisor);
+ if (*divisor < priv->div_min)
+ *divisor = priv->div_min;
+ if (*divisor > priv->div_max)
+ *divisor = priv->div_max;
+
+ return ERROR_OK;
+}
+
+static int esp_usb_jtag_speed(int divisor)
+{
+ if (divisor == 0) {
+ LOG_ERROR("esp_usb_jtag: Adaptive clocking is not supported.");
+ return ERROR_JTAG_NOT_IMPLEMENTED;
+ }
+
+ LOG_DEBUG("esp_usb_jtag: setting divisor %d", divisor);
+ jtag_libusb_control_transfer(priv->usb_device,
+ LIBUSB_REQUEST_TYPE_VENDOR, VEND_JTAG_SETDIV, divisor, 0, NULL, 0, LIBUSB_TIMEOUT_MS);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(esp_usb_jtag_tdo_cmd)
+{
+ char tdo;
+ if (!priv->usb_device)
+ return ERROR_FAIL;
+ int r = jtag_libusb_control_transfer(priv->usb_device,
+ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR, VEND_JTAG_GETTDO, 0, 0, &tdo, 1, LIBUSB_TIMEOUT_MS);
+ if (r < 1)
+ return r;
+
+ command_print(CMD, "%d", tdo);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(esp_usb_jtag_setio_cmd)
+{
+ uint32_t tdi, tms, tck, trst, srst;
+ uint16_t d = 0;
+
+ if (!priv->usb_device)
+ return ERROR_FAIL;
+
+ if (CMD_ARGC != 5)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], tdi);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], tms);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], tck);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], trst);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], srst);
+ if (tdi)
+ d |= VEND_JTAG_SETIO_TDI;
+ if (tms)
+ d |= VEND_JTAG_SETIO_TMS;
+ if (tck)
+ d |= VEND_JTAG_SETIO_TCK;
+ if (trst)
+ d |= VEND_JTAG_SETIO_TRST;
+ if (srst)
+ d |= VEND_JTAG_SETIO_SRST;
+
+ jtag_libusb_control_transfer(priv->usb_device,
+ 0x40, VEND_JTAG_SETIO, d, 0, NULL, 0, LIBUSB_TIMEOUT_MS);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(esp_usb_jtag_vid_pid)
+{
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_vid);
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], esp_usb_pid);
+ LOG_INFO("esp_usb_jtag: VID set to 0x%x and PID to 0x%x", esp_usb_vid, esp_usb_pid);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(esp_usb_jtag_caps_descriptor)
+{
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_jtag_caps);
+ LOG_INFO("esp_usb_jtag: capabilities descriptor set to 0x%x", esp_usb_jtag_caps);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(esp_usb_jtag_chip_id)
+{
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_target_chip_id);
+ LOG_INFO("esp_usb_jtag: target chip id set to %d", esp_usb_target_chip_id);
+
+ return ERROR_OK;
+}
+
+static const struct command_registration esp_usb_jtag_subcommands[] = {
+ {
+ .name = "tdo",
+ .handler = &esp_usb_jtag_tdo_cmd,
+ .mode = COMMAND_EXEC,
+ .help = "Returns the current state of the TDO line",
+ .usage = "",
+ },
+ {
+ .name = "setio",
+ .handler = &esp_usb_jtag_setio_cmd,
+ .mode = COMMAND_EXEC,
+ .help = "Manually set the status of the output lines",
+ .usage = "tdi tms tck trst srst"
+ },
+ {
+ .name = "vid_pid",
+ .handler = &esp_usb_jtag_vid_pid,
+ .mode = COMMAND_CONFIG,
+ .help = "set vendor ID and product ID for ESP usb jtag driver",
+ .usage = "vid pid",
+ },
+ {
+ .name = "caps_descriptor",
+ .handler = &esp_usb_jtag_caps_descriptor,
+ .mode = COMMAND_CONFIG,
+ .help = "set jtag descriptor to read capabilities of ESP usb jtag driver",
+ .usage = "descriptor",
+ },
+ {
+ .name = "chip_id",
+ .handler = &esp_usb_jtag_chip_id,
+ .mode = COMMAND_CONFIG,
+ .help = "set chip_id to transfer to the bridge",
+ .usage = "chip_id",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration esp_usb_jtag_commands[] = {
+ {
+ .name = "espusbjtag",
+ .mode = COMMAND_ANY,
+ .help = "ESP-USB-JTAG commands",
+ .chain = esp_usb_jtag_subcommands,
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+static struct jtag_interface esp_usb_jtag_interface = {
+ .supported = DEBUG_CAP_TMS_SEQ,
+ .execute_queue = bitq_execute_queue,
+};
+
+struct adapter_driver esp_usb_adapter_driver = {
+ .name = "esp_usb_jtag",
+ .transports = jtag_only,
+ .commands = esp_usb_jtag_commands,
+
+ .init = esp_usb_jtag_init,
+ .quit = esp_usb_jtag_quit,
+ .speed_div = esp_usb_jtag_speed_div,
+ .speed = esp_usb_jtag_speed,
+ .khz = esp_usb_jtag_khz,
+
+ .jtag_ops = &esp_usb_jtag_interface,
+};
diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c
index c930d8c..816b2d0 100644
--- a/src/jtag/drivers/ft232r.c
+++ b/src/jtag/drivers/ft232r.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 Serge Vakulenko *
* serge@vak.ru *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c
index 16cb027..d2dd893 100644
--- a/src/jtag/drivers/ftdi.c
+++ b/src/jtag/drivers/ftdi.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/**************************************************************************
* Copyright (C) 2012 by Andreas Fritiofson *
* andreas.fritiofson@gmail.com *
-* *
-* This program is free software; you can redistribute it and/or modify *
-* it under the terms of the GNU General Public License as published by *
-* the Free Software Foundation; either version 2 of the License, or *
-* (at your option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, *
-* but WITHOUT ANY WARRANTY; without even the implied warranty of *
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-* GNU General Public License for more details. *
-* *
-* You should have received a copy of the GNU General Public License *
-* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c
index db0a677..592e170 100644
--- a/src/jtag/drivers/gw16012.c
+++ b/src/jtag/drivers/gw16012.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/imx_gpio.c b/src/jtag/drivers/imx_gpio.c
index 39b463d..d44b127 100644
--- a/src/jtag/drivers/imx_gpio.c
+++ b/src/jtag/drivers/imx_gpio.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by Grzegorz Kostka, kostka.grzegorz@gmail.com *
* *
* Based on bcm2835gpio.c *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c
index 5c21874..0a96ac2 100644
--- a/src/jtag/drivers/jlink.c
+++ b/src/jtag/drivers/jlink.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net> *
* based on Dominic Rath's and Benedikt Sauter's usbprog.c *
@@ -13,19 +15,6 @@
* *
* Copyright (C) 2015 by Paul Fertser *
* fercerpav@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/jtag_dpi.c b/src/jtag/drivers/jtag_dpi.c
index 016ff55..2a36331 100644
--- a/src/jtag/drivers/jtag_dpi.c
+++ b/src/jtag/drivers/jtag_dpi.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* JTAG to DPI driver
*
@@ -7,19 +9,6 @@
*
* See file CREDITS for list of people who contributed to this
* project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c
index eb53a5b..f19e9ab 100644
--- a/src/jtag/drivers/jtag_vpi.c
+++ b/src/jtag/drivers/jtag_vpi.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* JTAG to VPI driver
*
@@ -5,19 +7,6 @@
*
* See file CREDITS for list of people who contributed to this
* project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c
index 5e2168e..0af1ff7 100644
--- a/src/jtag/drivers/kitprog.c
+++ b/src/jtag/drivers/kitprog.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net> *
* based on Dominic Rath's and Benedikt Sauter's usbprog.c *
@@ -16,19 +18,6 @@
* *
* Copyright (C) 2015-2017 by Forest Crossman *
* cyrozap@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -90,8 +79,24 @@
#define HID_COMMAND_CONFIGURE 0x8f
#define HID_COMMAND_BOOTLOADER 0xa0
-/* 512 bytes seems to work reliably */
-#define SWD_MAX_BUFFER_LENGTH 512
+/* 512 bytes seemed to work reliably.
+ * It works with both full queue of mostly reads or mostly writes.
+ *
+ * Unfortunately the commit 88f429ead019fd6df96ec15f0d897385f3cef0d0
+ * 5321: target/cortex_m: faster reading of all CPU registers
+ * revealed a serious Kitprog firmware problem:
+ * If the queue contains more than 63 transactions in the repeated pattern
+ * one write, two reads, the firmware fails badly.
+ * Sending 64 transactions makes the adapter to loose the connection with the
+ * device. Sending 65 or more transactions causes the adapter to stop
+ * receiving USB HID commands, next kitprog_hid_command() stops in hid_write().
+ *
+ * The problem was detected with KitProg v2.12 and v2.16.
+ * We can guess the problem is something like a buffer or stack overflow.
+ *
+ * Use shorter buffer as a workaround. 300 bytes (= 60 transactions) works.
+ */
+#define SWD_MAX_BUFFER_LENGTH 300
struct kitprog {
hid_device *hid_handle;
@@ -332,9 +337,13 @@ static int kitprog_hid_command(uint8_t *command, size_t command_length,
return ERROR_FAIL;
}
- ret = hid_read(kitprog_handle->hid_handle, data, data_length);
- if (ret < 0) {
- LOG_DEBUG("HID read returned %i", ret);
+ ret = hid_read_timeout(kitprog_handle->hid_handle,
+ data, data_length, LIBUSB_TIMEOUT_MS);
+ if (ret == 0) {
+ LOG_ERROR("HID read timed out");
+ return ERROR_TIMEOUT_REACHED;
+ } else if (ret < 0) {
+ LOG_ERROR("HID read error %ls", hid_error(kitprog_handle->hid_handle));
return ERROR_FAIL;
}
diff --git a/src/jtag/drivers/libjaylink b/src/jtag/drivers/libjaylink
-Subproject 9aa7a5957c07bb6e862fc1a6d3153d109c7407e
+Subproject 0d23921a05d5d427332a142d154c213d0c306eb
diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c
index fc961cb..53dfd50 100644
--- a/src/jtag/drivers/libusb_helper.c
+++ b/src/jtag/drivers/libusb_helper.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
* *
* Copyright (C) 2011 by Mauro Gamba <maurillo71@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h
index 9d51464..172c345 100644
--- a/src/jtag/drivers/libusb_helper.h
+++ b/src/jtag/drivers/libusb_helper.h
@@ -1,20 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
* *
* Copyright (C) 2011 by Mauro Gamba <maurillo71@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H
diff --git a/src/jtag/drivers/linuxgpiod.c b/src/jtag/drivers/linuxgpiod.c
index 288035f..d1a88c8 100644
--- a/src/jtag/drivers/linuxgpiod.c
+++ b/src/jtag/drivers/linuxgpiod.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Bitbang driver for Linux GPIO descriptors through libgpiod
* Copyright (C) 2020 Antonio Borneo <borneo.antonio@gmail.com>
@@ -14,67 +14,41 @@
#endif
#include <gpiod.h>
+#include <jtag/adapter.h>
#include <jtag/interface.h>
#include <transport/transport.h>
#include "bitbang.h"
-/* gpio numbers for each gpio. Negative values are invalid */
-static int tck_gpio = -1;
-static int tms_gpio = -1;
-static int tdi_gpio = -1;
-static int tdo_gpio = -1;
-static int trst_gpio = -1;
-static int srst_gpio = -1;
-static int swclk_gpio = -1;
-static int swdio_gpio = -1;
-static int swdio_dir_gpio = -1;
-static int led_gpio = -1;
-static int gpiochip = -1;
-static int tck_gpiochip = -1;
-static int tms_gpiochip = -1;
-static int tdi_gpiochip = -1;
-static int tdo_gpiochip = -1;
-static int trst_gpiochip = -1;
-static int srst_gpiochip = -1;
-static int swclk_gpiochip = -1;
-static int swdio_gpiochip = -1;
-static int swdio_dir_gpiochip = -1;
-static int led_gpiochip = -1;
-
-static struct gpiod_chip *gpiod_chip_tck;
-static struct gpiod_chip *gpiod_chip_tms;
-static struct gpiod_chip *gpiod_chip_tdi;
-static struct gpiod_chip *gpiod_chip_tdo;
-static struct gpiod_chip *gpiod_chip_trst;
-static struct gpiod_chip *gpiod_chip_srst;
-static struct gpiod_chip *gpiod_chip_swclk;
-static struct gpiod_chip *gpiod_chip_swdio;
-static struct gpiod_chip *gpiod_chip_swdio_dir;
-static struct gpiod_chip *gpiod_chip_led;
-
-static struct gpiod_line *gpiod_tck;
-static struct gpiod_line *gpiod_tms;
-static struct gpiod_line *gpiod_tdi;
-static struct gpiod_line *gpiod_tdo;
-static struct gpiod_line *gpiod_trst;
-static struct gpiod_line *gpiod_swclk;
-static struct gpiod_line *gpiod_swdio;
-static struct gpiod_line *gpiod_swdio_dir;
-static struct gpiod_line *gpiod_srst;
-static struct gpiod_line *gpiod_led;
+static struct gpiod_chip *gpiod_chip[ADAPTER_GPIO_IDX_NUM] = {};
+static struct gpiod_line *gpiod_line[ADAPTER_GPIO_IDX_NUM] = {};
static int last_swclk;
static int last_swdio;
static bool last_stored;
static bool swdio_input;
-static bool swdio_dir_is_active_high = true;
+
+static const struct adapter_gpio_config *adapter_gpio_config;
+
+/*
+ * Helper function to determine if gpio config is valid
+ *
+ * Assume here that there will be less than 10000 gpios per gpiochip, and less
+ * than 1000 gpiochips.
+ */
+static bool is_gpio_config_valid(enum adapter_gpio_config_index idx)
+{
+ return adapter_gpio_config[idx].chip_num >= 0
+ && adapter_gpio_config[idx].chip_num < 1000
+ && adapter_gpio_config[idx].gpio_num >= 0
+ && adapter_gpio_config[idx].gpio_num < 10000;
+}
/* Bitbang interface read of TDO */
static bb_value_t linuxgpiod_read(void)
{
int retval;
- retval = gpiod_line_get_value(gpiod_tdo);
+ retval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_TDO]);
if (retval < 0) {
LOG_WARNING("reading tdo failed");
return 0;
@@ -107,20 +81,20 @@ static int linuxgpiod_write(int tck, int tms, int tdi)
}
if (tdi != last_tdi) {
- retval = gpiod_line_set_value(gpiod_tdi, tdi);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TDI], tdi);
if (retval < 0)
LOG_WARNING("writing tdi failed");
}
if (tms != last_tms) {
- retval = gpiod_line_set_value(gpiod_tms, tms);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TMS], tms);
if (retval < 0)
LOG_WARNING("writing tms failed");
}
/* write clk last */
if (tck != last_tck) {
- retval = gpiod_line_set_value(gpiod_tck, tck);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TCK], tck);
if (retval < 0)
LOG_WARNING("writing tck failed");
}
@@ -136,7 +110,7 @@ static int linuxgpiod_swdio_read(void)
{
int retval;
- retval = gpiod_line_get_value(gpiod_swdio);
+ retval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]);
if (retval < 0) {
LOG_WARNING("Fail read swdio");
return 0;
@@ -154,23 +128,23 @@ static void linuxgpiod_swdio_drive(bool is_output)
* https://stackoverflow.com/questions/58735140/
* this would change in future libgpiod
*/
- gpiod_line_release(gpiod_swdio);
+ gpiod_line_release(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]);
if (is_output) {
- if (gpiod_swdio_dir) {
- retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 1 : 0);
+ if (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) {
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);
if (retval < 0)
LOG_WARNING("Fail set swdio_dir");
}
- retval = gpiod_line_request_output(gpiod_swdio, "OpenOCD", 1);
+ retval = gpiod_line_request_output(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], "OpenOCD", 1);
if (retval < 0)
LOG_WARNING("Fail request_output line swdio");
} else {
- retval = gpiod_line_request_input(gpiod_swdio, "OpenOCD");
+ retval = gpiod_line_request_input(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], "OpenOCD");
if (retval < 0)
LOG_WARNING("Fail request_input line swdio");
- if (gpiod_swdio_dir) {
- retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 0 : 1);
+ if (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) {
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);
if (retval < 0)
LOG_WARNING("Fail set swdio_dir");
}
@@ -186,7 +160,7 @@ static int linuxgpiod_swd_write(int swclk, int swdio)
if (!swdio_input) {
if (!last_stored || (swdio != last_swdio)) {
- retval = gpiod_line_set_value(gpiod_swdio, swdio);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], swdio);
if (retval < 0)
LOG_WARNING("Fail set swdio");
}
@@ -194,7 +168,7 @@ static int linuxgpiod_swd_write(int swclk, int swdio)
/* write swclk last */
if (!last_stored || (swclk != last_swclk)) {
- retval = gpiod_line_set_value(gpiod_swclk, swclk);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWCLK], swclk);
if (retval < 0)
LOG_WARNING("Fail set swclk");
}
@@ -210,10 +184,10 @@ static int linuxgpiod_blink(int on)
{
int retval;
- if (!gpiod_led)
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_LED))
return ERROR_OK;
- retval = gpiod_line_set_value(gpiod_led, on);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_LED], on);
if (retval < 0)
LOG_WARNING("Fail set led");
return retval;
@@ -239,16 +213,18 @@ static int linuxgpiod_reset(int trst, int srst)
LOG_DEBUG("linuxgpiod_reset");
- /* assume active low */
- if (gpiod_srst) {
- retval1 = gpiod_line_set_value(gpiod_srst, srst ? 0 : 1);
+ /*
+ * active low behaviour handled by "adaptor gpio" command and
+ * GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW flag when requesting the line.
+ */
+ if (gpiod_line[ADAPTER_GPIO_IDX_SRST]) {
+ retval1 = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SRST], srst);
if (retval1 < 0)
LOG_WARNING("set srst value failed");
}
- /* assume active low */
- if (gpiod_trst) {
- retval2 = gpiod_line_set_value(gpiod_trst, trst ? 0 : 1);
+ if (gpiod_line[ADAPTER_GPIO_IDX_TRST]) {
+ retval2 = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TRST], trst);
if (retval2 < 0)
LOG_WARNING("set trst value failed");
}
@@ -256,127 +232,134 @@ static int linuxgpiod_reset(int trst, int srst)
return ((retval1 < 0) || (retval2 < 0)) ? ERROR_FAIL : ERROR_OK;
}
-/*
- * Helper function to determine if gpio number is valid
- *
- * Assume here that there will be less than 10000 gpios per gpiochip
- */
-static bool is_gpio_valid(int gpio)
-{
- return gpio >= 0 && gpio < 10000;
-}
-
static bool linuxgpiod_jtag_mode_possible(void)
{
- if (!is_gpio_valid(tck_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK))
return false;
- if (!is_gpio_valid(tms_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS))
return false;
- if (!is_gpio_valid(tdi_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI))
return false;
- if (!is_gpio_valid(tdo_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO))
return false;
return true;
}
static bool linuxgpiod_swd_mode_possible(void)
{
- if (!is_gpio_valid(swclk_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK))
return false;
- if (!is_gpio_valid(swdio_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO))
return false;
return true;
}
-static inline void helper_release(struct gpiod_line *line)
+static inline void helper_release(enum adapter_gpio_config_index idx)
{
- if (line)
- gpiod_line_release(line);
+ if (gpiod_line[idx]) {
+ gpiod_line_release(gpiod_line[idx]);
+ gpiod_line[idx] = NULL;
+ }
+ if (gpiod_chip[idx]) {
+ gpiod_chip_close(gpiod_chip[idx]);
+ gpiod_chip[idx] = NULL;
+ }
}
static int linuxgpiod_quit(void)
{
- helper_release(gpiod_led);
- helper_release(gpiod_srst);
- helper_release(gpiod_swdio);
- helper_release(gpiod_swclk);
- helper_release(gpiod_trst);
- helper_release(gpiod_tms);
- helper_release(gpiod_tck);
- helper_release(gpiod_tdi);
- helper_release(gpiod_tdo);
-
- if (gpiod_chip_led != NULL)
- gpiod_chip_close(gpiod_chip_led);
- if (gpiod_chip_srst != NULL)
- gpiod_chip_close(gpiod_chip_srst);
- if (gpiod_chip_swdio != NULL)
- gpiod_chip_close(gpiod_chip_swdio);
- if (gpiod_chip_swdio_dir != NULL)
- gpiod_chip_close(gpiod_chip_swdio_dir);
- if (gpiod_chip_swclk != NULL)
- gpiod_chip_close(gpiod_chip_swclk);
- if (gpiod_chip_trst != NULL)
- gpiod_chip_close(gpiod_chip_trst);
- if (gpiod_chip_tms != NULL)
- gpiod_chip_close(gpiod_chip_tms);
- if (gpiod_chip_tck != NULL)
- gpiod_chip_close(gpiod_chip_tck);
- if (gpiod_chip_tdi != NULL)
- gpiod_chip_close(gpiod_chip_tdi);
- if (gpiod_chip_tdo != NULL)
- gpiod_chip_close(gpiod_chip_tdo);
+ LOG_DEBUG("linuxgpiod_quit");
+ for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i)
+ helper_release(i);
return ERROR_OK;
}
-static struct gpiod_line *helper_get_line(const char *label,
- struct gpiod_chip *gpiod_chip, unsigned int offset,
- int val, int dir, int flags)
+static int helper_get_line(enum adapter_gpio_config_index idx)
{
- struct gpiod_line *line;
- int retval;
+ if (!is_gpio_config_valid(idx))
+ return ERROR_OK;
+
+ int dir = GPIOD_LINE_REQUEST_DIRECTION_INPUT, flags = 0, val = 0, retval;
+
+ gpiod_chip[idx] = gpiod_chip_open_by_number(adapter_gpio_config[idx].chip_num);
+ if (!gpiod_chip[idx]) {
+ LOG_ERROR("Cannot open LinuxGPIOD chip %d for %s", adapter_gpio_config[idx].chip_num,
+ adapter_gpio_get_name(idx));
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ gpiod_line[idx] = gpiod_chip_get_line(gpiod_chip[idx], adapter_gpio_config[idx].gpio_num);
+ if (!gpiod_line[idx]) {
+ LOG_ERROR("Error get line %s", adapter_gpio_get_name(idx));
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ switch (adapter_gpio_config[idx].init_state) {
+ case ADAPTER_GPIO_INIT_STATE_INPUT:
+ dir = GPIOD_LINE_REQUEST_DIRECTION_INPUT;
+ break;
+ case ADAPTER_GPIO_INIT_STATE_INACTIVE:
+ dir = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
+ val = 0;
+ break;
+ case ADAPTER_GPIO_INIT_STATE_ACTIVE:
+ dir = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
+ val = 1;
+ break;
+ }
+
+ switch (adapter_gpio_config[idx].drive) {
+ case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:
+ flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN;
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
+ flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE;
+ break;
+ }
- line = gpiod_chip_get_line(gpiod_chip, offset);
- if (!line) {
- LOG_ERROR("Error get line %s", label);
- return NULL;
+ switch (adapter_gpio_config[idx].pull) {
+ case ADAPTER_GPIO_PULL_NONE:
+#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE
+ flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE;
+#endif
+ break;
+ case ADAPTER_GPIO_PULL_UP:
+#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP
+ flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP;
+#else
+ LOG_WARNING("linuxgpiod: ignoring request for pull-up on %s: not supported by gpiod v%s",
+ adapter_gpio_get_name(idx), gpiod_version_string());
+#endif
+ break;
+ case ADAPTER_GPIO_PULL_DOWN:
+#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN
+ flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN;
+#else
+ LOG_WARNING("linuxgpiod: ignoring request for pull-down on %s: not supported by gpiod v%s",
+ adapter_gpio_get_name(idx), gpiod_version_string());
+#endif
+ break;
}
+ if (adapter_gpio_config[idx].active_low)
+ flags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW;
+
struct gpiod_line_request_config config = {
.consumer = "OpenOCD",
.request_type = dir,
.flags = flags,
};
- retval = gpiod_line_request(line, &config, val);
+ retval = gpiod_line_request(gpiod_line[idx], &config, val);
if (retval < 0) {
- LOG_ERROR("Error requesting gpio line %s", label);
- return NULL;
+ LOG_ERROR("Error requesting gpio line %s", adapter_gpio_get_name(idx));
+ return ERROR_JTAG_INIT_FAILED;
}
- return line;
-}
-
-static struct gpiod_line *helper_get_input_line(const char *label,
- struct gpiod_chip *gpiod_chip, unsigned int offset)
-{
- return helper_get_line(label, gpiod_chip, offset, 0,
- GPIOD_LINE_REQUEST_DIRECTION_INPUT, 0);
-}
-
-static struct gpiod_line *helper_get_output_line(const char *label,
- struct gpiod_chip *gpiod_chip, unsigned int offset, int val)
-{
- return helper_get_line(label, gpiod_chip, offset, val,
- GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0);
-}
-
-static struct gpiod_line *helper_get_open_drain_output_line(const char *label,
- struct gpiod_chip *gpiod_chip, unsigned int offset, int val)
-{
- return helper_get_line(label, gpiod_chip, offset, val,
- GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN);
+ return ERROR_OK;
}
static int linuxgpiod_init(void)
@@ -384,11 +367,11 @@ static int linuxgpiod_init(void)
LOG_INFO("Linux GPIOD JTAG/SWD bitbang driver");
bitbang_interface = &linuxgpiod_bitbang;
+ adapter_gpio_config = adapter_gpio_get_config();
/*
- * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
- * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
- * For SWD, SWCLK and SWDIO are configures as output high.
+ * Configure JTAG/SWD signals. Default directions and initial states are handled
+ * by adapter.c and "adapter gpio" command.
*/
if (transport_is_jtag()) {
@@ -397,129 +380,44 @@ static int linuxgpiod_init(void)
goto out_error;
}
- gpiod_chip_tdo = gpiod_chip_open_by_number(tdo_gpiochip);
- if (!gpiod_chip_tdo) {
- LOG_ERROR("Cannot open LinuxGPIOD tdo_gpiochip %d", tdo_gpiochip);
- goto out_error;
- }
- gpiod_chip_tdi = gpiod_chip_open_by_number(tdi_gpiochip);
- if (!gpiod_chip_tdi) {
- LOG_ERROR("Cannot open LinuxGPIOD tdi_gpiochip %d", tdi_gpiochip);
- goto out_error;
- }
- gpiod_chip_tck = gpiod_chip_open_by_number(tck_gpiochip);
- if (!gpiod_chip_tck) {
- LOG_ERROR("Cannot open LinuxGPIOD tck_gpiochip %d", tck_gpiochip);
- goto out_error;
- }
- gpiod_chip_tms = gpiod_chip_open_by_number(tms_gpiochip);
- if (!gpiod_chip_tms) {
- LOG_ERROR("Cannot open LinuxGPIOD tms_gpiochip %d", tms_gpiochip);
- goto out_error;
- }
-
- gpiod_tdo = helper_get_input_line("tdo", gpiod_chip_tdo, tdo_gpio);
- if (!gpiod_tdo)
- goto out_error;
-
- gpiod_tdi = helper_get_output_line("tdi", gpiod_chip_tdi, tdi_gpio, 0);
- if (!gpiod_tdi)
- goto out_error;
-
- gpiod_tck = helper_get_output_line("tck", gpiod_chip_tck, tck_gpio, 0);
- if (!gpiod_tck)
- goto out_error;
-
- gpiod_tms = helper_get_output_line("tms", gpiod_chip_tms, tms_gpio, 1);
- if (!gpiod_tms)
- goto out_error;
-
- if (is_gpio_valid(trst_gpio)) {
- gpiod_chip_trst = gpiod_chip_open_by_number(trst_gpiochip);
- if (!gpiod_chip_trst) {
- LOG_ERROR("Cannot open LinuxGPIOD trst_gpiochip %d", trst_gpiochip);
+ if (helper_get_line(ADAPTER_GPIO_IDX_TDO) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_TDI) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_TCK) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_TMS) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_TRST) != ERROR_OK)
goto out_error;
- }
-
- if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN)
- gpiod_trst = helper_get_open_drain_output_line("trst", gpiod_chip_trst, trst_gpio, 1);
- else
- gpiod_trst = helper_get_output_line("trst", gpiod_chip_trst, trst_gpio, 1);
-
- if (!gpiod_trst)
- goto out_error;
- }
}
if (transport_is_swd()) {
+ int retval1, retval2;
if (!linuxgpiod_swd_mode_possible()) {
LOG_ERROR("Require swclk and swdio gpio for SWD mode");
goto out_error;
}
- gpiod_chip_swclk = gpiod_chip_open_by_number(swclk_gpiochip);
- if (!gpiod_chip_swclk) {
- LOG_ERROR("Cannot open LinuxGPIOD swclk_gpiochip %d", swclk_gpiochip);
- goto out_error;
+ /*
+ * swdio and its buffer should be initialized in the order that prevents
+ * two outputs from being connected together. This will occur if the
+ * swdio GPIO is configured as an output while the external buffer is
+ * configured to send the swdio signal from the target to the GPIO.
+ */
+ if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) {
+ retval1 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO);
+ retval2 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ } else {
+ retval1 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ retval2 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO);
}
- gpiod_chip_swdio = gpiod_chip_open_by_number(swdio_gpiochip);
- if (!gpiod_chip_swdio) {
- LOG_ERROR("Cannot open LinuxGPIOD swdio_gpiochip %d", swdio_gpiochip);
+ if (retval1 != ERROR_OK || retval2 != ERROR_OK)
goto out_error;
- }
-
- if (is_gpio_valid(swdio_dir_gpio)) {
- gpiod_chip_swdio_dir = gpiod_chip_open_by_number(swdio_dir_gpiochip);
- if (!gpiod_chip_swdio_dir) {
- LOG_ERROR("Cannot open LinuxGPIOD swdio_dir_gpiochip %d", swdio_dir_gpiochip);
- goto out_error;
- }
- }
- gpiod_swclk = helper_get_output_line("swclk", gpiod_chip_swclk, swclk_gpio, 1);
- if (!gpiod_swclk)
- goto out_error;
-
- /* Set buffer direction before making SWDIO an output */
- if (is_gpio_valid(swdio_dir_gpio)) {
- gpiod_swdio_dir = helper_get_output_line("swdio_dir", gpiod_chip_swdio_dir, swdio_dir_gpio,
- swdio_dir_is_active_high ? 1 : 0);
- if (!gpiod_swdio_dir)
- goto out_error;
- }
-
- gpiod_swdio = helper_get_output_line("swdio", gpiod_chip_swdio, swdio_gpio, 1);
- if (!gpiod_swdio)
+ if (helper_get_line(ADAPTER_GPIO_IDX_SWCLK) != ERROR_OK)
goto out_error;
}
- if (is_gpio_valid(srst_gpio)) {
- gpiod_chip_srst = gpiod_chip_open_by_number(srst_gpiochip);
- if (!gpiod_chip_srst) {
- LOG_ERROR("Cannot open LinuxGPIOD srst_gpiochip %d", srst_gpiochip);
- goto out_error;
- }
-
- if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL)
- gpiod_srst = helper_get_output_line("srst", gpiod_chip_srst, srst_gpio, 1);
- else
- gpiod_srst = helper_get_open_drain_output_line("srst", gpiod_chip_srst, srst_gpio, 1);
-
- if (!gpiod_srst)
- goto out_error;
- }
-
- if (is_gpio_valid(led_gpio)) {
- gpiod_chip_led = gpiod_chip_open_by_number(led_gpiochip);
- if (!gpiod_chip_led) {
- LOG_ERROR("Cannot open LinuxGPIOD led_gpiochip %d", led_gpiochip);
- goto out_error;
- }
-
- gpiod_led = helper_get_output_line("led", gpiod_chip_led, led_gpio, 0);
- if (!gpiod_led)
+ if (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK)
goto out_error;
- }
return ERROR_OK;
@@ -529,241 +427,6 @@ out_error:
return ERROR_JTAG_INIT_FAILED;
}
-COMMAND_HELPER(linuxgpiod_helper_gpionum, const char *name, int *chip, int *line)
-{
- int i = 0;
- if (CMD_ARGC > 2)
- return ERROR_COMMAND_SYNTAX_ERROR;
- if (CMD_ARGC == 2) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], *chip);
- i = 1;
- }
- if (CMD_ARGC > 0)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[i], *line);
- command_print(CMD, "LinuxGPIOD %s: chip = %d, num = %d", name, *chip, *line);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionums)
-{
- if (CMD_ARGC == 4) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);
- } else if (CMD_ARGC != 0) {
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- command_print(CMD,
- "LinuxGPIOD nums: tck = %d, tms = %d, tdi = %d, tdo = %d",
- tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tck)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tck", &tck_gpiochip,
- &tck_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tms)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tms", &tms_gpiochip,
- &tms_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdo)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdo", &tdo_gpiochip,
- &tdo_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdi)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdi", &tdi_gpiochip,
- &tdi_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_srst)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "srst", &srst_gpiochip,
- &srst_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_trst)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "trst", &trst_gpiochip,
- &trst_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_swd_gpionums)
-{
- if (CMD_ARGC == 2) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio);
- } else if (CMD_ARGC != 0) {
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- command_print(CMD,
- "LinuxGPIOD nums: swclk = %d, swdio = %d",
- swclk_gpio, swdio_gpio);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swclk)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swclk", &swclk_gpiochip,
- &swclk_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swdio", &swdio_gpiochip,
- &swdio_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio_dir)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swdio_dir", &swdio_dir_gpiochip,
- &swdio_dir_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_gpionum_led)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "led", &led_gpiochip,
- &led_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_gpiochip)
-{
- if (CMD_ARGC == 1) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], gpiochip);
- tck_gpiochip = gpiochip;
- tms_gpiochip = gpiochip;
- tdi_gpiochip = gpiochip;
- tdo_gpiochip = gpiochip;
- trst_gpiochip = gpiochip;
- srst_gpiochip = gpiochip;
- swclk_gpiochip = gpiochip;
- swdio_gpiochip = gpiochip;
- swdio_dir_gpiochip = gpiochip;
- led_gpiochip = gpiochip;
- }
-
- command_print(CMD, "LinuxGPIOD gpiochip = %d", gpiochip);
- return ERROR_OK;
-}
-
-static const struct command_registration linuxgpiod_subcommand_handlers[] = {
- {
- .name = "jtag_nums",
- .handler = linuxgpiod_handle_jtag_gpionums,
- .mode = COMMAND_CONFIG,
- .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)",
- .usage = "tck tms tdi tdo",
- },
- {
- .name = "tck_num",
- .handler = linuxgpiod_handle_jtag_gpionum_tck,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for tck.",
- .usage = "[chip] tck",
- },
- {
- .name = "tms_num",
- .handler = linuxgpiod_handle_jtag_gpionum_tms,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for tms.",
- .usage = "[chip] tms",
- },
- {
- .name = "tdo_num",
- .handler = linuxgpiod_handle_jtag_gpionum_tdo,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for tdo.",
- .usage = "[chip] tdo",
- },
- {
- .name = "tdi_num",
- .handler = linuxgpiod_handle_jtag_gpionum_tdi,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for tdi.",
- .usage = "[chip] tdi",
- },
- {
- .name = "srst_num",
- .handler = linuxgpiod_handle_jtag_gpionum_srst,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for srst.",
- .usage = "[chip] srst",
- },
- {
- .name = "trst_num",
- .handler = linuxgpiod_handle_jtag_gpionum_trst,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for trst.",
- .usage = "[chip] trst",
- },
- {
- .name = "swd_nums",
- .handler = linuxgpiod_handle_swd_gpionums,
- .mode = COMMAND_CONFIG,
- .help = "gpio numbers for swclk, swdio. (in that order)",
- .usage = "swclk swdio",
- },
- {
- .name = "swclk_num",
- .handler = linuxgpiod_handle_swd_gpionum_swclk,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for swclk.",
- .usage = "[chip] swclk",
- },
- {
- .name = "swdio_num",
- .handler = linuxgpiod_handle_swd_gpionum_swdio,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for swdio.",
- .usage = "[chip] swdio",
- },
- {
- .name = "swdio_dir_num",
- .handler = linuxgpiod_handle_swd_gpionum_swdio_dir,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for swdio_dir.",
- .usage = "[chip] swdio_dir",
- },
- {
- .name = "led_num",
- .handler = linuxgpiod_handle_gpionum_led,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for LED.",
- .usage = "[chip] led",
- },
- {
- .name = "gpiochip",
- .handler = linuxgpiod_handle_gpiochip,
- .mode = COMMAND_CONFIG,
- .help = "number of the gpiochip.",
- .usage = "gpiochip",
- },
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration linuxgpiod_command_handlers[] = {
- {
- .name = "linuxgpiod",
- .mode = COMMAND_ANY,
- .help = "perform linuxgpiod management",
- .chain = linuxgpiod_subcommand_handlers,
- .usage = "",
- },
- COMMAND_REGISTRATION_DONE
-};
-
static const char *const linuxgpiod_transport[] = { "swd", "jtag", NULL };
static struct jtag_interface linuxgpiod_interface = {
@@ -774,7 +437,6 @@ static struct jtag_interface linuxgpiod_interface = {
struct adapter_driver linuxgpiod_adapter_driver = {
.name = "linuxgpiod",
.transports = linuxgpiod_transport,
- .commands = linuxgpiod_command_handlers,
.init = linuxgpiod_init,
.quit = linuxgpiod_quit,
diff --git a/src/jtag/drivers/minidriver_imp.h b/src/jtag/drivers/minidriver_imp.h
index cd59a74..7afb463 100644
--- a/src/jtag/drivers/minidriver_imp.h
+++ b/src/jtag/drivers/minidriver_imp.h
@@ -1,20 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007-2009 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H
diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c
index 0e3d2be..18aeb38 100644
--- a/src/jtag/drivers/mpsse.c
+++ b/src/jtag/drivers/mpsse.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/**************************************************************************
* Copyright (C) 2012 by Andreas Fritiofson *
* andreas.fritiofson@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/mpsse.h b/src/jtag/drivers/mpsse.h
index 651eef9..a017aff 100644
--- a/src/jtag/drivers/mpsse.h
+++ b/src/jtag/drivers/mpsse.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/**************************************************************************
* Copyright (C) 2012 by Andreas Fritiofson *
* andreas.fritiofson@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_MPSSE_H
diff --git a/src/jtag/drivers/nulink_usb.c b/src/jtag/drivers/nulink_usb.c
index 84a4420..4fdb857 100644
--- a/src/jtag/drivers/nulink_usb.c
+++ b/src/jtag/drivers/nulink_usb.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2016-2017 by Nuvoton *
* Zale Yu <cyyu@nuvoton.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c
index ae21cf2..d0c5277 100644
--- a/src/jtag/drivers/opendous.c
+++ b/src/jtag/drivers/opendous.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* *
* Copyright (C) 2009 by Cahya Wirawan <cahya@gmx.at> *
@@ -11,19 +13,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c
index 771b6e6..6be9507 100644
--- a/src/jtag/drivers/openjtag.c
+++ b/src/jtag/drivers/openjtag.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*******************************************************************************
* Driver for OpenJTAG Project (www.openjtag.org) *
* Compatible with libftdi drivers. *
@@ -18,19 +20,6 @@
* And jlink.c *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/***************************************************************************
diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c
index f7665eb..d8fe713 100644
--- a/src/jtag/drivers/osbdm.c
+++ b/src/jtag/drivers/osbdm.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2012 by Jan Dakinevich *
* jan.dakinevich@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c
index 9273e3e..4073d06 100644
--- a/src/jtag/drivers/parport.c
+++ b/src/jtag/drivers/parport.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/presto.c b/src/jtag/drivers/presto.c
index e938a3b..f6e13f7 100644
--- a/src/jtag/drivers/presto.c
+++ b/src/jtag/drivers/presto.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Pavel Chromy *
* chromy@asix.cz *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c
index 6ab7cc9..36bcbe1 100644
--- a/src/jtag/drivers/remote_bitbang.c
+++ b/src/jtag/drivers/remote_bitbang.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Richard Uhler *
* ruhler@mit.edu *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c
index 0cf9dbb..c933b3e 100644
--- a/src/jtag/drivers/rlink.c
+++ b/src/jtag/drivers/rlink.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 Rob Brown, Lou Deluxe *
* rob@cobbleware.com, lou.openocd012@fixit.nospammail.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/rlink.h b/src/jtag/drivers/rlink.h
index 0c15a32..38f8429 100644
--- a/src/jtag/drivers/rlink.h
+++ b/src/jtag/drivers/rlink.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 Lou Deluxe *
* lou.openocd012@fixit.nospammail.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_RLINK_H
diff --git a/src/jtag/drivers/rlink_call.m4 b/src/jtag/drivers/rlink_call.m4
index bf07afa..39ac25c 100644
--- a/src/jtag/drivers/rlink_call.m4
+++ b/src/jtag/drivers/rlink_call.m4
@@ -1,21 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+#
+# Copyright (C) 2008 Lou Deluxe
+# lou.openocd012@fixit.nospammail.net
+#
+
m4_divert(`-1')
-/***************************************************************************
- * Copyright (C) 2008 Lou Deluxe *
- * lou.openocd012@fixit.nospammail.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
m4_dnl Setup and hold times depend on SHIFTER_PRESCALER
m4_define(`SETUP_DELAY_CYCLES', m4_eval(`('SHIFTER_PRESCALER` + 1) / 2'))
diff --git a/src/jtag/drivers/rlink_dtc_cmd.h b/src/jtag/drivers/rlink_dtc_cmd.h
index ff9e8b2..b40ad17 100644
--- a/src/jtag/drivers/rlink_dtc_cmd.h
+++ b/src/jtag/drivers/rlink_dtc_cmd.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 Lou Deluxe *
* lou.openocd012@fixit.nospammail.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_RLINK_DTC_CMD_H
diff --git a/src/jtag/drivers/rlink_ep1_cmd.h b/src/jtag/drivers/rlink_ep1_cmd.h
index 3f9f2b3..812d7e5 100644
--- a/src/jtag/drivers/rlink_ep1_cmd.h
+++ b/src/jtag/drivers/rlink_ep1_cmd.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 Lou Deluxe *
* lou.openocd012@fixit.nospammail.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_RLINK_EP1_CMD_H
diff --git a/src/jtag/drivers/rlink_init.m4 b/src/jtag/drivers/rlink_init.m4
index 8ad2f51..e77e943 100644
--- a/src/jtag/drivers/rlink_init.m4
+++ b/src/jtag/drivers/rlink_init.m4
@@ -1,21 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+#
+# Copyright (C) 2008 Lou Deluxe
+# lou.openocd012@fixit.nospammail.net
+#
+
m4_divert(`-1')
-/***************************************************************************
- * Copyright (C) 2008 Lou Deluxe *
- * lou.openocd012@fixit.nospammail.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
m4_undefine(`CTRL_MPEG_L')
m4_undefine(`CTRL_CARD_L')
diff --git a/src/jtag/drivers/rlink_st7.h b/src/jtag/drivers/rlink_st7.h
index 3d573e7..b891024 100644
--- a/src/jtag/drivers/rlink_st7.h
+++ b/src/jtag/drivers/rlink_st7.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 Lou Deluxe *
* lou.openocd012@fixit.nospammail.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_RLINK_ST7_H
diff --git a/src/jtag/drivers/rshim.c b/src/jtag/drivers/rshim.c
index 246e931..174fa12 100644
--- a/src/jtag/drivers/rshim.c
+++ b/src/jtag/drivers/rshim.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (c) 2020, Mellanox Technologies Ltd. - All Rights Reserved
* Liming Sun <lsun@mellanox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
@@ -282,36 +271,44 @@ static int rshim_ap_q_read(struct adiv5_ap *ap, unsigned int reg,
uint32_t addr;
int rc = ERROR_OK, tile;
+ if (is_adiv6(ap->dap)) {
+ static bool error_flagged;
+ if (!error_flagged)
+ LOG_ERROR("ADIv6 dap not supported by rshim dap-direct mode");
+ error_flagged = true;
+ return ERROR_FAIL;
+ }
+
switch (reg) {
- case MEM_AP_REG_CSW:
+ case ADIV5_MEM_AP_REG_CSW:
*data = ap_csw;
break;
- case MEM_AP_REG_CFG:
+ case ADIV5_MEM_AP_REG_CFG:
*data = 0;
break;
- case MEM_AP_REG_BASE:
+ case ADIV5_MEM_AP_REG_BASE:
*data = RSH_CS_ROM_BASE;
break;
- case AP_REG_IDR:
+ case ADIV5_AP_REG_IDR:
if (ap->ap_num == 0)
*data = APB_AP_IDR;
else
*data = 0;
break;
- case MEM_AP_REG_BD0:
- case MEM_AP_REG_BD1:
- case MEM_AP_REG_BD2:
- case MEM_AP_REG_BD3:
+ case ADIV5_MEM_AP_REG_BD0:
+ case ADIV5_MEM_AP_REG_BD1:
+ case ADIV5_MEM_AP_REG_BD2:
+ case ADIV5_MEM_AP_REG_BD3:
addr = (ap_tar & ~0xf) + (reg & 0x0C);
ap_addr_2_tile(&tile, &addr);
rc = coresight_read(tile, addr, data);
break;
- case MEM_AP_REG_DRW:
+ case ADIV5_MEM_AP_REG_DRW:
addr = (ap_tar & ~0x3) + ap_tar_inc;
ap_addr_2_tile(&tile, &addr);
rc = coresight_read(tile, addr, data);
@@ -338,31 +335,39 @@ static int rshim_ap_q_write(struct adiv5_ap *ap, unsigned int reg,
int rc = ERROR_OK, tile;
uint32_t addr;
+ if (is_adiv6(ap->dap)) {
+ static bool error_flagged;
+ if (!error_flagged)
+ LOG_ERROR("ADIv6 dap not supported by rshim dap-direct mode");
+ error_flagged = true;
+ return ERROR_FAIL;
+ }
+
if (ap_bank != 0) {
rshim_dap_retval = ERROR_FAIL;
return ERROR_FAIL;
}
switch (reg) {
- case MEM_AP_REG_CSW:
+ case ADIV5_MEM_AP_REG_CSW:
ap_csw = data;
break;
- case MEM_AP_REG_TAR:
+ case ADIV5_MEM_AP_REG_TAR:
ap_tar = data;
ap_tar_inc = 0;
break;
- case MEM_AP_REG_BD0:
- case MEM_AP_REG_BD1:
- case MEM_AP_REG_BD2:
- case MEM_AP_REG_BD3:
+ case ADIV5_MEM_AP_REG_BD0:
+ case ADIV5_MEM_AP_REG_BD1:
+ case ADIV5_MEM_AP_REG_BD2:
+ case ADIV5_MEM_AP_REG_BD3:
addr = (ap_tar & ~0xf) + (reg & 0x0C);
ap_addr_2_tile(&tile, &addr);
rc = coresight_write(tile, addr, data);
break;
- case MEM_AP_REG_DRW:
+ case ADIV5_MEM_AP_REG_DRW:
ap_drw = data;
addr = (ap_tar & ~0x3) + ap_tar_inc;
ap_addr_2_tile(&tile, &addr);
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index bb2c817..5b051c1 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2020 by Tarek Bochkati *
* Tarek Bochkati <tarek.bouchkati@gmail.com> *
@@ -13,19 +15,6 @@
* spen@spen-soft.co.uk *
* *
* This code is based on https://github.com/texane/stlink *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -4152,7 +4141,7 @@ static int stlink_dap_reinit_interface(void)
stlink_dap_handle->reconnect_pending = false;
/* on new FW, calling mode-leave closes all the opened AP; reopen them! */
if (stlink_dap_handle->version.flags & STLINK_F_HAS_AP_INIT)
- for (int apsel = 0; apsel <= DP_APSEL_MAX; apsel++)
+ for (unsigned int apsel = 0; apsel <= DP_APSEL_MAX; apsel++)
if (test_bit(apsel, opened_ap)) {
clear_bit(apsel, opened_ap);
stlink_dap_open_ap(apsel);
@@ -4286,7 +4275,15 @@ static int stlink_dap_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *d
uint32_t dummy;
int retval;
- if (reg != AP_REG_IDR) {
+ if (is_adiv6(dap)) {
+ static bool error_flagged;
+ if (!error_flagged)
+ LOG_ERROR("ADIv6 dap not supported by stlink dap-direct mode");
+ error_flagged = true;
+ return ERROR_FAIL;
+ }
+
+ if (reg != ADIV5_AP_REG_IDR) {
retval = stlink_dap_open_ap(ap->ap_num);
if (retval != ERROR_OK)
return retval;
@@ -4304,6 +4301,14 @@ static int stlink_dap_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t d
struct adiv5_dap *dap = ap->dap;
int retval;
+ if (is_adiv6(dap)) {
+ static bool error_flagged;
+ if (!error_flagged)
+ LOG_ERROR("ADIv6 dap not supported by stlink dap-direct mode");
+ error_flagged = true;
+ return ERROR_FAIL;
+ }
+
retval = stlink_dap_open_ap(ap->ap_num);
if (retval != ERROR_OK)
return retval;
@@ -4332,7 +4337,7 @@ static int stlink_usb_misc_rw_segment(void *handle, const struct dap_queue *q, u
LOG_DEBUG("Queue: %u commands in %u items", len, items);
- int ap_num = DP_APSEL_INVALID;
+ uint32_t ap_num = DP_APSEL_INVALID;
unsigned int cmd_index = 0;
unsigned int val_index = ALIGN_UP(items, 4);
for (unsigned int i = 0; i < len; i++) {
@@ -4481,7 +4486,7 @@ static int stlink_usb_count_misc_rw_queue(void *handle, const struct dap_queue *
{
struct stlink_usb_handle_s *h = handle;
unsigned int i, items = 0;
- int ap_num = DP_APSEL_INVALID;
+ uint32_t ap_num = DP_APSEL_INVALID;
unsigned int misc_max_items = (h->version.stlink == 2) ? STLINK_V2_RW_MISC_SIZE : STLINK_V3_RW_MISC_SIZE;
if (!(h->version.flags & STLINK_F_HAS_RW_MISC))
@@ -4591,7 +4596,7 @@ static void stlink_dap_run_internal(struct adiv5_dap *dap)
break;
case CMD_AP_WRITE:
/* ignore increment packed, not supported */
- if (q->ap_w.reg == MEM_AP_REG_CSW)
+ if (q->ap_w.reg == ADIV5_MEM_AP_REG_CSW)
q->ap_w.data &= ~CSW_ADDRINC_PACKED;
retval = stlink_dap_ap_write(q->ap_w.ap, q->ap_w.reg, q->ap_w.data);
break;
@@ -4736,18 +4741,18 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg,
/* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_RD_NO_INC
* and STLINK_F_HAS_RW_MISC */
if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) &&
- (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 ||
- reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) {
+ (reg == ADIV5_MEM_AP_REG_DRW || reg == ADIV5_MEM_AP_REG_BD0 || reg == ADIV5_MEM_AP_REG_BD1 ||
+ reg == ADIV5_MEM_AP_REG_BD2 || reg == ADIV5_MEM_AP_REG_BD3)) {
/* de-queue previous write-TAR */
struct dap_queue *prev_q = q - 1;
- if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_TAR) {
+ if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_TAR) {
stlink_dap_handle->queue_index = i;
i--;
q = prev_q;
prev_q--;
}
/* de-queue previous write-CSW if it didn't changed ap->csw_default */
- if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW &&
+ if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_CSW &&
!prev_q->ap_w.changes_csw_default) {
stlink_dap_handle->queue_index = i;
q = prev_q;
@@ -4769,7 +4774,7 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg,
return ERROR_FAIL;
}
- q->mem_ap.addr = (reg == MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c));
+ q->mem_ap.addr = (reg == ADIV5_MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c));
q->mem_ap.ap = ap;
q->mem_ap.p_data = data;
q->mem_ap.csw = ap->csw_default;
@@ -4802,18 +4807,18 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg,
/* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_WR_NO_INC
* and STLINK_F_HAS_RW_MISC */
if ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) &&
- (reg == MEM_AP_REG_DRW || reg == MEM_AP_REG_BD0 || reg == MEM_AP_REG_BD1 ||
- reg == MEM_AP_REG_BD2 || reg == MEM_AP_REG_BD3)) {
+ (reg == ADIV5_MEM_AP_REG_DRW || reg == ADIV5_MEM_AP_REG_BD0 || reg == ADIV5_MEM_AP_REG_BD1 ||
+ reg == ADIV5_MEM_AP_REG_BD2 || reg == ADIV5_MEM_AP_REG_BD3)) {
/* de-queue previous write-TAR */
struct dap_queue *prev_q = q - 1;
- if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_TAR) {
+ if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_TAR) {
stlink_dap_handle->queue_index = i;
i--;
q = prev_q;
prev_q--;
}
/* de-queue previous write-CSW if it didn't changed ap->csw_default */
- if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == MEM_AP_REG_CSW &&
+ if (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_CSW &&
!prev_q->ap_w.changes_csw_default) {
stlink_dap_handle->queue_index = i;
q = prev_q;
@@ -4835,7 +4840,7 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg,
return ERROR_FAIL;
}
- q->mem_ap.addr = (reg == MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c));
+ q->mem_ap.addr = (reg == ADIV5_MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c));
q->mem_ap.ap = ap;
q->mem_ap.data = data;
q->mem_ap.csw = ap->csw_default;
@@ -4848,9 +4853,10 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg,
q->ap_w.reg = reg;
q->ap_w.ap = ap;
q->ap_w.data = data;
- if (reg == MEM_AP_REG_CSW && ap->csw_default != last_csw_default[ap->ap_num]) {
+ uint8_t ap_num = ap->ap_num;
+ if (reg == ADIV5_MEM_AP_REG_CSW && ap->csw_default != last_csw_default[ap_num]) {
q->ap_w.changes_csw_default = true;
- last_csw_default[ap->ap_num] = ap->csw_default;
+ last_csw_default[ap_num] = ap->csw_default;
} else {
q->ap_w.changes_csw_default = false;
}
diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c
index 103b810..ee254d6 100644
--- a/src/jtag/drivers/sysfsgpio.c
+++ b/src/jtag/drivers/sysfsgpio.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* 2014-12: Addition of the SWD protocol support is based on the initial work
diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c
index e48d0e2..ca52559 100644
--- a/src/jtag/drivers/ti_icdi_usb.c
+++ b/src/jtag/drivers/ti_icdi_usb.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* *
* Copyright (C) 2012 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c
index 50609a6..fd29f12 100644
--- a/src/jtag/drivers/ulink.c
+++ b/src/jtag/drivers/ulink.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011-2013 by Martin Schmoelzer *
* <martin.schmoelzer@student.tuwien.ac.at> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/usb_blaster/Makefile.am b/src/jtag/drivers/usb_blaster/Makefile.am
index a6694c5..0fb8a07 100644
--- a/src/jtag/drivers/usb_blaster/Makefile.am
+++ b/src/jtag/drivers/usb_blaster/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libocdusbblaster.la
%C%_libocdusbblaster_la_SOURCES = $(USB_BLASTER_SRC)
%C%_libocdusbblaster_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS)
diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c
index 21f9ae7..7f97818 100644
--- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c
+++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Driver for USB-JTAG, Altera USB-Blaster II and compatibles
*
* Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/usb_blaster/ublast_access.h b/src/jtag/drivers/usb_blaster/ublast_access.h
index ada764c..3e138bd 100644
--- a/src/jtag/drivers/usb_blaster/ublast_access.h
+++ b/src/jtag/drivers/usb_blaster/ublast_access.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Driver for USB-JTAG, Altera USB-Blaster and compatibles
*
@@ -10,19 +12,6 @@
* Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca
* Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
#ifndef OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H
diff --git a/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c b/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c
index cb442f2..eb312ef 100644
--- a/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c
+++ b/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Driver for USB-JTAG, Altera USB-Blaster and compatibles
*
@@ -9,19 +11,6 @@
* Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca
* Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c
index 049a243..8c37048 100644
--- a/src/jtag/drivers/usb_blaster/usb_blaster.c
+++ b/src/jtag/drivers/usb_blaster/usb_blaster.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Driver for USB-JTAG, Altera USB-Blaster and compatibles
*
@@ -10,19 +12,6 @@
* Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca
* Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
/*
diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c
index a2ebdbc..0c0f24e 100644
--- a/src/jtag/drivers/usbprog.c
+++ b/src/jtag/drivers/usbprog.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Benedikt Sauter *
* sauter@ixbat.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
@@ -346,8 +335,6 @@ static void usbprog_reset(int trst, int srst)
/*************** jtag lowlevel functions ********************/
-struct usb_bus *busses;
-
struct usbprog_jtag *usbprog_jtag_open(void)
{
const uint16_t vids[] = { VID, 0 };
diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c
index a81740c..ef7a493 100644
--- a/src/jtag/drivers/vdebug.c
+++ b/src/jtag/drivers/vdebug.c
@@ -1,35 +1,14 @@
-/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
-/*----------------------------------------------------------------------------
- * Copyright 2020-2021 Cadence Design Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *----------------------------------------------------------------------------
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *----------------------------------------------------------------------------
-*/
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+
+/* Copyright 2020-2022 Cadence Design Systems, Inc. */
/*!
* @file
*
* @brief the virtual debug interface provides a connection between a sw debugger
- * and the simulated, emulated core over a soft connection, implemented by DPI
- * The vdebug debug driver currently supports JTAG transport
- * TODO: implement support and test big endian platforms
+ * and the simulated, emulated core. The openOCD client connects via TCP sockets
+ * with vdebug server and over DPI-based transactor with the emulation or simulation
+ * The vdebug debug driver supports JTAG and DAP-level transports
*
*/
@@ -68,16 +47,18 @@
#include "jtag/interface.h"
#include "jtag/commands.h"
#include "transport/transport.h"
+#include "target/arm_adi_v5.h"
#include "helper/time_support.h"
#include "helper/replacements.h"
#include "helper/log.h"
+#include "helper/list.h"
-#define VD_VERSION 43
+#define VD_VERSION 44
#define VD_BUFFER_LEN 4024
#define VD_CHEADER_LEN 24
#define VD_SHEADER_LEN 16
-#define VD_MAX_MEMORIES 4
+#define VD_MAX_MEMORIES 20
#define VD_POLL_INTERVAL 500
#define VD_SCALE_PSTOMS 1000000000
@@ -149,6 +130,8 @@ enum {
VD_CMD_SIGSET = 0x0a,
VD_CMD_SIGGET = 0x0b,
VD_CMD_JTAGCLOCK = 0x0f,
+ VD_CMD_REGWRITE = 0x15,
+ VD_CMD_REGREAD = 0x16,
VD_CMD_JTAGSHTAP = 0x1a,
VD_CMD_MEMOPEN = 0x21,
VD_CMD_MEMCLOSE = 0x22,
@@ -156,6 +139,13 @@ enum {
};
enum {
+ VD_ASPACE_AP = 0x01,
+ VD_ASPACE_DP = 0x02,
+ VD_ASPACE_ID = 0x03,
+ VD_ASPACE_AB = 0x04,
+};
+
+enum {
VD_BATCH_NO = 0,
VD_BATCH_WO = 1,
VD_BATCH_WR = 2,
@@ -165,37 +155,32 @@ struct vd_shm {
struct { /* VD_CHEADER_LEN written by client */
uint8_t cmd; /* 000; command */
uint8_t type; /* 001; interface type */
- uint16_t waddr; /* 002; write pointer */
- uint16_t wbytes; /* 004; data bytes */
- uint16_t rbytes; /* 006; data bytes to read */
- uint16_t wwords; /* 008; data words */
- uint16_t rwords; /* 00a; data words to read */
- uint32_t rwdata; /* 00c; read/write data */
- uint32_t offset; /* 010; address offset */
- uint16_t offseth; /* 014; address offset 47:32 */
- uint16_t wid; /* 016; request id*/
- };
- union { /* 018; */
- uint8_t wd8[VD_BUFFER_LEN];
- uint16_t wd16[VD_BUFFER_LEN / 2];
- uint32_t wd32[VD_BUFFER_LEN / 4];
- uint64_t wd64[VD_BUFFER_LEN / 8];
+ uint8_t waddr[2]; /* 002; write pointer */
+ uint8_t wbytes[2]; /* 004; data bytes */
+ uint8_t rbytes[2]; /* 006; data bytes to read */
+ uint8_t wwords[2]; /* 008; data words */
+ uint8_t rwords[2]; /* 00a; data words to read */
+ uint8_t rwdata[4]; /* 00c; read/write data */
+ uint8_t offset[4]; /* 010; address offset */
+ uint8_t offseth[2]; /* 014; address offset 47:32 */
+ uint8_t wid[2]; /* 016; request id*/
};
+ uint8_t wd8[VD_BUFFER_LEN]; /* 018; */
struct { /* VD_SHEADER_LEN written by server */
- uint16_t rid; /* fd0: request id read */
- uint16_t awords; /* fd2: actual data words read back */
- int32_t status; /* fd4; */
- uint64_t duttime; /* fd8; */
+ uint8_t rid[2]; /* fd0: request id read */
+ uint8_t awords[2]; /* fd2: actual data words read back */
+ uint8_t status[4]; /* fd4; */
+ uint8_t duttime[8]; /* fd8; */
};
- union { /* fe0: */
- uint8_t rd8[VD_BUFFER_LEN];
- uint16_t rd16[VD_BUFFER_LEN / 2];
- uint32_t rd32[VD_BUFFER_LEN / 4];
- uint64_t rd64[VD_BUFFER_LEN / 8];
- };
- uint32_t state; /* 1f98; connection state */
- uint32_t count; /* 1f9c; */
+ uint8_t rd8[VD_BUFFER_LEN]; /* fe0: */
+ uint8_t state[4]; /* 1f98; connection state */
+ uint8_t count[4]; /* 1f9c; */
uint8_t dummy[96]; /* 1fa0; 48+40B+8B; */
+} __attribute__((packed));
+
+struct vd_rdata {
+ struct list_head lh;
+ uint8_t *rdata;
};
struct vd_client {
@@ -222,7 +207,7 @@ struct vd_client {
char server_name[32];
char bfm_path[128];
char mem_path[VD_MAX_MEMORIES][128];
- uint8_t *tdo;
+ struct vd_rdata rdataq;
};
struct vd_jtag_hdr {
@@ -234,6 +219,16 @@ struct vd_jtag_hdr {
uint64_t rlen:16;
};
+struct vd_reg_hdr {
+ uint64_t prot:3;
+ uint64_t nonincr:1;
+ uint64_t haddr:12;
+ uint64_t tlen:11;
+ uint64_t asize:3;
+ uint64_t cmd:2;
+ uint64_t addr:32;
+};
+
static struct vd_shm *pbuf;
static struct vd_client vdc;
@@ -277,7 +272,7 @@ static int vdebug_socket_open(char *server_addr, uint32_t port)
LOG_ERROR("socket_open: cannot resolve address %s, error %d", server_addr, vdebug_socket_error());
rc = VD_ERR_SOC_ADDR;
} else {
- ((struct sockaddr_in *)(ainfo->ai_addr))->sin_port = htons(port);
+ buf_set_u32((uint8_t *)ainfo->ai_addr->sa_data, 0, 16, htons(port));
if (connect(hsock, ainfo->ai_addr, sizeof(struct sockaddr)) < 0) {
LOG_ERROR("socket_open: cannot connect to %s:%d, error %d", server_addr, port, vdebug_socket_error());
rc = VD_ERR_SOC_CONN;
@@ -299,8 +294,8 @@ static int vdebug_socket_receive(int hsock, struct vd_shm *pmem)
{
int rc;
int dreceived = 0;
- int offset = (uint8_t *)&pmem->rid - &pmem->cmd;
- int to_receive = VD_SHEADER_LEN + pmem->rbytes;
+ int offset = &pmem->rid[0] - &pmem->cmd;
+ int to_receive = VD_SHEADER_LEN + le_to_h_u16(pmem->rbytes);
char *pb = (char *)pmem;
do {
@@ -320,7 +315,7 @@ static int vdebug_socket_receive(int hsock, struct vd_shm *pmem)
static int vdebug_socket_send(int hsock, struct vd_shm *pmem)
{
- int rc = send(hsock, (const char *)&pmem->cmd, VD_CHEADER_LEN + pmem->wbytes, 0);
+ int rc = send(hsock, (const char *)&pmem->cmd, VD_CHEADER_LEN + le_to_h_u16(pmem->wbytes), 0);
if (rc <= 0)
LOG_WARNING("socket_send: send failed, error %d", vdebug_socket_error());
else
@@ -333,6 +328,7 @@ static uint32_t vdebug_wait_server(int hsock, struct vd_shm *pmem)
{
if (!hsock)
return VD_ERR_SOC_OPEN;
+
int st = vdebug_socket_send(hsock, pmem);
if (st <= 0)
return VD_ERR_SOC_SEND;
@@ -341,9 +337,9 @@ static uint32_t vdebug_wait_server(int hsock, struct vd_shm *pmem)
if (rd <= 0)
return VD_ERR_SOC_RECV;
- int rc = pmem->status;
+ int rc = le_to_h_u32(pmem->status);
LOG_DEBUG_IO("wait_server: cmd %02" PRIx8 " done, sent %d, rcvd %d, status %d",
- pmem->cmd, st, rd, rc);
+ pmem->cmd, st, rd, rc);
return rc;
}
@@ -356,22 +352,23 @@ int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count)
int64_t ts, te;
uint8_t *tdo;
int rc;
- struct vd_jtag_hdr *hdr;
+ uint64_t jhdr;
+ struct vd_rdata *rd;
req = 0; /* beginning of request */
waddr = 0;
rwords = 0;
- pm->wbytes = pm->wwords * vdc.buf_width;
- pm->rbytes = pm->rwords * vdc.buf_width;
+ h_u16_to_le(pm->wbytes, le_to_h_u16(pm->wwords) * vdc.buf_width);
+ h_u16_to_le(pm->rbytes, le_to_h_u16(pm->rwords) * vdc.buf_width);
ts = timeval_ms();
rc = vdebug_wait_server(hsock, pm);
while (!rc && (req < count)) { /* loop over requests to read data and print out */
- hdr = (struct vd_jtag_hdr *)&pm->wd8[waddr * 4];
- hwords = hdr->wlen;
- words = hdr->rlen;
- anum = hdr->tlen;
- num_pre = hdr->pre;
- num_post = hdr->post;
+ jhdr = le_to_h_u64(&pm->wd8[waddr * 4]);
+ words = jhdr >> 48;
+ hwords = (jhdr >> 32) & 0xffff;
+ anum = jhdr & 0xffffff;
+ num_pre = (jhdr >> 27) & 0x7;
+ num_post = (jhdr >> 24) & 0x7;
if (num_post)
num = anum - num_pre - num_post + 1;
else
@@ -379,21 +376,29 @@ int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count)
bytes = (num + 7) / 8;
vdc.trans_last = (req + 1) < count ? 0 : 1;
vdc.trans_first = waddr ? 0 : 1;
- if (hdr->cmd == 3) { /* read */
- tdo = vdc.tdo;
+ if (((jhdr >> 30) & 0x3) == 3) { /* cmd is read */
+ if (!rwords) {
+ rd = &vdc.rdataq;
+ tdo = rd->rdata;
+ } else {
+ rd = list_first_entry(&vdc.rdataq.lh, struct vd_rdata, lh);
+ tdo = rd->rdata;
+ list_del(&rd->lh);
+ free(rd);
+ }
for (unsigned int j = 0; j < bytes; j++) {
tdo[j] = (pm->rd8[rwords * 8 + j] >> num_pre) | (pm->rd8[rwords * 8 + j + 1] << (8 - num_pre));
- LOG_DEBUG_IO("%04x D0[%02x]:%02x", pm->wid - count + req, j, tdo[j]);
+ LOG_DEBUG_IO("%04x D0[%02x]:%02x", le_to_h_u16(pm->wid) - count + req, j, tdo[j]);
}
rwords += words; /* read data offset */
} else {
tdo = NULL;
}
- waddr += sizeof(struct vd_jtag_hdr) / 4; /* waddr past header */
+ waddr += sizeof(uint64_t) / 4; /* waddr past header */
tdi = (pm->wd8[waddr * 4] >> num_pre) | (pm->wd8[waddr * 4 + 1] << (8 - num_pre));
tms = (pm->wd8[waddr * 4 + 4] >> num_pre) | (pm->wd8[waddr * 4 + 4 + 1] << (8 - num_pre));
- LOG_DEBUG("%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x",
- pm->wid - count + req, num, (vdc.trans_first << 14) | (vdc.trans_last << 15),
+ LOG_DEBUG_IO("%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x",
+ le_to_h_u16(pm->wid) - count + req, num, (vdc.trans_first << 14) | (vdc.trans_last << 15),
waddr - 2, tdi, tms, (tdo ? tdo[0] : 0xdd));
waddr += hwords * 2; /* start of next request */
req += 1;
@@ -406,10 +411,83 @@ int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count)
te = timeval_ms();
vdc.targ_time += (uint32_t)(te - ts);
- pm->offseth = 0; /* reset buffer write address */
- pm->offset = 0;
- pm->rwords = 0;
- pm->waddr = 0;
+ h_u16_to_le(pm->offseth, 0); /* reset buffer write address */
+ h_u32_to_le(pm->offset, 0);
+ h_u16_to_le(pm->rwords, 0);
+ h_u16_to_le(pm->waddr, 0);
+ assert(list_empty(&vdc.rdataq.lh));/* list should be empty after run queue */
+
+ return rc;
+}
+
+int vdebug_run_reg_queue(int hsock, struct vd_shm *pm, unsigned int count)
+{
+ unsigned int num, awidth, wwidth;
+ unsigned int req, waddr, rwords;
+ uint8_t aspace;
+ uint32_t addr;
+ int64_t ts, te;
+ uint8_t *data;
+ int rc;
+ uint64_t rhdr;
+ struct vd_rdata *rd;
+
+ req = 0; /* beginning of request */
+ waddr = 0;
+ rwords = 0;
+ h_u16_to_le(pm->wbytes, le_to_h_u16(pm->wwords) * vdc.buf_width);
+ h_u16_to_le(pm->rbytes, le_to_h_u16(pm->rwords) * vdc.buf_width);
+ ts = timeval_ms();
+ rc = vdebug_wait_server(hsock, pm);
+ while (!rc && (req < count)) { /* loop over requests to read data and print out */
+ rhdr = le_to_h_u64(&pm->wd8[waddr * 4]);
+ addr = rhdr >> 32; /* reconstruct data for a single request */
+ num = (rhdr >> 16) & 0x7ff;
+ aspace = rhdr & 0x3;
+ awidth = (1 << ((rhdr >> 27) & 0x7));
+ wwidth = (awidth + vdc.buf_width - 1) / vdc.buf_width;
+ vdc.trans_last = (req + 1) < count ? 0 : 1;
+ vdc.trans_first = waddr ? 0 : 1;
+ if (((rhdr >> 30) & 0x3) == 2) { /* cmd is read */
+ if (num) {
+ if (!rwords) {
+ rd = &vdc.rdataq;
+ data = rd->rdata;
+ } else {
+ rd = list_first_entry(&vdc.rdataq.lh, struct vd_rdata, lh);
+ data = rd->rdata;
+ list_del(&rd->lh);
+ free(rd);
+ }
+ for (unsigned int j = 0; j < num; j++)
+ memcpy(&data[j * awidth], &pm->rd8[(rwords + j) * awidth], awidth);
+ }
+ LOG_DEBUG_IO("read %04x AS:%02x RG:%02x O:%05x @%03x D:%08x", le_to_h_u16(pm->wid) - count + req,
+ aspace, addr, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr,
+ (num ? le_to_h_u32(&pm->rd8[rwords * 4]) : 0xdead));
+ rwords += num * wwidth;
+ waddr += sizeof(uint64_t) / 4; /* waddr past header */
+ } else {
+ LOG_DEBUG_IO("write %04x AS:%02x RG:%02x O:%05x @%03x D:%08x", le_to_h_u16(pm->wid) - count + req,
+ aspace, addr, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr,
+ le_to_h_u32(&pm->wd8[(waddr + num + 1) * 4]));
+ waddr += sizeof(uint64_t) / 4 + (num * wwidth * awidth + 3) / 4;
+ }
+ req += 1;
+ }
+
+ if (rc) {
+ LOG_ERROR("0x%x executing transaction", rc);
+ rc = ERROR_FAIL;
+ }
+
+ te = timeval_ms();
+ vdc.targ_time += (uint32_t)(te - ts);
+ h_u16_to_le(pm->offseth, 0); /* reset buffer write address */
+ h_u32_to_le(pm->offset, 0);
+ h_u16_to_le(pm->rwords, 0);
+ h_u16_to_le(pm->waddr, 0);
+ assert(list_empty(&vdc.rdataq.lh));/* list should be empty after run queue */
return rc;
}
@@ -420,35 +498,35 @@ static int vdebug_open(int hsock, struct vd_shm *pm, const char *path,
int rc = VD_ERR_NOT_OPEN;
pm->cmd = VD_CMD_OPEN;
- pm->wid = VD_VERSION; /* client version */
- pm->wbytes = 0;
- pm->rbytes = 0;
- pm->wwords = 0;
- pm->rwords = 0;
+ h_u16_to_le(pm->wid, VD_VERSION); /* client version */
+ h_u16_to_le(pm->wbytes, 0);
+ h_u16_to_le(pm->rbytes, 0);
+ h_u16_to_le(pm->wwords, 0);
+ h_u16_to_le(pm->rwords, 0);
rc = vdebug_wait_server(hsock, pm);
if (rc != 0) { /* communication problem */
LOG_ERROR("0x%x connecting to server", rc);
- } else if (pm->rid < pm->wid) {
- LOG_ERROR("server version %d too old for the client %d", pm->rid, pm->wid);
+ } else if (le_to_h_u16(pm->rid) < le_to_h_u16(pm->wid)) {
+ LOG_ERROR("server version %d too old for the client %d", le_to_h_u16(pm->rid), le_to_h_u16(pm->wid));
pm->cmd = VD_CMD_CLOSE; /* let server close the connection */
vdebug_wait_server(hsock, pm);
rc = VD_ERR_VERSION;
} else {
pm->cmd = VD_CMD_CONNECT;
pm->type = type; /* BFM type to connect to, here JTAG */
- pm->rwdata = sig_mask | VD_SIG_BUF | (VD_SIG_BUF << 16);
- pm->wbytes = strlen(path) + 1;
- pm->rbytes = 12;
- pm->wid = 0; /* reset wid for transaction ID */
- pm->wwords = 0;
- pm->rwords = 0;
- memcpy(pm->wd8, path, pm->wbytes + 1);
+ h_u32_to_le(pm->rwdata, sig_mask | VD_SIG_BUF | (VD_SIG_BUF << 16));
+ h_u16_to_le(pm->wbytes, strlen(path) + 1);
+ h_u16_to_le(pm->rbytes, 12);
+ h_u16_to_le(pm->wid, 0); /* reset wid for transaction ID */
+ h_u16_to_le(pm->wwords, 0);
+ h_u16_to_le(pm->rwords, 0);
+ memcpy(pm->wd8, path, le_to_h_u16(pm->wbytes));
rc = vdebug_wait_server(hsock, pm);
- vdc.sig_read = pm->rwdata >> 16; /* signal read mask */
- vdc.sig_write = pm->rwdata; /* signal write mask */
+ vdc.sig_read = le_to_h_u32(pm->rwdata) >> 16; /* signal read mask */
+ vdc.sig_write = le_to_h_u32(pm->rwdata); /* signal write mask */
vdc.bfm_period = period_ps;
- vdc.buf_width = pm->rd32[0] / 8;/* access width in bytes */
- vdc.addr_bits = pm->rd32[2]; /* supported address bits */
+ vdc.buf_width = le_to_h_u32(&pm->rd8[0]) / 8;/* access width in bytes */
+ vdc.addr_bits = le_to_h_u32(&pm->rd8[2 * 4]); /* supported address bits */
}
if (rc) {
@@ -456,6 +534,7 @@ static int vdebug_open(int hsock, struct vd_shm *pm, const char *path,
return ERROR_FAIL;
}
+ INIT_LIST_HEAD(&vdc.rdataq.lh);
LOG_DEBUG("%s type %0x, period %dps, buffer %dx%dB signals r%04xw%04x",
path, type, vdc.bfm_period, VD_BUFFER_LEN / vdc.buf_width,
vdc.buf_width, vdc.sig_read, vdc.sig_write);
@@ -467,17 +546,17 @@ static int vdebug_close(int hsock, struct vd_shm *pm, uint8_t type)
{
pm->cmd = VD_CMD_DISCONNECT;
pm->type = type; /* BFM type, here JTAG */
- pm->wbytes = 0;
- pm->rbytes = 0;
- pm->wwords = 0;
- pm->rwords = 0;
+ h_u16_to_le(pm->wbytes, 0);
+ h_u16_to_le(pm->rbytes, 0);
+ h_u16_to_le(pm->wwords, 0);
+ h_u16_to_le(pm->rwords, 0);
vdebug_wait_server(hsock, pm);
pm->cmd = VD_CMD_CLOSE;
- pm->wid = VD_VERSION; /* client version */
- pm->wbytes = 0;
- pm->rbytes = 0;
- pm->wwords = 0;
- pm->rwords = 0;
+ h_u16_to_le(pm->wid, VD_VERSION); /* client version */
+ h_u16_to_le(pm->wbytes, 0);
+ h_u16_to_le(pm->rbytes, 0);
+ h_u16_to_le(pm->wwords, 0);
+ h_u16_to_le(pm->rwords, 0);
vdebug_wait_server(hsock, pm);
LOG_DEBUG("type %0x", type);
@@ -488,9 +567,9 @@ static int vdebug_wait(int hsock, struct vd_shm *pm, uint32_t cycles)
{
if (cycles) {
pm->cmd = VD_CMD_WAIT;
- pm->wbytes = 0;
- pm->rbytes = 0;
- pm->rwdata = cycles; /* clock sycles to wait */
+ h_u16_to_le(pm->wbytes, 0);
+ h_u16_to_le(pm->rbytes, 0);
+ h_u32_to_le(pm->rwdata, cycles); /* clock sycles to wait */
int rc = vdebug_wait_server(hsock, pm);
if (rc) {
LOG_ERROR("0x%x waiting %" PRIx32 " cycles", rc, cycles);
@@ -505,9 +584,9 @@ static int vdebug_wait(int hsock, struct vd_shm *pm, uint32_t cycles)
static int vdebug_sig_set(int hsock, struct vd_shm *pm, uint32_t write_mask, uint32_t value)
{
pm->cmd = VD_CMD_SIGSET;
- pm->wbytes = 0;
- pm->rbytes = 0;
- pm->rwdata = (write_mask << 16) | (value & 0xffff); /* mask and value of signals to set */
+ h_u16_to_le(pm->wbytes, 0);
+ h_u16_to_le(pm->rbytes, 0);
+ h_u32_to_le(pm->rwdata, (write_mask << 16) | (value & 0xffff)); /* mask and value of signals to set */
int rc = vdebug_wait_server(hsock, pm);
if (rc) {
LOG_ERROR("0x%x setting signals %04" PRIx32, rc, write_mask);
@@ -522,9 +601,9 @@ static int vdebug_sig_set(int hsock, struct vd_shm *pm, uint32_t write_mask, uin
static int vdebug_jtag_clock(int hsock, struct vd_shm *pm, uint32_t value)
{
pm->cmd = VD_CMD_JTAGCLOCK;
- pm->wbytes = 0;
- pm->rbytes = 0;
- pm->rwdata = value; /* divider value */
+ h_u16_to_le(pm->wbytes, 0);
+ h_u16_to_le(pm->rbytes, 0);
+ h_u32_to_le(pm->rwdata, value); /* divider value */
int rc = vdebug_wait_server(hsock, pm);
if (rc) {
LOG_ERROR("0x%x setting jtag_clock", rc);
@@ -546,11 +625,11 @@ static int vdebug_jtag_shift_tap(int hsock, struct vd_shm *pm, uint8_t num_pre,
int rc = 0;
pm->cmd = VD_CMD_JTAGSHTAP;
- vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO) || tdo;
+ vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO);
if (vdc.trans_first)
waddr = 0; /* reset buffer offset */
else
- waddr = pm->offseth; /* continue from the previous transaction */
+ waddr = le_to_h_u32(pm->offseth); /* continue from the previous transaction */
if (num_post) /* actual number of bits to shift */
anum = num + num_pre + num_post - 1;
else
@@ -559,25 +638,22 @@ static int vdebug_jtag_shift_tap(int hsock, struct vd_shm *pm, uint8_t num_pre,
words = (hwords + 1) / 2; /* in 8B TDO words to read */
bytes = (num + 7) / 8; /* data only portion in bytes */
/* buffer overflow check and flush */
- if (4 * waddr + sizeof(struct vd_jtag_hdr) + 8 * hwords + 64 > VD_BUFFER_LEN) {
+ if (4 * waddr + sizeof(uint64_t) + 8 * hwords + 64 > VD_BUFFER_LEN) {
vdc.trans_last = 1; /* force flush within 64B of buffer end */
- } else if (4 * waddr + sizeof(struct vd_jtag_hdr) + 8 * hwords > VD_BUFFER_LEN) {
+ } else if (4 * waddr + sizeof(uint64_t) + 8 * hwords > VD_BUFFER_LEN) {
/* this req does not fit, discard it */
LOG_ERROR("%04x L:%02d O:%05x @%04x too many bits to shift",
- pm->wid, anum, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr);
+ le_to_h_u16(pm->wid), anum, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr);
rc = ERROR_FAIL;
}
if (!rc && anum) {
- uint16_t i, j;
- struct vd_jtag_hdr *hdr = (struct vd_jtag_hdr *)&pm->wd8[4 * waddr]; /* 8 bytes header */
- hdr->cmd = (tdo ? 3 : 1); /* R and W bits */
- hdr->pre = num_pre;
- hdr->post = num_post;
- hdr->tlen = anum;
- hdr->wlen = hwords;
- hdr->rlen = words;
- pm->wid++; /* transaction ID */
+ uint16_t i, j; /* portability requires to use bit operations for 8B JTAG header */
+ uint64_t jhdr = (tdo ? ((uint64_t)(words) << 48) : 0) + ((uint64_t)(hwords) << 32) +
+ ((tdo ? 3UL : 1UL) << 30) + (num_pre << 27) + (num_post << 24) + anum;
+ h_u64_to_le(&pm->wd8[4 * waddr], jhdr);
+
+ h_u16_to_le(pm->wid, le_to_h_u16(pm->wid) + 1); /* transaction ID */
waddr += 2; /* waddr past header */
/* TDI/TMS data follows as 32 bit word pairs {TMS,TDI} */
pm->wd8[4 * waddr] = (tdi ? (tdi[0] << num_pre) : 0);
@@ -615,19 +691,102 @@ static int vdebug_jtag_shift_tap(int hsock, struct vd_shm *pm, uint8_t num_pre,
}
if (tdo) {
- pm->rwords += words; /* keep track of the words to read */
- vdc.tdo = tdo;
+ struct vd_rdata *rd;
+ if (le_to_h_u16(pm->rwords) == 0) {
+ rd = &vdc.rdataq;
+ } else {
+ rd = calloc(1, sizeof(struct vd_rdata));
+ if (!rd) /* check allocation for 24B */
+ return ERROR_FAIL;
+ list_add_tail(&rd->lh, &vdc.rdataq.lh);
+ }
+ rd->rdata = tdo;
+ h_u16_to_le(pm->rwords, le_to_h_u16(pm->rwords) + words);/* keep track of the words to read */
}
- pm->wwords = waddr / 2 + hwords; /* payload size *2 to include both TDI and TMS data */
- pm->waddr++;
+ h_u16_to_le(pm->wwords, waddr / 2 + hwords); /* payload size *2 to include both TDI and TMS data */
+ h_u16_to_le(pm->waddr, le_to_h_u16(pm->waddr) + 1);
}
if (!waddr) /* flush issued, but buffer empty */
;
else if (!vdc.trans_last) /* buffered request */
- pm->offseth = waddr + hwords * 2; /* offset for next transaction, must be even */
+ h_u16_to_le(pm->offseth, waddr + hwords * 2); /* offset for next transaction, must be even */
else /* execute batch of requests */
- rc = vdebug_run_jtag_queue(hsock, pm, pm->waddr);
+ rc = vdebug_run_jtag_queue(hsock, pm, le_to_h_u16(pm->waddr));
+ vdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */
+
+ return rc;
+}
+
+static int vdebug_reg_write(int hsock, struct vd_shm *pm, const uint32_t reg,
+ const uint32_t data, uint8_t aspace, uint8_t f_last)
+{
+ uint32_t waddr;
+ int rc = ERROR_OK;
+
+ pm->cmd = VD_CMD_REGWRITE;
+ vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO);
+ if (vdc.trans_first)
+ waddr = 0; /* reset buffer offset */
+ else
+ waddr = le_to_h_u16(pm->offseth); /* continue from the previous transaction */
+
+ if (4 * waddr + 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN)
+ vdc.trans_last = 1; /* force flush, no room for next request */
+
+ uint64_t rhdr = ((uint64_t)reg << 32) + (1UL << 30) + (2UL << 27) + (1UL << 16) + aspace;
+ h_u64_to_le(&pm->wd8[4 * waddr], rhdr);
+ h_u32_to_le(&pm->wd8[4 * (waddr + 2)], data);
+ h_u16_to_le(pm->wid, le_to_h_u16(pm->wid) + 1);
+ h_u16_to_le(pm->wwords, waddr + 3);
+ h_u16_to_le(pm->waddr, le_to_h_u16(pm->waddr) + 1);
+ if (!vdc.trans_last) /* buffered request */
+ h_u16_to_le(pm->offseth, waddr + 3);
+ else
+ rc = vdebug_run_reg_queue(hsock, pm, le_to_h_u16(pm->waddr));
+ vdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */
+
+ return rc;
+}
+
+static int vdebug_reg_read(int hsock, struct vd_shm *pm, const uint32_t reg,
+ uint32_t *data, uint8_t aspace, uint8_t f_last)
+{
+ uint32_t waddr;
+ int rc = ERROR_OK;
+
+ pm->cmd = VD_CMD_REGREAD;
+ vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO);
+ if (vdc.trans_first)
+ waddr = 0; /* reset buffer offset */
+ else
+ waddr = le_to_h_u16(pm->offseth); /* continue from the previous transaction */
+
+ if (4 * waddr + 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN)
+ vdc.trans_last = 1; /* force flush, no room for next request */
+
+ uint64_t rhdr = ((uint64_t)reg << 32) + (2UL << 30) + (2UL << 27) + ((data ? 1UL : 0UL) << 16) + aspace;
+ h_u64_to_le(&pm->wd8[4 * waddr], rhdr);
+ h_u16_to_le(pm->wid, le_to_h_u16(pm->wid) + 1);
+ if (data) {
+ struct vd_rdata *rd;
+ if (le_to_h_u16(pm->rwords) == 0) {
+ rd = &vdc.rdataq;
+ } else {
+ rd = calloc(1, sizeof(struct vd_rdata));
+ if (!rd) /* check allocation for 24B */
+ return ERROR_FAIL;
+ list_add_tail(&rd->lh, &vdc.rdataq.lh);
+ }
+ rd->rdata = (uint8_t *)data;
+ h_u16_to_le(pm->rwords, le_to_h_u16(pm->rwords) + 1);
+ }
+ h_u16_to_le(pm->wwords, waddr + 2);
+ h_u16_to_le(pm->waddr, le_to_h_u16(pm->waddr) + 1);
+ if (!vdc.trans_last) /* buffered request */
+ h_u16_to_le(pm->offseth, waddr + 2);
+ else
+ rc = vdebug_run_reg_queue(hsock, pm, le_to_h_u16(pm->waddr));
vdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */
return rc;
@@ -641,19 +800,19 @@ static int vdebug_mem_open(int hsock, struct vd_shm *pm, const char *path, uint8
return ERROR_OK;
pm->cmd = VD_CMD_MEMOPEN;
- pm->wbytes = strlen(path) + 1; /* includes terminating 0 */
- pm->rbytes = 8;
- pm->wwords = 0;
- pm->rwords = 0;
- memcpy(pm->wd8, path, pm->wbytes);
+ h_u16_to_le(pm->wbytes, strlen(path) + 1); /* includes terminating 0 */
+ h_u16_to_le(pm->rbytes, 8);
+ h_u16_to_le(pm->wwords, 0);
+ h_u16_to_le(pm->rwords, 0);
+ memcpy(pm->wd8, path, le_to_h_u16(pm->wbytes));
rc = vdebug_wait_server(hsock, pm);
if (rc) {
LOG_ERROR("0x%x opening memory %s", rc, path);
- } else if (ndx != pm->rd16[1]) {
- LOG_WARNING("Invalid memory index %" PRIu16 " returned. Direct memory access disabled", pm->rd16[1]);
+ } else if (ndx != pm->rd8[2]) {
+ LOG_WARNING("Invalid memory index %" PRIu16 " returned. Direct memory access disabled", pm->rd8[2]);
} else {
- vdc.mem_width[ndx] = pm->rd16[0] / 8; /* memory width in bytes */
- vdc.mem_depth[ndx] = pm->rd32[1]; /* memory depth in words */
+ vdc.mem_width[ndx] = le_to_h_u16(&pm->rd8[0]) / 8; /* memory width in bytes */
+ vdc.mem_depth[ndx] = le_to_h_u32(&pm->rd8[4]); /* memory depth in words */
LOG_DEBUG("%" PRIx8 ": %s memory %" PRIu32 "x%" PRIu32 "B, buffer %" PRIu32 "x%" PRIu32 "B", ndx, path,
vdc.mem_depth[ndx], vdc.mem_width[ndx], VD_BUFFER_LEN / vdc.mem_width[ndx], vdc.mem_width[ndx]);
}
@@ -664,15 +823,16 @@ static int vdebug_mem_open(int hsock, struct vd_shm *pm, const char *path, uint8
static void vdebug_mem_close(int hsock, struct vd_shm *pm, uint8_t ndx)
{
pm->cmd = VD_CMD_MEMCLOSE;
- pm->rwdata = ndx; /* which memory */
- pm->wbytes = 0;
- pm->rbytes = 0;
- pm->wwords = 0;
- pm->rwords = 0;
+ h_u32_to_le(pm->rwdata, ndx); /* which memory */
+ h_u16_to_le(pm->wbytes, 0);
+ h_u16_to_le(pm->rbytes, 0);
+ h_u16_to_le(pm->wwords, 0);
+ h_u16_to_le(pm->rwords, 0);
vdebug_wait_server(hsock, pm);
LOG_DEBUG("%" PRIx8 ": %s", ndx, vdc.mem_path[ndx]);
}
+
static int vdebug_init(void)
{
vdc.hsocket = vdebug_socket_open(vdc.server_name, vdc.server_port);
@@ -680,7 +840,7 @@ static int vdebug_init(void)
if (!pbuf) {
close_socket(vdc.hsocket);
vdc.hsocket = 0;
- LOG_ERROR("cannot allocate %lu bytes", sizeof(struct vd_shm));
+ LOG_ERROR("cannot allocate %zu bytes", sizeof(struct vd_shm));
return ERROR_FAIL;
}
if (vdc.hsocket <= 0) {
@@ -692,10 +852,13 @@ static int vdebug_init(void)
}
vdc.trans_first = 1;
vdc.poll_cycles = vdc.poll_max;
- uint32_t sig_mask = VD_SIG_RESET | VD_SIG_TRST | VD_SIG_TCKDIV;
+ uint32_t sig_mask = VD_SIG_RESET;
+ if (transport_is_jtag())
+ sig_mask |= VD_SIG_TRST | VD_SIG_TCKDIV;
+
int rc = vdebug_open(vdc.hsocket, pbuf, vdc.bfm_path, vdc.bfm_type, vdc.bfm_period, sig_mask);
if (rc != 0) {
- LOG_ERROR("cannot connect to %s, rc 0x%x", vdc.bfm_path, rc);
+ LOG_ERROR("0x%x cannot connect to %s", rc, vdc.bfm_path);
close_socket(vdc.hsocket);
vdc.hsocket = 0;
free(pbuf);
@@ -704,7 +867,7 @@ static int vdebug_init(void)
for (uint8_t i = 0; i < vdc.mem_ndx; i++) {
rc = vdebug_mem_open(vdc.hsocket, pbuf, vdc.mem_path[i], i);
if (rc != 0)
- LOG_ERROR("cannot connect to %s, rc 0x%x", vdc.mem_path[i], rc);
+ LOG_ERROR("0x%x cannot connect to %s", rc, vdc.mem_path[i]);
}
LOG_INFO("vdebug %d connected to %s through %s:%" PRIu16,
@@ -754,7 +917,7 @@ static int vdebug_reset(int trst, int srst)
static int vdebug_jtag_tms_seq(const uint8_t *tms, int num, uint8_t f_flush)
{
- LOG_INFO("tms len:%d tms:%x", num, *(const uint32_t *)tms);
+ LOG_INFO("tms len:%d tms:%x", num, *tms);
return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num, *tms, 0, NULL, 0, 0, NULL, f_flush);
}
@@ -811,8 +974,8 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush)
uint8_t cur_tms_post = i == cmd->num_fields - 1 ? tms_post : 0;
uint8_t cur_flush = i == cmd->num_fields - 1 ? f_flush : 0;
rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, cur_num_pre, cur_tms_pre,
- cmd->fields[i].num_bits, cmd->fields[i].out_value, cur_num_post, cur_tms_post,
- cmd->fields[i].in_value, cur_flush);
+ cmd->fields[i].num_bits, cmd->fields[i].out_value, cur_num_post, cur_tms_post,
+ cmd->fields[i].in_value, cur_flush);
if (rc)
break;
}
@@ -913,6 +1076,61 @@ static int vdebug_jtag_execute_queue(void)
return rc;
}
+static int vdebug_dap_connect(struct adiv5_dap *dap)
+{
+ return dap_dp_init(dap);
+}
+
+static int vdebug_dap_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
+{
+ return ERROR_OK;
+}
+
+static int vdebug_dap_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
+{
+ return vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0);
+}
+
+static int vdebug_dap_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
+{
+ return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0);
+}
+
+static int vdebug_dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
+{
+ if ((reg & DP_SELECT_APBANK) != ap->dap->select) {
+ vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0);
+ ap->dap->select = reg & DP_SELECT_APBANK;
+ }
+
+ vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, NULL, VD_ASPACE_AP, 0);
+
+ return vdebug_reg_read(vdc.hsocket, pbuf, DP_RDBUFF >> 2, data, VD_ASPACE_DP, 0);
+}
+
+static int vdebug_dap_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)
+{
+ if ((reg & DP_SELECT_APBANK) != ap->dap->select) {
+ vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0);
+ ap->dap->select = reg & DP_SELECT_APBANK;
+ }
+
+ return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_AP, 0);
+}
+
+static int vdebug_dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
+{
+ return vdebug_reg_write(vdc.hsocket, pbuf, 0, 0x1, VD_ASPACE_AB, 0);
+}
+
+static int vdebug_dap_run(struct adiv5_dap *dap)
+{
+ if (pbuf->waddr)
+ return vdebug_run_reg_queue(vdc.hsocket, pbuf, le_to_h_u16(pbuf->waddr));
+
+ return ERROR_OK;
+}
+
COMMAND_HANDLER(vdebug_set_server)
{
if ((CMD_ARGC != 1) || !strchr(CMD_ARGV[0], ':'))
@@ -951,7 +1169,10 @@ COMMAND_HANDLER(vdebug_set_bfm)
default:
break;
}
- vdc.bfm_type = VD_BFM_JTAG;
+ if (transport_is_dapdirect_swd())
+ vdc.bfm_type = VD_BFM_SWDP;
+ else
+ vdc.bfm_type = VD_BFM_JTAG;
LOG_DEBUG("bfm_path: %s clk_period %ups", vdc.bfm_path, vdc.bfm_period);
return ERROR_OK;
@@ -1062,9 +1283,24 @@ static struct jtag_interface vdebug_jtag_ops = {
.execute_queue = vdebug_jtag_execute_queue,
};
+static const struct dap_ops vdebug_dap_ops = {
+ .connect = vdebug_dap_connect,
+ .send_sequence = vdebug_dap_send_sequence,
+ .queue_dp_read = vdebug_dap_queue_dp_read,
+ .queue_dp_write = vdebug_dap_queue_dp_write,
+ .queue_ap_read = vdebug_dap_queue_ap_read,
+ .queue_ap_write = vdebug_dap_queue_ap_write,
+ .queue_ap_abort = vdebug_dap_queue_ap_abort,
+ .run = vdebug_dap_run,
+ .sync = NULL, /* optional */
+ .quit = NULL, /* optional */
+};
+
+static const char *const vdebug_transports[] = { "jtag", "dapdirect_swd", NULL };
+
struct adapter_driver vdebug_adapter_driver = {
.name = "vdebug",
- .transports = jtag_only,
+ .transports = vdebug_transports,
.speed = vdebug_jtag_speed,
.khz = vdebug_jtag_khz,
.speed_div = vdebug_jtag_div,
@@ -1073,4 +1309,5 @@ struct adapter_driver vdebug_adapter_driver = {
.quit = vdebug_quit,
.reset = vdebug_reset,
.jtag_ops = &vdebug_jtag_ops,
+ .dap_swd_ops = &vdebug_dap_ops,
};
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c
index 0d60725..ac5b1a2 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c
index bd61049..be2d8c3 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c
index e756817..941680a 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c
index 23a5097..42c8023 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c
index f701bb0..070f68c 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h
index 0ae3c03..caeaa26 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h
index 3698886..8a6e476 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_INTERNAL_H
diff --git a/src/jtag/drivers/versaloon/versaloon.c b/src/jtag/drivers/versaloon/versaloon.c
index 7c2efef..48d3174 100644
--- a/src/jtag/drivers/versaloon/versaloon.c
+++ b/src/jtag/drivers/versaloon/versaloon.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/versaloon.h b/src/jtag/drivers/versaloon/versaloon.h
index e4aafb2..5d7aa19 100644
--- a/src/jtag/drivers/versaloon/versaloon.h
+++ b/src/jtag/drivers/versaloon/versaloon.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H
diff --git a/src/jtag/drivers/versaloon/versaloon_include.h b/src/jtag/drivers/versaloon/versaloon_include.h
index a954b48..5804ad5 100644
--- a/src/jtag/drivers/versaloon/versaloon_include.h
+++ b/src/jtag/drivers/versaloon/versaloon_include.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INCLUDE_H
diff --git a/src/jtag/drivers/versaloon/versaloon_internal.h b/src/jtag/drivers/versaloon/versaloon_internal.h
index 8372970..edeb335 100644
--- a/src/jtag/drivers/versaloon/versaloon_internal.h
+++ b/src/jtag/drivers/versaloon/versaloon_internal.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INTERNAL_H
diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c
index dbbdef4..255ff88 100644
--- a/src/jtag/drivers/vsllink.c
+++ b/src/jtag/drivers/vsllink.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* Versaloon is a programming tool for multiple MCUs.
diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c
index c5249b2..ecba36b 100644
--- a/src/jtag/drivers/xds110.c
+++ b/src/jtag/drivers/xds110.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/xlnx-pcie-xvc.c b/src/jtag/drivers/xlnx-pcie-xvc.c
index c05b9cf..6ad0255 100644
--- a/src/jtag/drivers/xlnx-pcie-xvc.c
+++ b/src/jtag/drivers/xlnx-pcie-xvc.c
@@ -1,5 +1,6 @@
-/* SPDX-License-Identifier: GPL-2.0
- *
+// SPDX-License-Identifier: GPL-2.0-only
+
+/*
* Copyright (c) 2019 Google, LLC.
* Author: Moritz Fischer <moritzf@google.com>
*/
diff --git a/src/jtag/hla/Makefile.am b/src/jtag/hla/Makefile.am
index 6bb2960..4111786 100644
--- a/src/jtag/hla/Makefile.am
+++ b/src/jtag/hla/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libocdhla.la
%C%_libocdhla_la_SOURCES = \
diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c
index 074e3c2..6198b3d 100644
--- a/src/jtag/hla/hla_interface.c
+++ b/src/jtag/hla/hla_interface.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
* *
* Copyright (C) 2012 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h
index 31d055a..fa49658 100644
--- a/src/jtag/hla/hla_interface.h
+++ b/src/jtag/hla/hla_interface.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
* *
* Copyright (C) 2012 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_HLA_HLA_INTERFACE_H
diff --git a/src/jtag/hla/hla_layout.c b/src/jtag/hla/hla_layout.c
index 16b2217..a760f0b 100644
--- a/src/jtag/hla/hla_layout.c
+++ b/src/jtag/hla/hla_layout.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
* *
* Copyright (C) 2012 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/hla/hla_layout.h b/src/jtag/hla/hla_layout.h
index 732fe1e..e13da65 100644
--- a/src/jtag/hla/hla_layout.h
+++ b/src/jtag/hla/hla_layout.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
* *
* Copyright (C) 2012 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_HLA_HLA_LAYOUT_H
diff --git a/src/jtag/hla/hla_tcl.c b/src/jtag/hla/hla_tcl.c
index 6b206d2..3283399 100644
--- a/src/jtag/hla/hla_tcl.c
+++ b/src/jtag/hla/hla_tcl.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
* *
* Copyright (C) 2012 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/hla/hla_tcl.h b/src/jtag/hla/hla_tcl.h
index ac00add..b028e4b 100644
--- a/src/jtag/hla/hla_tcl.h
+++ b/src/jtag/hla/hla_tcl.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
* *
* Copyright (C) 2012 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_HLA_HLA_TCL_H
diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c
index 58dfe4b..91228be 100644
--- a/src/jtag/hla/hla_transport.c
+++ b/src/jtag/hla/hla_transport.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
* *
* Copyright (C) 2012 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/hla/hla_transport.h b/src/jtag/hla/hla_transport.h
index 0e0bea2..965f561 100644
--- a/src/jtag/hla/hla_transport.h
+++ b/src/jtag/hla/hla_transport.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
* *
* Copyright (C) 2012 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_HLA_HLA_TRANSPORT_H
diff --git a/src/jtag/interface.c b/src/jtag/interface.c
index 56bbf6e..bc9ff3e 100644
--- a/src/jtag/interface.c
+++ b/src/jtag/interface.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -11,19 +13,6 @@
* *
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/interface.h b/src/jtag/interface.h
index 58bfd02..a8d9ee4 100644
--- a/src/jtag/interface.h
+++ b/src/jtag/interface.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_INTERFACE_H
diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c
index 9afd69d..67bbb3b 100644
--- a/src/jtag/interfaces.c
+++ b/src/jtag/interfaces.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -13,19 +15,6 @@
* zw@superlucidity.net *
* *
* Copyright (C) 2020, Ampere Computing LLC *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -54,6 +43,9 @@ extern struct adapter_driver ftdi_adapter_driver;
#if BUILD_USB_BLASTER == 1 || BUILD_USB_BLASTER_2 == 1
extern struct adapter_driver usb_blaster_adapter_driver;
#endif
+#if BUILD_ESP_USB_JTAG == 1
+extern struct adapter_driver esp_usb_adapter_driver;
+#endif
#if BUILD_JTAG_VPI == 1
extern struct adapter_driver jtag_vpi_adapter_driver;
#endif
@@ -171,6 +163,9 @@ struct adapter_driver *adapter_drivers[] = {
#if BUILD_USB_BLASTER || BUILD_USB_BLASTER_2 == 1
&usb_blaster_adapter_driver,
#endif
+#if BUILD_ESP_USB_JTAG == 1
+ &esp_usb_adapter_driver,
+#endif
#if BUILD_JTAG_VPI == 1
&jtag_vpi_adapter_driver,
#endif
diff --git a/src/jtag/interfaces.h b/src/jtag/interfaces.h
index ddbd735..6e6c2ce 100644
--- a/src/jtag/interfaces.h
+++ b/src/jtag/interfaces.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -11,19 +13,6 @@
* *
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_INTERFACES_H
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index 4ec2f1e..4f94e99 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007-2010 Øyvind Harboe *
* oyvind.harboe@zylin.com *
-* *
-* This program is free software; you can redistribute it and/or modify *
-* it under the terms of the GNU General Public License as published by *
-* the Free Software Foundation; either version 2 of the License, or *
-* (at your option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, *
-* but WITHOUT ANY WARRANTY; without even the implied warranty of *
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-* GNU General Public License for more details. *
-* *
-* You should have received a copy of the GNU General Public License *
-* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_JTAG_H
@@ -598,6 +587,19 @@ bool jtag_poll_get_enabled(void);
*/
void jtag_poll_set_enabled(bool value);
+/**
+ * Mask (disable) polling and return the current mask status that should be
+ * feed to jtag_poll_unmask() to restore it.
+ * Multiple nested calls to jtag_poll_mask() are allowed, each balanced with
+ * its call to jtag_poll_unmask().
+ */
+bool jtag_poll_mask(void);
+
+/**
+ * Restore saved mask for polling.
+ */
+void jtag_poll_unmask(bool saved);
+
#include <jtag/minidriver.h>
int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h
index 0624c55..a40cffa 100644
--- a/src/jtag/minidriver.h
+++ b/src/jtag/minidriver.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_MINIDRIVER_H
diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl
index ee11626..aeb42ed 100644
--- a/src/jtag/startup.tcl
+++ b/src/jtag/startup.tcl
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
# Defines basic Tcl procs for OpenOCD JTAG module
# Executed during "init". Can be overridden
@@ -120,6 +122,66 @@ proc jtag_ntrst_assert_width args {
#
# FIXME phase these aids out after some releases
#
+lappend _telnet_autocomplete_skip adapter_gpio_helper_with_caller
+# Helper for deprecated driver functions that should call "adapter gpio XXX".
+
+# Call this function as:
+# adapter_gpio_helper_with_caller caller sig_name
+# adapter_gpio_helper_with_caller caller sig_name gpio_num
+# adapter_gpio_helper_with_caller caller sig_name chip_num gpio_num
+proc adapter_gpio_helper_with_caller {caller sig_name args} {
+ echo "DEPRECATED! use 'adapter gpio $sig_name' not '$caller'"
+ switch [llength $args] {
+ 0 {}
+ 1 {eval adapter gpio $sig_name $args}
+ 2 {eval adapter gpio $sig_name [lindex $args 1] -chip [lindex $args 0]}
+ default {return -code 1 -level 1 "$caller: syntax error"}
+ }
+ eval adapter gpio $sig_name
+}
+
+lappend _telnet_autocomplete_skip adapter_gpio_helper
+# Call this function as:
+# adapter_gpio_helper sig_name
+# adapter_gpio_helper sig_name gpio_num
+# adapter_gpio_helper sig_name chip_num gpio_num
+proc adapter_gpio_helper {sig_name args} {
+ set caller [lindex [info level -1] 0]
+ eval adapter_gpio_helper_with_caller {"$caller"} $sig_name $args
+}
+
+lappend _telnet_autocomplete_skip adapter_gpio_jtag_nums_with_caller
+# Helper for deprecated driver functions that implemented jtag_nums
+proc adapter_gpio_jtag_nums_with_caller {caller tck_num tms_num tdi_num tdo_num} {
+ echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not '$caller'"
+ eval adapter gpio tck $tck_num
+ eval adapter gpio tms $tms_num
+ eval adapter gpio tdi $tdi_num
+ eval adapter gpio tdo $tdo_num
+}
+
+lappend _telnet_autocomplete_skip adapter_gpio_jtag_nums
+# Helper for deprecated driver functions that implemented jtag_nums
+proc adapter_gpio_jtag_nums {args} {
+ set caller [lindex [info level -1] 0]
+ eval adapter_gpio_jtag_nums_with_caller {"$caller"} $args
+}
+
+lappend _telnet_autocomplete_skip adapter_gpio_swd_nums_with_caller
+# Helper for deprecated driver functions that implemented swd_nums
+proc adapter_gpio_swd_nums_with_caller {caller swclk_num swdio_num} {
+ echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not '$caller'"
+ eval adapter gpio swclk $swclk_num
+ eval adapter gpio swdio $swdio_num
+}
+
+lappend _telnet_autocomplete_skip adapter_gpio_swd_nums
+# Helper for deprecated driver functions that implemented jtag_nums
+proc adapter_gpio_swd_nums {args} {
+ set caller [lindex [info level -1] 0]
+ eval adapter_gpio_swd_nums_with_caller {"$caller"} $args
+}
+
lappend _telnet_autocomplete_skip jtag_reset
proc jtag_reset args {
echo "DEPRECATED! use 'adapter \[de\]assert' not 'jtag_reset'"
@@ -393,70 +455,140 @@ proc vsllink_usb_interface args {
eval vsllink usb_interface $args
}
+
+lappend _telnet_autocomplete_skip bcm2835_gpio_helper
+proc bcm2835_gpio_helper {sig_name args} {
+ set caller [lindex [info level -1] 0]
+ echo "DEPRECATED! use 'adapter gpio $sig_name' not '$caller'"
+ switch [llength $args] {
+ 0 {}
+ 1 {eval adapter gpio $sig_name $args -chip 0}
+ 2 {eval adapter gpio $sig_name [lindex $args 1] -chip [lindex $args 0]}
+ default {return -code 1 -level 1 "$caller: syntax error"}
+ }
+ eval adapter gpio $sig_name
+}
+
lappend _telnet_autocomplete_skip bcm2835gpio_jtag_nums
-proc bcm2835gpio_jtag_nums args {
- echo "DEPRECATED! use 'bcm2835gpio jtag_nums' not 'bcm2835gpio_jtag_nums'"
- eval bcm2835gpio jtag_nums $args
+proc bcm2835gpio_jtag_nums {tck_num tms_num tdi_num tdo_num} {
+ echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'bcm2835gpio_jtag_nums'"
+ eval adapter gpio tck $tck_num -chip 0
+ eval adapter gpio tms $tms_num -chip 0
+ eval adapter gpio tdi $tdi_num -chip 0
+ eval adapter gpio tdo $tdo_num -chip 0
}
lappend _telnet_autocomplete_skip bcm2835gpio_tck_num
proc bcm2835gpio_tck_num args {
- echo "DEPRECATED! use 'bcm2835gpio tck_num' not 'bcm2835gpio_tck_num'"
- eval bcm2835gpio tck_num $args
+ eval bcm2835_gpio_helper tck $args
}
lappend _telnet_autocomplete_skip bcm2835gpio_tms_num
proc bcm2835gpio_tms_num args {
- echo "DEPRECATED! use 'bcm2835gpio tms_num' not 'bcm2835gpio_tms_num'"
- eval bcm2835gpio tms_num $args
+ eval bcm2835_gpio_helper tms $args
}
lappend _telnet_autocomplete_skip bcm2835gpio_tdo_num
proc bcm2835gpio_tdo_num args {
- echo "DEPRECATED! use 'bcm2835gpio tdo_num' not 'bcm2835gpio_tdo_num'"
- eval bcm2835gpio tdo_num $args
+ eval bcm2835_gpio_helper tdo $args
}
lappend _telnet_autocomplete_skip bcm2835gpio_tdi_num
proc bcm2835gpio_tdi_num args {
- echo "DEPRECATED! use 'bcm2835gpio tdi_num' not 'bcm2835gpio_tdi_num'"
- eval bcm2835gpio tdi_num $args
+ eval bcm2835_gpio_helper tdi $args
}
lappend _telnet_autocomplete_skip bcm2835gpio_swd_nums
-proc bcm2835gpio_swd_nums args {
- echo "DEPRECATED! use 'bcm2835gpio swd_nums' not 'bcm2835gpio_swd_nums'"
- eval bcm2835gpio swd_nums $args
+proc bcm2835gpio_swd_nums {swclk_num swdio_num} {
+ echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'bcm2835gpio_swd_nums'"
+ eval adapter gpio swclk $swclk_num -chip 0
+ eval adapter gpio swdio $swdio_num -chip 0
}
lappend _telnet_autocomplete_skip bcm2835gpio_swclk_num
proc bcm2835gpio_swclk_num args {
- echo "DEPRECATED! use 'bcm2835gpio swclk_num' not 'bcm2835gpio_swclk_num'"
- eval bcm2835gpio swclk_num $args
+ eval bcm2835_gpio_helper swclk $args
}
lappend _telnet_autocomplete_skip bcm2835gpio_swdio_num
proc bcm2835gpio_swdio_num args {
- echo "DEPRECATED! use 'bcm2835gpio swdio_num' not 'bcm2835gpio_swdio_num'"
- eval bcm2835gpio swdio_num $args
+ eval bcm2835_gpio_helper swdio $args
}
lappend _telnet_autocomplete_skip bcm2835gpio_swdio_dir_num
proc bcm2835gpio_swdio_dir_num args {
- echo "DEPRECATED! use 'bcm2835gpio swdio_dir_num' not 'bcm2835gpio_swdio_dir_num'"
- eval bcm2835gpio swdio_dir_num $args
+ eval bcm2835_gpio_helper swdio_dir $args
}
lappend _telnet_autocomplete_skip bcm2835gpio_srst_num
proc bcm2835gpio_srst_num args {
- echo "DEPRECATED! use 'bcm2835gpio srst_num' not 'bcm2835gpio_srst_num'"
- eval bcm2835gpio srst_num $args
+ eval bcm2835_gpio_helper srst $args
}
lappend _telnet_autocomplete_skip bcm2835gpio_trst_num
proc bcm2835gpio_trst_num args {
- echo "DEPRECATED! use 'bcm2835gpio trst_num' not 'bcm2835gpio_trst_num'"
- eval bcm2835gpio trst_num $args
+ eval bcm2835_gpio_helper trst $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio jtag_nums"
+proc "bcm2835gpio jtag_nums" {tck_num tms_num tdi_num tdo_num} {
+ echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'bcm2835gpio jtag_nums'"
+ eval adapter gpio tck $tck_num -chip 0
+ eval adapter gpio tms $tms_num -chip 0
+ eval adapter gpio tdi $tdi_num -chip 0
+ eval adapter gpio tdo $tdo_num -chip 0
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio tck_num"
+proc "bcm2835gpio tck_num" args {
+ eval bcm2835_gpio_helper tck $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio tms_num"
+proc "bcm2835gpio tms_num" args {
+ eval bcm2835_gpio_helper tms $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio tdo_num"
+proc "bcm2835gpio tdo_num" args {
+ eval bcm2835_gpio_helper tdo $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio tdi_num"
+proc "bcm2835gpio tdi_num" args {
+ eval bcm2835_gpio_helper tdi $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio swd_nums"
+proc "bcm2835gpio swd_nums" {swclk_num swdio_num} {
+ echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'bcm2835gpio swd_nums'"
+ eval adapter gpio swclk $swclk_num -chip 0
+ eval adapter gpio swdio $swdio_num -chip 0
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio swclk_num"
+proc "bcm2835gpio swclk_num" args {
+ eval bcm2835_gpio_helper swclk $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio swdio_num"
+proc "bcm2835gpio swdio_num" args {
+ eval bcm2835_gpio_helper swdio $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio swdio_dir_num"
+proc "bcm2835gpio swdio_dir_num" args {
+ eval bcm2835_gpio_helper swdio_dir $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio srst_num"
+proc "bcm2835gpio srst_num" args {
+ eval bcm2835_gpio_helper srst $args
+}
+
+lappend _telnet_autocomplete_skip "bcm2835gpio trst_num"
+proc "bcm2835gpio trst_num" args {
+ eval bcm2835_gpio_helper trst $args
}
lappend _telnet_autocomplete_skip bcm2835gpio_speed_coeffs
@@ -473,74 +605,72 @@ proc bcm2835gpio_peripheral_base args {
lappend _telnet_autocomplete_skip linuxgpiod_jtag_nums
proc linuxgpiod_jtag_nums args {
- echo "DEPRECATED! use 'linuxgpiod jtag_nums' not 'linuxgpiod_jtag_nums'"
- eval linuxgpiod jtag_nums $args
+ eval adapter_gpio_jtag_nums $args
}
lappend _telnet_autocomplete_skip linuxgpiod_tck_num
proc linuxgpiod_tck_num args {
- echo "DEPRECATED! use 'linuxgpiod tck_num' not 'linuxgpiod_tck_num'"
- eval linuxgpiod tck_num $args
+ eval adapter_gpio_helper tck $args
}
lappend _telnet_autocomplete_skip linuxgpiod_tms_num
proc linuxgpiod_tms_num args {
- echo "DEPRECATED! use 'linuxgpiod tms_num' not 'linuxgpiod_tms_num'"
- eval linuxgpiod tms_num $args
+ eval adapter_gpio_helper tms $args
}
lappend _telnet_autocomplete_skip linuxgpiod_tdo_num
proc linuxgpiod_tdo_num args {
- echo "DEPRECATED! use 'linuxgpiod tdo_num' not 'linuxgpiod_tdo_num'"
- eval linuxgpiod tdo_num $args
+ eval adapter_gpio_helper tdo $args
}
lappend _telnet_autocomplete_skip linuxgpiod_tdi_num
proc linuxgpiod_tdi_num args {
- echo "DEPRECATED! use 'linuxgpiod tdi_num' not 'linuxgpiod_tdi_num'"
- eval linuxgpiod tdi_num $args
+ eval adapter_gpio_helper tdi $args
}
lappend _telnet_autocomplete_skip linuxgpiod_srst_num
proc linuxgpiod_srst_num args {
- echo "DEPRECATED! use 'linuxgpiod srst_num' not 'linuxgpiod_srst_num'"
- eval linuxgpiod srst_num $args
+ eval adapter_gpio_helper srst $args
}
lappend _telnet_autocomplete_skip linuxgpiod_trst_num
proc linuxgpiod_trst_num args {
- echo "DEPRECATED! use 'linuxgpiod trst_num' not 'linuxgpiod_trst_num'"
- eval linuxgpiod trst_num $args
+ eval adapter_gpio_helper trst $args
}
lappend _telnet_autocomplete_skip linuxgpiod_swd_nums
proc linuxgpiod_swd_nums args {
- echo "DEPRECATED! use 'linuxgpiod swd_nums' not 'linuxgpiod_swd_nums'"
- eval linuxgpiod swd_nums $args
+ eval adapter_gpio_swd_nums $args
}
lappend _telnet_autocomplete_skip linuxgpiod_swclk_num
proc linuxgpiod_swclk_num args {
- echo "DEPRECATED! use 'linuxgpiod swclk_num' not 'linuxgpiod_swclk_num'"
- eval linuxgpiod swclk_num $args
+ eval adapter_gpio_helper swclk $args
}
lappend _telnet_autocomplete_skip linuxgpiod_swdio_num
proc linuxgpiod_swdio_num args {
- echo "DEPRECATED! use 'linuxgpiod swdio_num' not 'linuxgpiod_swdio_num'"
- eval linuxgpiod swdio_num $args
+ eval adapter_gpio_helper swdio $args
}
lappend _telnet_autocomplete_skip linuxgpiod_led_num
proc linuxgpiod_led_num args {
- echo "DEPRECATED! use 'linuxgpiod led_num' not 'linuxgpiod_led_num'"
- eval linuxgpiod led_num $args
+ eval adapter_gpio_helper led $args
}
lappend _telnet_autocomplete_skip linuxgpiod_gpiochip
proc linuxgpiod_gpiochip args {
- echo "DEPRECATED! use 'linuxgpiod gpiochip' not 'linuxgpiod_gpiochip'"
- eval linuxgpiod gpiochip $args
+ echo "DEPRECATED! use 'adapter <signal_name> -chip' not 'linuxgpiod_gpiochip'"
+ switch [llength $args] {
+ 0 { }
+ 1 {
+ foreach sig_name {tck tms tdi tdo trst srst swclk swdio swdio_dir led} {
+ eval adapter gpio $sig_name -chip $args
+ }
+ }
+ default {return -code 1 -level 1 "linuxgpiod_gpiochip: syntax error"}
+ }
+ eval adapter gpio
}
lappend _telnet_autocomplete_skip sysfsgpio_jtag_nums
@@ -801,4 +931,187 @@ proc "xds110 serial" {args} {
eval adapter serial $args
}
+lappend _telnet_autocomplete_skip linuxgpiod
+# linuxgpiod command completely removed, this is required for the sub-commands to work
+proc linuxgpiod {subcommand args} {
+ eval {"linuxgpiod $subcommand"} $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod tck_num"
+proc "linuxgpiod tck_num" {args} {
+ eval adapter_gpio_helper tck $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod tms_num"
+proc "linuxgpiod tms_num" {args} {
+ eval adapter_gpio_helper tms $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod tdi_num"
+proc "linuxgpiod tdi_num" {args} {
+ eval adapter_gpio_helper tdi $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod tdo_num"
+proc "linuxgpiod tdo_num" {args} {
+ eval adapter_gpio_helper tdo $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod trst_num"
+proc "linuxgpiod trst_num" {args} {
+ eval adapter_gpio_helper trst $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod srst_num"
+proc "linuxgpiod srst_num" {args} {
+ eval adapter_gpio_helper srst $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod swclk_num"
+proc "linuxgpiod swclk_num" {args} {
+ eval adapter_gpio_helper swclk $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod swdio_num"
+proc "linuxgpiod swdio_num" {args} {
+ eval adapter_gpio_helper swdio $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod swdio_dir_num"
+proc "linuxgpiod swdio_dir_num" {args} {
+ eval adapter_gpio_helper swdio_dir $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod led_num"
+proc "linuxgpiod led_num" {args} {
+ eval adapter_gpio_helper led $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod gpiochip"
+proc "linuxgpiod gpiochip" {num} {
+ echo "DEPRECATED! use 'adapter <signal_name> -chip' not 'linuxgpiod gpiochip'"
+ foreach sig_name {tck tms tdi tdo trst srst swclk swdio swdio_dir led} {
+ eval adapter gpio $sig_name -chip $num
+ }
+ eval adapter gpio
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod jtag_nums"
+proc "linuxgpiod jtag_nums" {tck_num tms_num tdi_num tdo_num} {
+ echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'linuxgpiod jtag_nums'"
+ eval adapter gpio tck $tck_num
+ eval adapter gpio tms $tms_num
+ eval adapter gpio tdi $tdi_num
+ eval adapter gpio tdo $tdo_num
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod swd_nums"
+proc "linuxgpiod swd_nums" {swclk swdio} {
+ echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'linuxgpiod jtag_nums'"
+ eval adapter gpio swclk $swclk
+ eval adapter gpio swdio $swdio
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio jtag_nums"
+proc "am335xgpio jtag_nums" {tck_num tms_num tdi_num tdo_num} {
+ echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'am335xgpio jtag_nums'"
+ eval adapter gpio tck [expr {$tck_num % 32}] -chip [expr {$tck_num / 32}]
+ eval adapter gpio tms [expr {$tms_num % 32}] -chip [expr {$tms_num / 32}]
+ eval adapter gpio tdi [expr {$tdi_num % 32}] -chip [expr {$tdi_num / 32}]
+ eval adapter gpio tdo [expr {$tdo_num % 32}] -chip [expr {$tdo_num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio tck_num"
+proc "am335xgpio tck_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio tck' not 'am335xgpio tck_num'"
+ eval adapter gpio tck [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio tms_num"
+proc "am335xgpio tms_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio tms' not 'am335xgpio tms_num'"
+ eval adapter gpio tms [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio tdi_num"
+proc "am335xgpio tdi_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio tdi' not 'am335xgpio tdi_num'"
+ eval adapter gpio tdi [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio tdo_num"
+proc "am335xgpio tdo_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio tdo' not 'am335xgpio tdo_num'"
+ eval adapter gpio tdo [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio swd_nums"
+proc "am335xgpio swd_nums" {swclk swdio} {
+ echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'am335xgpio jtag_nums'"
+ eval adapter gpio swclk [expr {$swclk % 32}] -chip [expr {$swclk / 32}]
+ eval adapter gpio swdio [expr {$swdio % 32}] -chip [expr {$swdio / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio swclk_num"
+proc "am335xgpio swclk_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio swclk' not 'am335xgpio swclk_num'"
+ eval adapter gpio swclk [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio swdio_num"
+proc "am335xgpio swdio_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio swdio' not 'am335xgpio swdio_num'"
+ eval adapter gpio swdio [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio swdio_dir_num"
+proc "am335xgpio swdio_dir_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio swdio_dir' not 'am335xgpio swdio_dir_num'"
+ eval adapter gpio swdio_dir [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio swdio_dir_output_state"
+proc "am335xgpio swdio_dir_output_state" {state} {
+ echo "DEPRECATED! use 'adapter gpio swdio_dir -active-high' or 'adapter gpio swdio_dir -active-low', not 'am335xgpio swdio_dir_output_state'"
+ switch $state {
+ "high"
+ {eval adapter gpio swdio_dir -active-high}
+ "low"
+ {eval adapter gpio swdio_dir -active-low}
+ default
+ {return -code 1 -level 1 "am335xgpio swdio_dir_output_state: syntax error"}
+ }
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio srst_num"
+proc "am335xgpio srst_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio srst' not 'am335xgpio srst_num'"
+ eval adapter gpio srst [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio trst_num"
+proc "am335xgpio trst_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio trst' not 'am335xgpio trst_num'"
+ eval adapter gpio trst [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio led_num"
+proc "am335xgpio led_num" {num} {
+ echo "DEPRECATED! use 'adapter gpio led' not 'am335xgpio led_num'"
+ eval adapter gpio led [expr {$num % 32}] -chip [expr {$num / 32}]
+}
+
+lappend _telnet_autocomplete_skip "am335xgpio led_on_state"
+proc "am335xgpio led_on_state" {state} {
+ echo "DEPRECATED! use 'adapter gpio led -active-high' or 'adapter gpio led -active-low', not 'am335xgpio led_on_state'"
+ switch $state {
+ "high"
+ {eval adapter gpio led -active-high}
+ "low"
+ {eval adapter gpio led -active-low}
+ default
+ {return -code 1 -level 1 "am335xgpio led_on_state: syntax error"}
+ }
+}
+
# END MIGRATION AIDS
diff --git a/src/jtag/swd.h b/src/jtag/swd.h
index 8a436d0..5f626c1 100644
--- a/src/jtag/swd.h
+++ b/src/jtag/swd.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009-2010 by David Brownell *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_SWD_H
diff --git a/src/jtag/swim.c b/src/jtag/swim.c
index 936268b..de3e106 100644
--- a/src/jtag/swim.c
+++ b/src/jtag/swim.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2020 by Antonio Borneo <borneo.antonio@gmail.com
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index e6e976d..b1815b7 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -11,19 +13,6 @@
* *
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/tcl.h b/src/jtag/tcl.h
index 932b47a..d67c085 100644
--- a/src/jtag/tcl.h
+++ b/src/jtag/tcl.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -11,19 +13,6 @@
* *
* Copyright (C) 2009 Zachary T Welch *
* zw@superlucidity.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_TCL_H
diff --git a/src/main.c b/src/main.c
index a437b6b..a36e6b5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/openocd.c b/src/openocd.c
index fdc4a87..bef084f 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 Richard Missenden *
* richard.missenden@googlemail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -130,6 +119,8 @@ COMMAND_HANDLER(handle_init_command)
initialized = 1;
+ bool save_poll_mask = jtag_poll_mask();
+
retval = command_run_line(CMD_CTX, "target init");
if (retval != ERROR_OK)
return ERROR_FAIL;
@@ -177,6 +168,8 @@ COMMAND_HANDLER(handle_init_command)
if (command_run_line(CMD_CTX, "tpiu init") != ERROR_OK)
return ERROR_FAIL;
+ jtag_poll_unmask(save_poll_mask);
+
/* initialize telnet subsystem */
gdb_target_add_all(all_targets);
diff --git a/src/openocd.h b/src/openocd.h
index 543ac3c..1c2a633 100644
--- a/src/openocd.h
+++ b/src/openocd.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_OPENOCD_H
diff --git a/src/pld/Makefile.am b/src/pld/Makefile.am
index 7f3a554..14786af 100644
--- a/src/pld/Makefile.am
+++ b/src/pld/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libpld.la
%C%_libpld_la_SOURCES = \
%D%/pld.c \
diff --git a/src/pld/pld.c b/src/pld/pld.c
index fe21f6c..e2e0ef4 100644
--- a/src/pld/pld.c
+++ b/src/pld/pld.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/pld/pld.h b/src/pld/pld.h
index 3178fd4..a7cd20f 100644
--- a/src/pld/pld.h
+++ b/src/pld/pld.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_PLD_PLD_H
diff --git a/src/pld/virtex2.c b/src/pld/virtex2.c
index a2de8cc..771af99 100644
--- a/src/pld/virtex2.c
+++ b/src/pld/virtex2.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/pld/virtex2.h b/src/pld/virtex2.h
index d6d922e..05558f7 100644
--- a/src/pld/virtex2.h
+++ b/src/pld/virtex2.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_PLD_VIRTEX2_H
diff --git a/src/pld/xilinx_bit.c b/src/pld/xilinx_bit.c
index fe3faef..25deb80 100644
--- a/src/pld/xilinx_bit.c
+++ b/src/pld/xilinx_bit.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/pld/xilinx_bit.h b/src/pld/xilinx_bit.h
index 625a9d3..e30ed23 100644
--- a/src/pld/xilinx_bit.h
+++ b/src/pld/xilinx_bit.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_PLD_XILINX_BIT_H
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
index 2e468c7..5038b09 100644
--- a/src/rtos/FreeRTOS.c
+++ b/src/rtos/FreeRTOS.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -83,7 +72,8 @@ static int cortex_m_stacking(struct rtos *rtos, const struct rtos_register_stack
int cm4_fpu_enabled = 0;
struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);
if (is_armv7m(armv7m_target)) {
- if (armv7m_target->fp_feature == FPV4_SP) {
+ if ((armv7m_target->fp_feature == FPV4_SP) || (armv7m_target->fp_feature == FPV5_SP) ||
+ (armv7m_target->fp_feature == FPV5_DP)) {
/* Found ARM v7m target which includes a FPU */
uint32_t cpacr;
@@ -280,6 +270,7 @@ enum freertos_symbol_values {
FREERTOS_VAL_X_SUSPENDED_TASK_LIST = 8,
FREERTOS_VAL_UX_CURRENT_NUMBER_OF_TASKS = 9,
FREERTOS_VAL_UX_TOP_USED_PRIORITY = 10,
+ FREERTOS_VAL_X_SCHEDULER_RUNNING = 11,
};
struct symbols {
@@ -299,6 +290,7 @@ static const struct symbols freertos_symbol_list[] = {
{ "xSuspendedTaskList", true }, /* Only if INCLUDE_vTaskSuspend */
{ "uxCurrentNumberOfTasks", false },
{ "uxTopUsedPriority", true }, /* Unavailable since v7.5.3 */
+ { "xSchedulerRunning", false },
{ NULL, false }
};
@@ -529,7 +521,20 @@ static int freertos_update_threads(struct rtos *rtos)
rtos->symbols[FREERTOS_VAL_PX_CURRENT_TCB].address,
pxCurrentTCB);
- if ((thread_list_size == 0) || (pxCurrentTCB == 0)) {
+ /* read scheduler running */
+ uint32_t scheduler_running;
+ retval = target_read_u32(rtos->target,
+ rtos->symbols[FREERTOS_VAL_X_SCHEDULER_RUNNING].address,
+ &scheduler_running);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Error reading FreeRTOS scheduler state");
+ return retval;
+ }
+ LOG_DEBUG("FreeRTOS: Read xSchedulerRunning at 0x%" PRIx64 ", value 0x%" PRIx32,
+ rtos->symbols[FREERTOS_VAL_X_SCHEDULER_RUNNING].address,
+ scheduler_running);
+
+ if ((thread_list_size == 0) || (rtos->current_thread == 0) || (scheduler_running != 1)) {
/* 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 */
diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am
index f09ac21..f00d719 100644
--- a/src/rtos/Makefile.am
+++ b/src/rtos/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/librtos.la
%C%_librtos_la_SOURCES = \
%D%/rtos.c \
diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c
index 4161e63..7b76fb6 100644
--- a/src/rtos/ThreadX.c
+++ b/src/rtos/ThreadX.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/chibios.c b/src/rtos/chibios.c
index ef1f34d..8319cc8 100644
--- a/src/rtos/chibios.c
+++ b/src/rtos/chibios.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2012 by Matthias Blaicher *
* Matthias Blaicher - matthias@blaicher.com *
* *
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/chromium-ec.c b/src/rtos/chromium-ec.c
index 95a228d..a95969e 100644
--- a/src/rtos/chromium-ec.c
+++ b/src/rtos/chromium-ec.c
@@ -1,6 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
/*
- * SPDX-License-Identifier: GPL-2.0
- *
* Copyright (c) 2018 National Instruments Corp
* Author: Moritz Fischer <moritz.fischer@ettus.com>
*
diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c
index a81d7b9..3f813ac 100644
--- a/src/rtos/eCos.c
+++ b/src/rtos/eCos.c
@@ -1,17 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c
index d70ae37..c1b5723 100644
--- a/src/rtos/embKernel.c
+++ b/src/rtos/embKernel.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c
index 28f9727..5e60c61 100644
--- a/src/rtos/hwthread.c
+++ b/src/rtos/hwthread.c
@@ -1,18 +1,4 @@
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
+// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/rtos/linux.c b/src/rtos/linux.c
index d147c1c..f9edabc 100644
--- a/src/rtos/linux.c
+++ b/src/rtos/linux.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by STEricsson *
* Heythem Bouhaja heythem.bouhaja@stericsson.com : creation *
* Michel JAOUEN michel.jaouen@stericsson.com : adaptation to rtos *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/linux_header.h b/src/rtos/linux_header.h
index a2b408e..7919964 100644
--- a/src/rtos/linux_header.h
+++ b/src/rtos/linux_header.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
#ifndef OPENOCD_RTOS_LINUX_HEADER_H
#define OPENOCD_RTOS_LINUX_HEADER_H
diff --git a/src/rtos/mqx.c b/src/rtos/mqx.c
index 754470e..8d483ed 100644
--- a/src/rtos/mqx.c
+++ b/src/rtos/mqx.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2014 by Marian Cingel *
* cingel.marian@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c
index f0b3048..87b28c6 100644
--- a/src/rtos/nuttx.c
+++ b/src/rtos/nuttx.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright 2016,2017 Sony Video & Sound Products Inc. *
* Masatoshi Tateishi - Masatoshi.Tateishi@jp.sony.com *
* Masayuki Ishikawa - Masayuki.Ishikawa@jp.sony.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -114,7 +103,7 @@ static const struct stack_register_offset nuttx_stack_offsets_cortex_m[] = {
{ ARMV7M_R13, 0, 32 }, /* sp */
{ ARMV7M_R14, 0x3c, 32 }, /* lr */
{ ARMV7M_PC, 0x40, 32 }, /* pc */
- { ARMV7M_xPSR, 0x44, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x44, 32 }, /* xPSR */
};
@@ -142,7 +131,7 @@ static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = {
{ ARMV7M_R13, 0, 32 }, /* sp */
{ ARMV7M_R14, 0x80, 32 }, /* lr */
{ ARMV7M_PC, 0x84, 32 }, /* pc */
- { ARMV7M_xPSR, 0x88, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x88, 32 }, /* xPSR */
};
static const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = {
diff --git a/src/rtos/nuttx_header.h b/src/rtos/nuttx_header.h
index 00b0484..3436df1 100644
--- a/src/rtos/nuttx_header.h
+++ b/src/rtos/nuttx_header.h
@@ -1,20 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright 2016,2017 Sony Video & Sound Products Inc. *
* Masatoshi Tateishi - Masatoshi.Tateishi@jp.sony.com *
* Masayuki Ishikawa - Masayuki.Ishikawa@jp.sony.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_RTOS_NUTTX_HEADER_H
diff --git a/src/rtos/riot.c b/src/rtos/riot.c
index 8a38742..be5452e 100644
--- a/src/rtos/riot.c
+++ b/src/rtos/riot.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by Daniel Krebs *
* Daniel Krebs - github@daniel-krebs.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index b82ecb3..c9da33b 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -148,6 +137,9 @@ int rtos_create(struct jim_getopt_info *goi, struct target *target)
if (e != JIM_OK)
return e;
+ if (strcmp(cp, "none") == 0)
+ return JIM_OK;
+
if (strcmp(cp, "auto") == 0) {
/* Auto detect tries to look up all symbols for each RTOS,
* and runs the RTOS driver's _detect() function when GDB
@@ -167,7 +159,7 @@ int rtos_create(struct jim_getopt_info *goi, struct target *target)
res = Jim_GetResult(goi->interp);
for (x = 0; rtos_types[x]; x++)
Jim_AppendStrings(goi->interp, res, rtos_types[x]->name, ", ", NULL);
- Jim_AppendStrings(goi->interp, res, " or auto", NULL);
+ Jim_AppendStrings(goi->interp, res, ", auto or none", NULL);
return JIM_ERR;
}
@@ -186,35 +178,32 @@ int gdb_thread_packet(struct connection *connection, char const *packet, int pac
return target->rtos->gdb_thread_packet(connection, packet, packet_size);
}
-static struct symbol_table_elem *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr)
+static struct symbol_table_elem *find_symbol(const struct rtos *os, const char *symbol)
{
struct symbol_table_elem *s;
- if (!os->symbols)
- os->type->get_symbol_list_to_lookup(&os->symbols);
-
- if (!cur_symbol[0])
- return &os->symbols[0];
-
for (s = os->symbols; s->symbol_name; s++)
- if (!strcmp(s->symbol_name, cur_symbol)) {
- s->address = cur_addr;
- s++;
+ if (!strcmp(s->symbol_name, symbol))
return s;
- }
return NULL;
}
-/* searches for 'symbol' in the lookup table for 'os' and returns TRUE,
- * if 'symbol' is not declared optional */
-static bool is_symbol_mandatory(const struct rtos *os, const char *symbol)
+static struct symbol_table_elem *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr)
{
- for (struct symbol_table_elem *s = os->symbols; s->symbol_name; ++s) {
- if (!strcmp(s->symbol_name, symbol))
- return !s->optional;
- }
- return false;
+ if (!os->symbols)
+ os->type->get_symbol_list_to_lookup(&os->symbols);
+
+ if (!cur_symbol[0])
+ return &os->symbols[0];
+
+ struct symbol_table_elem *s = find_symbol(os, cur_symbol);
+ if (!s)
+ return NULL;
+
+ s->address = cur_addr;
+ s++;
+ return s;
}
/* rtos_qsymbol() processes and replies to all qSymbol packets from GDB.
@@ -234,6 +223,12 @@ static bool is_symbol_mandatory(const struct rtos *os, const char *symbol)
* specified explicitly, then no further symbol lookup is done. When
* auto-detecting, the RTOS driver _detect() function must return success.
*
+ * The symbol is tried twice to handle the -flto case with gcc. The first
+ * attempt uses the symbol as-is, and the second attempt tries the symbol
+ * with ".lto_priv.0" appended to it. We only consider the first static
+ * symbol here from the -flto case. (Each subsequent static symbol with
+ * the same name is exported as .lto_priv.1, .lto_priv.2, etc.)
+ *
* rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise.
*/
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
@@ -242,7 +237,7 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s
uint64_t addr = 0;
size_t reply_len;
char reply[GDB_BUFFER_SIZE + 1], cur_sym[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for null-termination */
- struct symbol_table_elem *next_sym;
+ struct symbol_table_elem *next_sym = NULL;
struct target *target = get_target_from_connection(connection);
struct rtos *os = target->rtos;
@@ -255,33 +250,60 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s
size_t len = unhexify((uint8_t *)cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1));
cur_sym[len] = 0;
+ const char no_suffix[] = "";
+ const char lto_suffix[] = ".lto_priv.0";
+ const size_t lto_suffix_len = strlen(lto_suffix);
+
+ const char *cur_suffix;
+ const char *next_suffix;
+
+ /* Detect what suffix was used during the previous symbol lookup attempt, and
+ * speculatively determine the next suffix (only used for the unknown address case) */
+ if (len > lto_suffix_len && !strcmp(cur_sym + len - lto_suffix_len, lto_suffix)) {
+ /* Trim the suffix from cur_sym for comparison purposes below */
+ cur_sym[len - lto_suffix_len] = '\0';
+ cur_suffix = lto_suffix;
+ next_suffix = NULL;
+ } else {
+ cur_suffix = no_suffix;
+ next_suffix = lto_suffix;
+ }
+
if ((strcmp(packet, "qSymbol::") != 0) && /* GDB is not offering symbol lookup for the first time */
- (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr)) && /* GDB did not find an address for a symbol */
- is_symbol_mandatory(os, cur_sym)) { /* the symbol is mandatory for this RTOS */
+ (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr))) { /* GDB did not find an address for a symbol */
/* GDB could not find an address for the previous symbol */
- if (!target->rtos_auto_detect) {
- LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym);
- goto done;
- } else {
- /* Autodetecting RTOS - try next RTOS */
- if (!rtos_try_next(target)) {
- LOG_WARNING("No RTOS could be auto-detected!");
+ struct symbol_table_elem *sym = find_symbol(os, cur_sym);
+
+ if (next_suffix) {
+ next_sym = sym;
+ } else if (sym && !sym->optional) { /* the symbol is mandatory for this RTOS */
+ if (!target->rtos_auto_detect) {
+ LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym);
goto done;
- }
+ } else {
+ /* Autodetecting RTOS - try next RTOS */
+ if (!rtos_try_next(target)) {
+ LOG_WARNING("No RTOS could be auto-detected!");
+ goto done;
+ }
- /* Next RTOS selected - invalidate current symbol */
- cur_sym[0] = '\x00';
+ /* Next RTOS selected - invalidate current symbol */
+ cur_sym[0] = '\x00';
+ }
}
}
- LOG_DEBUG("RTOS: Address of symbol '%s' is 0x%" PRIx64, cur_sym, addr);
+ LOG_DEBUG("RTOS: Address of symbol '%s%s' is 0x%" PRIx64, cur_sym, cur_suffix, addr);
- next_sym = next_symbol(os, cur_sym, addr);
+ if (!next_sym) {
+ next_sym = next_symbol(os, cur_sym, addr);
+ next_suffix = no_suffix;
+ }
/* Should never happen unless the debugger misbehaves */
if (!next_sym) {
- LOG_WARNING("RTOS: Debugger sent us qSymbol with '%s' that we did not ask for", cur_sym);
+ LOG_WARNING("RTOS: Debugger sent us qSymbol with '%s%s' that we did not ask for", cur_sym, cur_suffix);
goto done;
}
@@ -303,17 +325,26 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s
}
}
- if (8 + (strlen(next_sym->symbol_name) * 2) + 1 > sizeof(reply)) {
- LOG_ERROR("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym->symbol_name);
+ assert(next_suffix);
+
+ reply_len = 8; /* snprintf(..., "qSymbol:") */
+ reply_len += 2 * strlen(next_sym->symbol_name); /* hexify(..., next_sym->symbol_name, ...) */
+ reply_len += 2 * strlen(next_suffix); /* hexify(..., next_suffix, ...) */
+ reply_len += 1; /* Terminating NUL */
+ if (reply_len > sizeof(reply)) {
+ LOG_ERROR("ERROR: RTOS symbol '%s%s' name is too long for GDB!", next_sym->symbol_name, next_suffix);
goto done;
}
- LOG_DEBUG("RTOS: Requesting symbol lookup of '%s' from the debugger", next_sym->symbol_name);
+ LOG_DEBUG("RTOS: Requesting symbol lookup of '%s%s' from the debugger", next_sym->symbol_name, next_suffix);
reply_len = snprintf(reply, sizeof(reply), "qSymbol:");
reply_len += hexify(reply + reply_len,
(const uint8_t *)next_sym->symbol_name, strlen(next_sym->symbol_name),
sizeof(reply) - reply_len);
+ reply_len += hexify(reply + reply_len,
+ (const uint8_t *)next_suffix, strlen(next_suffix),
+ sizeof(reply) - reply_len);
done:
gdb_put_packet(connection, reply, reply_len);
diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h
index 745bea7..6695915 100644
--- a/src/rtos/rtos.h
+++ b/src/rtos/rtos.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_RTOS_RTOS_H
diff --git a/src/rtos/rtos_chibios_stackings.c b/src/rtos/rtos_chibios_stackings.c
index 77bcb86..e2fe0a2 100644
--- a/src/rtos/rtos_chibios_stackings.c
+++ b/src/rtos/rtos_chibios_stackings.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2012 by Matthias Blaicher *
* Matthias Blaicher - matthias@blaicher.com *
* *
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -43,7 +32,7 @@ static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets[ARM
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, -1, 32 }, /* lr */
{ ARMV7M_PC, 0x20, 32 }, /* pc */
- { ARMV7M_xPSR, -1, 32 }, /* xPSR */
+ { ARMV7M_XPSR, -1, 32 }, /* xPSR */
};
const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking = {
@@ -70,7 +59,7 @@ static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets_w_f
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, -1, 32 }, /* lr */
{ ARMV7M_PC, 0x60, 32 }, /* pc */
- { ARMV7M_xPSR, -1, 32 }, /* xPSR */
+ { ARMV7M_XPSR, -1, 32 }, /* xPSR */
};
const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu = {
diff --git a/src/rtos/rtos_chibios_stackings.h b/src/rtos/rtos_chibios_stackings.h
index 130aaa1..23ad44a 100644
--- a/src/rtos/rtos_chibios_stackings.h
+++ b/src/rtos/rtos_chibios_stackings.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H
diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c
index 4745470..0f54e86 100644
--- a/src/rtos/rtos_ecos_stackings.c
+++ b/src/rtos/rtos_ecos_stackings.c
@@ -1,18 +1,4 @@
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
+// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -39,7 +25,7 @@ static const struct stack_register_offset rtos_ecos_cortex_m3_stack_offsets[ARMV
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, -1, 32 }, /* lr */
{ ARMV7M_PC, 0x40, 32 }, /* pc */
- { ARMV7M_xPSR, -1, 32 }, /* xPSR */
+ { ARMV7M_XPSR, -1, 32 }, /* xPSR */
};
const struct rtos_register_stacking rtos_ecos_cortex_m3_stacking = {
diff --git a/src/rtos/rtos_ecos_stackings.h b/src/rtos/rtos_ecos_stackings.h
index d66d05f..0375e2d 100644
--- a/src/rtos/rtos_ecos_stackings.h
+++ b/src/rtos/rtos_ecos_stackings.h
@@ -1,18 +1,4 @@
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
+/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H
#define OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H
diff --git a/src/rtos/rtos_embkernel_stackings.c b/src/rtos/rtos_embkernel_stackings.c
index df1fc51..809b622 100644
--- a/src/rtos/rtos_embkernel_stackings.c
+++ b/src/rtos/rtos_embkernel_stackings.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -41,7 +30,7 @@ static const struct stack_register_offset rtos_embkernel_cortex_m_stack_offsets[
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, 0x38, 32 }, /* lr */
{ ARMV7M_PC, 0x3c, 32 }, /* pc */
- { ARMV7M_xPSR, 0x40, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x40, 32 }, /* xPSR */
};
const struct rtos_register_stacking rtos_embkernel_cortex_m_stacking = {
diff --git a/src/rtos/rtos_embkernel_stackings.h b/src/rtos/rtos_embkernel_stackings.h
index 7850beb..972bce6 100644
--- a/src/rtos/rtos_embkernel_stackings.h
+++ b/src/rtos/rtos_embkernel_stackings.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H
diff --git a/src/rtos/rtos_mqx_stackings.c b/src/rtos/rtos_mqx_stackings.c
index f99190e..8c8fd20 100644
--- a/src/rtos/rtos_mqx_stackings.c
+++ b/src/rtos/rtos_mqx_stackings.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2014 by Marian Cingel *
* cingel.marian@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -67,7 +56,7 @@ static const struct stack_register_offset rtos_mqx_arm_v7m_stack_offsets[ARMV7M_
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, 0x28, 32 }, /* lr */
{ ARMV7M_PC, 0x44, 32 }, /* pc */
- { ARMV7M_xPSR, 0x48, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x48, 32 }, /* xPSR */
};
const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking = {
diff --git a/src/rtos/rtos_mqx_stackings.h b/src/rtos/rtos_mqx_stackings.h
index 6ebd287..f86c05a 100644
--- a/src/rtos/rtos_mqx_stackings.h
+++ b/src/rtos/rtos_mqx_stackings.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2014 by Marian Cingel *
* cingel.marian@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_RTOS_RTOS_MQX_STACKINGS_H
diff --git a/src/rtos/rtos_riot_stackings.c b/src/rtos/rtos_riot_stackings.c
index 84e1f7f..e717e8c 100644
--- a/src/rtos/rtos_riot_stackings.c
+++ b/src/rtos/rtos_riot_stackings.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by Daniel Krebs *
* Daniel Krebs - github@daniel-krebs.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -54,7 +43,7 @@ static const struct stack_register_offset rtos_riot_cortex_m0_stack_offsets[ARMV
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, 0x38, 32 }, /* lr */
{ ARMV7M_PC, 0x3c, 32 }, /* pc */
- { ARMV7M_xPSR, 0x40, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x40, 32 }, /* xPSR */
};
const struct rtos_register_stacking rtos_riot_cortex_m0_stacking = {
@@ -83,7 +72,7 @@ static const struct stack_register_offset rtos_riot_cortex_m34_stack_offsets[ARM
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, 0x38, 32 }, /* lr */
{ ARMV7M_PC, 0x3c, 32 }, /* pc */
- { ARMV7M_xPSR, 0x40, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x40, 32 }, /* xPSR */
};
const struct rtos_register_stacking rtos_riot_cortex_m34_stacking = {
diff --git a/src/rtos/rtos_riot_stackings.h b/src/rtos/rtos_riot_stackings.h
index c5b8f59..3b6c5f4 100644
--- a/src/rtos/rtos_riot_stackings.h
+++ b/src/rtos/rtos_riot_stackings.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2015 by Daniel Krebs *
* Daniel Krebs - github@daniel-krebs.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_RTOS_RTOS_RIOT_STACKINGS_H
diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c
index d338a47..f2b4e15 100644
--- a/src/rtos/rtos_standard_stackings.c
+++ b/src/rtos/rtos_standard_stackings.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -41,7 +30,7 @@ static const struct stack_register_offset rtos_standard_cortex_m3_stack_offsets[
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, 0x34, 32 }, /* lr */
{ ARMV7M_PC, 0x38, 32 }, /* pc */
- { ARMV7M_xPSR, 0x3c, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x3c, 32 }, /* xPSR */
};
static const struct stack_register_offset rtos_standard_cortex_m4f_stack_offsets[] = {
@@ -61,7 +50,7 @@ static const struct stack_register_offset rtos_standard_cortex_m4f_stack_offsets
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, 0x38, 32 }, /* lr */
{ ARMV7M_PC, 0x3c, 32 }, /* pc */
- { ARMV7M_xPSR, 0x40, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x40, 32 }, /* xPSR */
};
static const struct stack_register_offset rtos_standard_cortex_m4f_fpu_stack_offsets[] = {
@@ -81,7 +70,7 @@ static const struct stack_register_offset rtos_standard_cortex_m4f_fpu_stack_off
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, 0x78, 32 }, /* lr */
{ ARMV7M_PC, 0x7c, 32 }, /* pc */
- { ARMV7M_xPSR, 0x80, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x80, 32 }, /* xPSR */
};
diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h
index 71118fd..455acc4 100644
--- a/src/rtos/rtos_standard_stackings.h
+++ b/src/rtos/rtos_standard_stackings.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H
diff --git a/src/rtos/rtos_ucos_iii_stackings.c b/src/rtos/rtos_ucos_iii_stackings.c
index 0d533b5..9ba5288 100644
--- a/src/rtos/rtos_ucos_iii_stackings.c
+++ b/src/rtos/rtos_ucos_iii_stackings.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -43,7 +32,7 @@ static const struct stack_register_offset rtos_ucos_iii_cortex_m_stack_offsets[]
{ ARMV7M_R13, -2, 32 }, /* sp */
{ ARMV7M_R14, 0x34, 32 }, /* lr */
{ ARMV7M_PC, 0x38, 32 }, /* pc */
- { ARMV7M_xPSR, 0x3c, 32 }, /* xPSR */
+ { ARMV7M_XPSR, 0x3c, 32 }, /* xPSR */
};
static const struct stack_register_offset rtos_ucos_iii_esi_risc_stack_offsets[] = {
diff --git a/src/rtos/rtos_ucos_iii_stackings.h b/src/rtos/rtos_ucos_iii_stackings.h
index f2f120f..831c68e 100644
--- a/src/rtos/rtos_ucos_iii_stackings.h
+++ b/src/rtos/rtos_ucos_iii_stackings.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2017 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_RTOS_RTOS_UCOS_III_STACKINGS_H
diff --git a/src/rtos/uCOS-III.c b/src/rtos/uCOS-III.c
index 385c8d8..21be8ff 100644
--- a/src/rtos/uCOS-III.c
+++ b/src/rtos/uCOS-III.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/zephyr.c b/src/rtos/zephyr.c
index 7f3325f..b00b4b3 100644
--- a/src/rtos/zephyr.c
+++ b/src/rtos/zephyr.c
@@ -1,11 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2017 by Intel Corporation
* Leandro Pereira <leandro.pereira@intel.com>
* Daniel Glöckner <dg@emlix.com>*
* Copyright (C) 2021 by Synopsys, Inc.
* Evgeniy Didin <didin@synopsys.com>
- * *
- * SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -136,7 +136,7 @@ static const struct stack_register_offset arm_cpu_saved[] = {
{ ARMV7M_R13, -2, 32 },
{ ARMV7M_R14, 20, 32 },
{ ARMV7M_PC, 24, 32 },
- { ARMV7M_xPSR, 28, 32 },
+ { ARMV7M_XPSR, 28, 32 },
};
static struct stack_register_offset arc_cpu_saved[] = {
diff --git a/src/rtt/Makefile.am b/src/rtt/Makefile.am
index e3fcefd..9968554 100644
--- a/src/rtt/Makefile.am
+++ b/src/rtt/Makefile.am
@@ -1,2 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/librtt.la
%C%_librtt_la_SOURCES = %D%/rtt.c %D%/rtt.h %D%/tcl.c
diff --git a/src/rtt/rtt.c b/src/rtt/rtt.c
index 3da3cce..e31e754 100644
--- a/src/rtt/rtt.c
+++ b/src/rtt/rtt.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtt/rtt.h b/src/rtt/rtt.h
index bc21bd0..a5630a9 100644
--- a/src/rtt/rtt.h
+++ b/src/rtt/rtt.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENOCD_RTT_RTT_H
diff --git a/src/rtt/tcl.c b/src/rtt/tcl.c
index 4a34d8b..7cbdccf 100644
--- a/src/rtt/tcl.c
+++ b/src/rtt/tcl.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2019-2020 by Marc Schink <dev@zapb.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/server/Makefile.am b/src/server/Makefile.am
index e3699f1..13a5914 100644
--- a/src/server/Makefile.am
+++ b/src/server/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libserver.la
%C%_libserver_la_SOURCES = \
%D%/server.c \
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index e5bf74f..956a347 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -19,19 +21,6 @@
* *
* Copyright (C) 2013 Franck Jullien *
* elec4fun@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -1362,6 +1351,8 @@ static int gdb_set_registers_packet(struct connection *connection,
packet_p = packet;
for (i = 0; i < reg_list_size; i++) {
uint8_t *bin_buf;
+ if (!reg_list[i] || !reg_list[i]->exist || reg_list[i]->hidden)
+ continue;
int chars = (DIV_ROUND_UP(reg_list[i]->size, 8) * 2);
if (packet_p + chars > packet + packet_size)
@@ -1414,7 +1405,8 @@ static int gdb_get_register_packet(struct connection *connection,
if (retval != ERROR_OK)
return gdb_error(connection, retval);
- if (reg_list_size <= reg_num) {
+ if ((reg_list_size <= reg_num) || !reg_list[reg_num] ||
+ !reg_list[reg_num]->exist || reg_list[reg_num]->hidden) {
LOG_ERROR("gdb requested a non-existing register (reg_num=%d)", reg_num);
return ERROR_SERVER_REMOTE_CLOSED;
}
@@ -1476,7 +1468,8 @@ static int gdb_set_register_packet(struct connection *connection,
return gdb_error(connection, retval);
}
- if (reg_list_size <= reg_num) {
+ if ((reg_list_size <= reg_num) || !reg_list[reg_num] ||
+ !reg_list[reg_num]->exist || reg_list[reg_num]->hidden) {
LOG_ERROR("gdb requested a non-existing register (reg_num=%d)", reg_num);
free(bin_buf);
free(reg_list);
@@ -1814,8 +1807,11 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
if (!bp_target)
return ERROR_FAIL;
}
- retval = breakpoint_add(bp_target, address, size, bp_type);
- if (retval != ERROR_OK) {
+ retval = breakpoint_add(target, address, size, bp_type);
+ if (retval == ERROR_NOT_IMPLEMENTED) {
+ /* Send empty reply to report that breakpoints of this type are not supported */
+ gdb_put_packet(connection, "", 0);
+ } else if (retval != ERROR_OK) {
retval = gdb_error(connection, retval);
if (retval != ERROR_OK)
return retval;
@@ -1832,7 +1828,10 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
{
if (packet[0] == 'Z') {
retval = watchpoint_add(target, address, size, wp_type, 0, 0xffffffffu);
- if (retval != ERROR_OK) {
+ if (retval == ERROR_NOT_IMPLEMENTED) {
+ /* Send empty reply to report that watchpoints of this type are not supported */
+ gdb_put_packet(connection, "", 0);
+ } else if (retval != ERROR_OK) {
retval = gdb_error(connection, retval);
if (retval != ERROR_OK)
return retval;
@@ -3002,6 +3001,11 @@ static int gdb_query_packet(struct connection *connection,
gdb_connection->noack_mode = 1;
gdb_put_packet(connection, "OK", 2);
return ERROR_OK;
+ } else if (target->type->gdb_query_custom) {
+ char *buffer = NULL;
+ int ret = target->type->gdb_query_custom(target, packet, &buffer);
+ gdb_put_packet(connection, buffer, strlen(buffer));
+ return ret;
}
gdb_put_packet(connection, "", 0);
@@ -3062,139 +3066,138 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
gdb_running_type = 's';
bool fake_step = false;
- if (strncmp(parse, "s:", 2) == 0) {
- struct target *ct = target;
- int current_pc = 1;
- int64_t thread_id;
+ struct target *ct = target;
+ int current_pc = 1;
+ int64_t thread_id;
+ parse++;
+ packet_size--;
+ if (parse[0] == ':') {
char *endp;
-
- parse += 2;
- packet_size -= 2;
-
+ parse++;
+ packet_size--;
thread_id = strtoll(parse, &endp, 16);
if (endp) {
packet_size -= endp - parse;
parse = endp;
}
+ } else {
+ thread_id = 0;
+ }
- if (target->rtos) {
- /* FIXME: why is this necessary? rtos state should be up-to-date here already! */
-
- /* Sometimes this results in picking a different thread than
- * gdb just requested to step. Then we fake it, and now there's
- * a different thread selected than gdb expects, so register
- * accesses go to the wrong one!
- * E.g.:
- * Hg1$
- * P8=72101ce197869329$ # write r8 on thread 1
- * g$
- * vCont?$
- * vCont;s:1;c$ # rtos_update_threads changes to other thread
- * g$
- * qXfer:threads:read::0,fff$
- * P8=cc060607eb89ca7f$ # write r8 on other thread
- * g$
- * */
- /* rtos_update_threads(target); */
-
- target->rtos->gdb_target_for_threadid(connection, thread_id, &ct);
-
- /*
- * check if the thread to be stepped is the current rtos thread
- * if not, we must fake the step
- */
- fake_step = rtos_needs_fake_step(target, thread_id);
- }
+ if (target->rtos) {
+ /* FIXME: why is this necessary? rtos state should be up-to-date here already! */
+
+ /* Sometimes this results in picking a different thread than
+ * gdb just requested to step. Then we fake it, and now there's
+ * a different thread selected than gdb expects, so register
+ * accesses go to the wrong one!
+ * E.g.:
+ * Hg1$
+ * P8=72101ce197869329$ # write r8 on thread 1
+ * g$
+ * vCont?$
+ * vCont;s:1;c$ # rtos_update_threads changes to other thread
+ * g$
+ * qXfer:threads:read::0,fff$
+ * P8=cc060607eb89ca7f$ # write r8 on other thread
+ * g$
+ * */
+ /* rtos_update_threads(target); */
+
+ target->rtos->gdb_target_for_threadid(connection, thread_id, &ct);
+
+ /*
+ * check if the thread to be stepped is the current rtos thread
+ * if not, we must fake the step
+ */
+ fake_step = rtos_needs_fake_step(target, thread_id);
+ }
+
+ if (parse[0] == ';') {
+ ++parse;
+ --packet_size;
- if (parse[0] == ';') {
- ++parse;
- --packet_size;
+ if (parse[0] == 'c') {
+ parse += 1;
- if (parse[0] == 'c') {
+ /* check if thread-id follows */
+ if (parse[0] == ':') {
+ int64_t tid;
parse += 1;
- /* check if thread-id follows */
- if (parse[0] == ':') {
- int64_t tid;
- parse += 1;
-
- tid = strtoll(parse, &endp, 16);
- if (tid == thread_id) {
- /*
- * Special case: only step a single thread (core),
- * keep the other threads halted. Currently, only
- * aarch64 target understands it. Other target types don't
- * care (nobody checks the actual value of 'current')
- * and it doesn't really matter. This deserves
- * a symbolic constant and a formal interface documentation
- * at a later time.
- */
- LOG_DEBUG("request to step current core only");
- /* uncomment after checking that indeed other targets are safe */
- /*current_pc = 2;*/
- }
+ tid = strtoll(parse, NULL, 16);
+ if (tid == thread_id) {
+ /*
+ * Special case: only step a single thread (core),
+ * keep the other threads halted. Currently, only
+ * aarch64 target understands it. Other target types don't
+ * care (nobody checks the actual value of 'current')
+ * and it doesn't really matter. This deserves
+ * a symbolic constant and a formal interface documentation
+ * at a later time.
+ */
+ LOG_DEBUG("request to step current core only");
+ /* uncomment after checking that indeed other targets are safe */
+ /*current_pc = 2;*/
}
}
}
+ }
- LOG_DEBUG("target %s single-step thread %"PRIx64, target_name(ct), thread_id);
- gdb_connection->output_flag = GDB_OUTPUT_ALL;
- target_call_event_callbacks(ct, TARGET_EVENT_GDB_START);
-
- if (fake_step) {
- /* We just fake the step to not trigger an internal error in
- * gdb. See https://sourceware.org/bugzilla/show_bug.cgi?id=22925
- * for details. */
- int sig_reply_len;
- char sig_reply[128];
-
- LOG_DEBUG("fake step thread %"PRIx64, thread_id);
- target->rtos->current_threadid = thread_id;
+ LOG_DEBUG("target %s single-step thread %"PRIx64, target_name(ct), thread_id);
+ gdb_connection->output_flag = GDB_OUTPUT_ALL;
+ target_call_event_callbacks(ct, TARGET_EVENT_GDB_START);
- sig_reply_len = snprintf(sig_reply, sizeof(sig_reply),
- "T05thread:%016"PRIx64";", thread_id);
+ if (fake_step) {
+ /* We just fake the step to not trigger an internal error in
+ * gdb. See https://sourceware.org/bugzilla/show_bug.cgi?id=22925
+ * for details. */
+ int sig_reply_len;
+ char sig_reply[128];
- gdb_put_packet(connection, sig_reply, sig_reply_len);
- gdb_connection->output_flag = GDB_OUTPUT_NO;
+ LOG_DEBUG("fake step thread %"PRIx64, thread_id);
+ target->rtos->current_threadid = thread_id;
- return true;
- }
+ sig_reply_len = snprintf(sig_reply, sizeof(sig_reply),
+ "T05thread:%016"PRIx64";", thread_id);
- /* support for gdb_sync command */
- if (gdb_connection->sync) {
- gdb_connection->sync = false;
- if (ct->state == TARGET_HALTED) {
- LOG_DEBUG("stepi ignored. GDB will now fetch the register state "
- "from the target.");
- gdb_sig_halted(connection);
- gdb_connection->output_flag = GDB_OUTPUT_NO;
- } else
- gdb_connection->frontend_state = TARGET_RUNNING;
- return true;
- }
+ gdb_put_packet(connection, sig_reply, sig_reply_len);
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
- retval = target_step(ct, current_pc, 0, 0);
- if (retval == ERROR_TARGET_NOT_HALTED)
- LOG_INFO("target %s was not halted when step was requested", target_name(ct));
+ return true;
+ }
- /* if step was successful send a reply back to gdb */
- if (retval == ERROR_OK) {
- retval = target_poll(ct);
- if (retval != ERROR_OK)
- LOG_DEBUG("error polling target %s after successful step", target_name(ct));
- /* send back signal information */
- gdb_signal_reply(ct, connection);
- /* stop forwarding log packets! */
+ /* support for gdb_sync command */
+ if (gdb_connection->sync) {
+ gdb_connection->sync = false;
+ if (ct->state == TARGET_HALTED) {
+ LOG_DEBUG("stepi ignored. GDB will now fetch the register state "
+ "from the target.");
+ gdb_sig_halted(connection);
gdb_connection->output_flag = GDB_OUTPUT_NO;
} else
gdb_connection->frontend_state = TARGET_RUNNING;
- } else {
- LOG_ERROR("Unknown vCont packet");
- return false;
+ return true;
}
+
+ retval = target_step(ct, current_pc, 0, 0);
+ if (retval == ERROR_TARGET_NOT_HALTED)
+ LOG_INFO("target %s was not halted when step was requested", target_name(ct));
+
+ /* if step was successful send a reply back to gdb */
+ if (retval == ERROR_OK) {
+ retval = target_poll(ct);
+ if (retval != ERROR_OK)
+ LOG_DEBUG("error polling target %s after successful step", target_name(ct));
+ /* send back signal information */
+ gdb_signal_reply(ct, connection);
+ /* stop forwarding log packets! */
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
+ } else
+ gdb_connection->frontend_state = TARGET_RUNNING;
return true;
}
-
+ LOG_ERROR("Unknown vCont packet");
return false;
}
diff --git a/src/server/gdb_server.h b/src/server/gdb_server.h
index 0c50836..6821e36 100644
--- a/src/server/gdb_server.h
+++ b/src/server/gdb_server.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2011 by Broadcom Corporation *
* Evan Hunter - ehunter@broadcom.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_SERVER_GDB_SERVER_H
diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c
index 3bbcf07..f4a6f6c 100644
--- a/src/server/ipdbg.c
+++ b/src/server/ipdbg.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Copyright (C) 2020 by Daniel Anselmi <danselmi@gmx.ch> */
#ifdef HAVE_CONFIG_H
diff --git a/src/server/rtt_server.c b/src/server/rtt_server.c
index 3850c26..df2247b 100644
--- a/src/server/rtt_server.c
+++ b/src/server/rtt_server.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2016-2017 by Marc Schink <dev@zapb.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/server/rtt_server.h b/src/server/rtt_server.h
index aec6f22..5cea25a 100644
--- a/src/server/rtt_server.h
+++ b/src/server/rtt_server.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (C) 2016-2017 by Marc Schink <dev@zapb.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENOCD_SERVER_RTT_SERVER_H
diff --git a/src/server/server.c b/src/server/server.c
index 082febb..4da31ae 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -484,7 +473,7 @@ int server_loop(struct command_context *command_context)
tv.tv_usec = 0;
retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
} else {
- /* Every 100ms, can be changed with "poll_period" command */
+ /* Timeout socket_select() when a target timer expires or every polling_period */
int timeout_ms = next_event - timeval_ms();
if (timeout_ms < 0)
timeout_ms = 0;
@@ -519,9 +508,12 @@ int server_loop(struct command_context *command_context)
}
if (retval == 0) {
- /* We only execute these callbacks when there was nothing to do or we timed
- *out */
- target_call_timer_callbacks_now();
+ /* Execute callbacks of expired timers when
+ * - there was nothing to do if poll_ok was true
+ * - socket_select() timed out if poll_ok was false, now one or more
+ * timers expired or the polling period elapsed
+ */
+ target_call_timer_callbacks();
next_event = target_timer_next_event();
process_jim_events(command_context);
@@ -756,6 +748,11 @@ int connection_read(struct connection *connection, void *data, int len)
return read(connection->fd, data, len);
}
+bool openocd_is_shutdown_pending(void)
+{
+ return shutdown_openocd != CONTINUE_MAIN_LOOP;
+}
+
/* tell the server we want to shut down */
COMMAND_HANDLER(handle_shutdown_command)
{
diff --git a/src/server/server.h b/src/server/server.h
index a6b1963..c9d4698 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_SERVER_SERVER_H
@@ -115,6 +104,8 @@ int server_register_commands(struct command_context *context);
int connection_write(struct connection *connection, const void *data, int len);
int connection_read(struct connection *connection, void *data, int len);
+bool openocd_is_shutdown_pending(void);
+
/**
* Defines an extended command handler function declaration to enable
* access to (and manipulation of) the server port number.
diff --git a/src/server/startup.tcl b/src/server/startup.tcl
index 447b57c..1d30b1d 100644
--- a/src/server/startup.tcl
+++ b/src/server/startup.tcl
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
# Defines basic Tcl procs for OpenOCD server modules
# Handle GDB 'R' packet. Can be overridden by configuration script,
diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c
index 458d7ea..16cbedc 100644
--- a/src/server/tcl_server.c
+++ b/src/server/tcl_server.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/server/tcl_server.h b/src/server/tcl_server.h
index 6ce3ab9..bee562c 100644
--- a/src/server/tcl_server.h
+++ b/src/server/tcl_server.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_SERVER_TCL_SERVER_H
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index 8e79626..938bc5b 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/server/telnet_server.h b/src/server/telnet_server.h
index 27148d7..313b529 100644
--- a/src/server/telnet_server.h
+++ b/src/server/telnet_server.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_SERVER_TELNET_SERVER_H
diff --git a/src/svf/Makefile.am b/src/svf/Makefile.am
index 5603d53..5fcb02c 100644
--- a/src/svf/Makefile.am
+++ b/src/svf/Makefile.am
@@ -1,2 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libsvf.la
%C%_libsvf_la_SOURCES = %D%/svf.c %D%/svf.h
diff --git a/src/svf/svf.c b/src/svf/svf.c
index 3021dcb..a537431 100644
--- a/src/svf/svf.c
+++ b/src/svf/svf.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Simon Qian *
* SimonQian@SimonQian.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* The specification for SVF is available here:
diff --git a/src/svf/svf.h b/src/svf/svf.h
index 4101a3f..74f7d9c 100644
--- a/src/svf/svf.h
+++ b/src/svf/svf.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Simon Qian *
* SimonQian@SimonQian.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_SVF_SVF_H
diff --git a/src/target/Makefile.am b/src/target/Makefile.am
index 799c3dd..4687092 100644
--- a/src/target/Makefile.am
+++ b/src/target/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
%C%_libtarget_la_LIBADD = %D%/openrisc/libopenrisc.la \
%D%/riscv/libriscv.la \
%D%/xtensa/libxtensa.la \
diff --git a/src/target/a64_disassembler.c b/src/target/a64_disassembler.c
index 58ddf60..ca3d3ea 100644
--- a/src/target/a64_disassembler.c
+++ b/src/target/a64_disassembler.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2019 by Mete Balci *
* metebalci@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/a64_disassembler.h b/src/target/a64_disassembler.h
index 5c58bbf..28fcf4b 100644
--- a/src/target/a64_disassembler.h
+++ b/src/target/a64_disassembler.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2019 by Mete Balci *
* metebalci@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_AARCH64_DISASSEMBLER_H
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index ecd9324..8592daa 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -1,20 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by David Ung *
* *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -1849,7 +1837,7 @@ static int aarch64_remove_watchpoint(struct target *target,
* find out which watchpoint hits
* get exception address and compare the address to watchpoints
*/
-int aarch64_hit_watchpoint(struct target *target,
+static int aarch64_hit_watchpoint(struct target *target,
struct watchpoint **hit_watchpoint)
{
if (target->debug_reason != DBG_REASON_WATCHPOINT)
@@ -1942,7 +1930,7 @@ static int aarch64_assert_reset(struct target *target)
else if (reset_config & RESET_HAS_SRST) {
bool srst_asserted = false;
- if (target->reset_halt) {
+ if (target->reset_halt && !(reset_config & RESET_SRST_PULLS_TRST)) {
if (target_was_examined(target)) {
if (reset_config & RESET_SRST_NO_GATING) {
@@ -1952,12 +1940,12 @@ static int aarch64_assert_reset(struct target *target)
*/
adapter_assert_reset();
srst_asserted = true;
-
- /* make sure to clear all sticky errors */
- mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
}
+ /* make sure to clear all sticky errors */
+ mem_ap_write_atomic_u32(armv8->debug_ap,
+ armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
+
/* set up Reset Catch debug event to halt the CPU after reset */
retval = aarch64_enable_reset_catch(target, true);
if (retval != ERROR_OK)
@@ -2558,15 +2546,24 @@ 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_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);
+ 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_ap(swjdp, pc->adiv5_config.ap_num);
+ armv8->debug_ap = dap_get_ap(swjdp, pc->adiv5_config.ap_num);
+ if (!armv8->debug_ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
retval = mem_ap_init(armv8->debug_ap);
@@ -2755,6 +2752,9 @@ static void aarch64_deinit_target(struct target *target)
struct armv8_common *armv8 = &aarch64->armv8_common;
struct arm_dpm *dpm = &armv8->dpm;
+ if (armv8->debug_ap)
+ dap_put_ap(armv8->debug_ap);
+
armv8_free_reg_cache(target);
free(aarch64->brp_list);
free(dpm->dbp);
@@ -3144,8 +3144,6 @@ static const struct command_registration aarch64_exec_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
-extern const struct command_registration semihosting_common_handlers[];
-
static const struct command_registration aarch64_command_handlers[] = {
{
.name = "arm",
diff --git a/src/target/aarch64.h b/src/target/aarch64.h
index b57361f..2721fe7 100644
--- a/src/target/aarch64.h
+++ b/src/target/aarch64.h
@@ -1,19 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2015 by David Ung *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
***************************************************************************/
#ifndef OPENOCD_TARGET_AARCH64_H
@@ -21,7 +9,7 @@
#include "armv8.h"
-#define AARCH64_COMMON_MAGIC 0x411fc082
+#define AARCH64_COMMON_MAGIC 0x41413634U
#define CPUDBG_CPUID 0xD00
#define CPUDBG_CTYPR 0xD04
@@ -50,7 +38,9 @@ struct aarch64_brp {
};
struct aarch64_common {
- int common_magic;
+ unsigned int common_magic;
+
+ struct armv8_common armv8_common;
/* Context information */
uint32_t system_control_reg;
@@ -67,8 +57,6 @@ struct aarch64_common {
int wp_num_available;
struct aarch64_brp *wp_list;
- struct armv8_common armv8_common;
-
enum aarch64_isrmasking_mode isrmasking_mode;
};
diff --git a/src/target/adi_v5_dapdirect.c b/src/target/adi_v5_dapdirect.c
index c0deee1..e1c00b7 100644
--- a/src/target/adi_v5_dapdirect.c
+++ b/src/target/adi_v5_dapdirect.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2019, STMicroelectronics - All Rights Reserved
* Author(s): Antonio Borneo <borneo.antonio@gmail.com> for STMicroelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c
index 94ee8cf..eeb796b 100644
--- a/src/target/adi_v5_jtag.c
+++ b/src/target/adi_v5_jtag.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Magnus Lundin
* lundin@mlu.mine.nu
@@ -10,24 +12,13 @@
*
* Copyright (C) 2009-2010 by David Brownell
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * Copyright (C) 2020-2021, Ampere Computing LLC *
***************************************************************************/
/**
* @file
* This file implements JTAG transport support for cores implementing
- the ARM Debug Interface version 5 (ADIv5).
+ the ARM Debug Interface version 5 (ADIv5) and version 6 (ADIv6).
*/
#ifdef HAVE_CONFIG_H
@@ -49,13 +40,15 @@
#define JTAG_DP_IDCODE 0xFE
/* three-bit ACK values for DPACC and APACC reads */
-#define JTAG_ACK_OK_FAULT 0x2
-#define JTAG_ACK_WAIT 0x1
+#define JTAG_ACK_WAIT 0x1 /* ADIv5 and ADIv6 */
+#define JTAG_ACK_OK_FAULT 0x2 /* ADIv5 */
+#define JTAG_ACK_FAULT 0x2 /* ADIv6 */
+#define JTAG_ACK_OK 0x4 /* ADIV6 */
static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack);
#ifdef DEBUG_WAIT
-static const char *dap_reg_name(int instr, int reg_addr)
+static const char *dap_reg_name(struct adiv5_dap *dap, uint8_t instr, uint16_t reg_addr)
{
char *reg_name = "UNK";
@@ -83,41 +76,32 @@ static const char *dap_reg_name(int instr, int reg_addr)
}
if (instr == JTAG_DP_APACC) {
- switch (reg_addr) {
- case MEM_AP_REG_CSW:
+ if (reg_addr == MEM_AP_REG_CSW(dap))
reg_name = "CSW";
- break;
- case MEM_AP_REG_TAR:
+ else if (reg_addr == MEM_AP_REG_TAR(dap))
reg_name = "TAR";
- break;
- case MEM_AP_REG_DRW:
+ else if (reg_addr == MEM_AP_REG_TAR64(dap))
+ reg_name = "TAR64";
+ else if (reg_addr == MEM_AP_REG_DRW(dap))
reg_name = "DRW";
- break;
- case MEM_AP_REG_BD0:
+ else if (reg_addr == MEM_AP_REG_BD0(dap))
reg_name = "BD0";
- break;
- case MEM_AP_REG_BD1:
+ else if (reg_addr == MEM_AP_REG_BD1(dap))
reg_name = "BD1";
- break;
- case MEM_AP_REG_BD2:
+ else if (reg_addr == MEM_AP_REG_BD2(dap))
reg_name = "BD2";
- break;
- case MEM_AP_REG_BD3:
+ else if (reg_addr == MEM_AP_REG_BD3(dap))
reg_name = "BD3";
- break;
- case MEM_AP_REG_CFG:
+ else if (reg_addr == MEM_AP_REG_CFG(dap))
reg_name = "CFG";
- break;
- case MEM_AP_REG_BASE:
+ else if (reg_addr == MEM_AP_REG_BASE(dap))
reg_name = "BASE";
- break;
- case AP_REG_IDR:
+ else if (reg_addr == MEM_AP_REG_BASE64(dap))
+ reg_name = "BASE64";
+ else if (reg_addr == AP_REG_IDR(dap))
reg_name = "IDR";
- break;
- default:
+ else
reg_name = "UNK";
- break;
- }
}
return reg_name;
@@ -127,12 +111,12 @@ static const char *dap_reg_name(int instr, int reg_addr)
struct dap_cmd {
struct list_head lh;
uint8_t instr;
- uint8_t reg_addr;
+ uint16_t reg_addr;
uint8_t rnw;
uint8_t *invalue;
uint8_t ack;
uint32_t memaccess_tck;
- uint32_t dp_select;
+ uint64_t dp_select;
struct scan_field fields[2];
uint8_t out_addr_buf;
@@ -147,17 +131,38 @@ struct dap_cmd_pool {
struct dap_cmd cmd;
};
-static void log_dap_cmd(const char *header, struct dap_cmd *el)
+static void log_dap_cmd(struct adiv5_dap *dap, const char *header, struct dap_cmd *el)
{
#ifdef DEBUG_WAIT
+ const char *ack;
+ switch (el->ack) {
+ case JTAG_ACK_WAIT: /* ADIv5 and ADIv6 */
+ ack = "WAIT";
+ break;
+ case JTAG_ACK_OK_FAULT: /* ADIv5, same value as JTAG_ACK_FAULT */
+ /* case JTAG_ACK_FAULT: */ /* ADIv6 */
+ if (is_adiv6(dap))
+ ack = "FAULT";
+ else
+ ack = "OK";
+ break;
+ case JTAG_ACK_OK: /* ADIv6 */
+ if (is_adiv6(dap)) {
+ ack = "OK";
+ break;
+ }
+ /* fall-through */
+ default:
+ ack = "INVAL";
+ break;
+ }
LOG_DEBUG("%s: %2s %6s %5s 0x%08x 0x%08x %2s", header,
el->instr == JTAG_DP_APACC ? "AP" : "DP",
- dap_reg_name(el->instr, el->reg_addr),
+ dap_reg_name(dap, el->instr, el->reg_addr),
el->rnw == DPAP_READ ? "READ" : "WRITE",
buf_get_u32(el->outvalue_buf, 0, 32),
buf_get_u32(el->invalue, 0, 32),
- el->ack == JTAG_ACK_OK_FAULT ? "OK" :
- (el->ack == JTAG_ACK_WAIT ? "WAIT" : "INVAL"));
+ ack);
#endif
}
@@ -170,7 +175,7 @@ static int jtag_limit_queue_size(struct adiv5_dap *dap)
}
static struct dap_cmd *dap_cmd_new(struct adiv5_dap *dap, uint8_t instr,
- uint8_t reg_addr, uint8_t rnw,
+ uint16_t reg_addr, uint8_t rnw,
uint8_t *outvalue, uint8_t *invalue,
uint32_t memaccess_tck)
{
@@ -268,17 +273,14 @@ static int adi_jtag_dp_scan_cmd(struct adiv5_dap *dap, struct dap_cmd *cmd, uint
jtag_add_dr_scan(tap, 2, cmd->fields, TAP_IDLE);
- /* Add specified number of tck clocks after starting memory bus
- * access, giving the hardware time to complete the access.
+ /* Add specified number of tck clocks after starting AP register
+ * access or memory bus access, giving the hardware time to complete
+ * the access.
* They provide more time for the (MEM) AP to complete the read ...
- * See "Minimum Response Time" for JTAG-DP, in the ADIv5 spec.
+ * See "Minimum Response Time" for JTAG-DP, in the ADIv5/ADIv6 spec.
*/
- if (cmd->instr == JTAG_DP_APACC) {
- if (((cmd->reg_addr == MEM_AP_REG_DRW)
- || ((cmd->reg_addr & 0xF0) == MEM_AP_REG_BD0))
- && (cmd->memaccess_tck != 0))
- jtag_add_runtest(cmd->memaccess_tck, TAP_IDLE);
- }
+ if (cmd->instr == JTAG_DP_APACC && cmd->memaccess_tck != 0)
+ jtag_add_runtest(cmd->memaccess_tck, TAP_IDLE);
return ERROR_OK;
}
@@ -296,7 +298,7 @@ static int adi_jtag_dp_scan_cmd_sync(struct adiv5_dap *dap, struct dap_cmd *cmd,
/**
* Scan DPACC or APACC using target ordered uint8_t buffers. No endianness
- * conversions are performed. See section 4.4.3 of the ADIv5 spec, which
+ * conversions are performed. See section 4.4.3 of the ADIv5/ADIv6 spec, which
* discusses operations which access these registers.
*
* Note that only one scan is performed. If rnw is set, a separate scan
@@ -315,7 +317,7 @@ static int adi_jtag_dp_scan_cmd_sync(struct adiv5_dap *dap, struct dap_cmd *cmd,
*/
static int adi_jtag_dp_scan(struct adiv5_dap *dap,
- uint8_t instr, uint8_t reg_addr, uint8_t rnw,
+ uint8_t instr, uint16_t reg_addr, uint8_t rnw,
uint8_t *outvalue, uint8_t *invalue,
uint32_t memaccess_tck, uint8_t *ack)
{
@@ -342,13 +344,27 @@ static int adi_jtag_dp_scan(struct adiv5_dap *dap,
* must be different).
*/
static int adi_jtag_dp_scan_u32(struct adiv5_dap *dap,
- uint8_t instr, uint8_t reg_addr, uint8_t rnw,
+ uint8_t instr, uint16_t reg_addr, uint8_t rnw,
uint32_t outvalue, uint32_t *invalue,
uint32_t memaccess_tck, uint8_t *ack)
{
uint8_t out_value_buf[4];
int retval;
-
+ uint64_t sel = (reg_addr >> 4) & 0xf;
+
+ /* No need to change SELECT or RDBUFF as they are not banked */
+ if (instr == JTAG_DP_DPACC && reg_addr != DP_SELECT && reg_addr != DP_RDBUFF &&
+ sel != (dap->select & 0xf)) {
+ if (dap->select != DP_SELECT_INVALID)
+ sel |= dap->select & ~0xfull;
+ dap->select = sel;
+ LOG_DEBUG("DP BANKSEL: %x", (uint32_t)sel);
+ buf_set_u32(out_value_buf, 0, 32, (uint32_t)sel);
+ retval = adi_jtag_dp_scan(dap, JTAG_DP_DPACC,
+ DP_SELECT, DPAP_WRITE, out_value_buf, NULL, 0, NULL);
+ if (retval != ERROR_OK)
+ return retval;
+ }
buf_set_u32(out_value_buf, 0, 32, outvalue);
retval = adi_jtag_dp_scan(dap, instr, reg_addr, rnw,
@@ -377,7 +393,7 @@ static int adi_jtag_finish_read(struct adiv5_dap *dap)
}
static int adi_jtag_scan_inout_check_u32(struct adiv5_dap *dap,
- uint8_t instr, uint8_t reg_addr, uint8_t rnw,
+ uint8_t instr, uint16_t reg_addr, uint8_t rnw,
uint32_t outvalue, uint32_t *invalue, uint32_t memaccess_tck)
{
int retval;
@@ -416,14 +432,19 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
/* skip all completed transactions up to the first WAIT */
list_for_each_entry(el, &dap->cmd_journal, lh) {
- if (el->ack == JTAG_ACK_OK_FAULT) {
- log_dap_cmd("LOG", el);
+ /*
+ * JTAG_ACK_OK_FAULT (ADIv5) and JTAG_ACK_FAULT (ADIv6) are equal so
+ * the following statement is checking to see if an acknowledgment of
+ * OK or FAULT is generated for ADIv5 or ADIv6
+ */
+ if (el->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && el->ack == JTAG_ACK_OK)) {
+ log_dap_cmd(dap, "LOG", el);
} else if (el->ack == JTAG_ACK_WAIT) {
found_wait = 1;
break;
} else {
LOG_ERROR("Invalid ACK (%1x) in DAP response", el->ack);
- log_dap_cmd("ERR", el);
+ log_dap_cmd(dap, "ERR", el);
retval = ERROR_JTAG_DEVICE_ERROR;
goto done;
}
@@ -436,14 +457,15 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
if (found_wait && el != list_first_entry(&dap->cmd_journal, struct dap_cmd, lh)) {
prev = list_entry(el->lh.prev, struct dap_cmd, lh);
if (prev->rnw == DPAP_READ) {
- log_dap_cmd("PND", prev);
+ log_dap_cmd(dap, "PND", prev);
/* search for the next OK transaction, it contains
* the result of the previous READ */
tmp = el;
list_for_each_entry_from(tmp, &dap->cmd_journal, lh) {
- if (tmp->ack == JTAG_ACK_OK_FAULT) {
+ /* The following check covers OK and FAULT ACKs for both ADIv5 and ADIv6 */
+ if (tmp->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && tmp->ack == JTAG_ACK_OK)) {
/* recover the read value */
- log_dap_cmd("FND", tmp);
+ log_dap_cmd(dap, "FND", tmp);
if (el->invalue != el->invalue_buf) {
uint32_t invalue = le_to_h_u32(tmp->invalue);
memcpy(el->invalue, &invalue, sizeof(uint32_t));
@@ -454,7 +476,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
}
if (prev) {
- log_dap_cmd("LST", el);
+ log_dap_cmd(dap, "LST", el);
/*
* At this point we're sure that no previous
@@ -476,8 +498,9 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
retval = adi_jtag_dp_scan_cmd_sync(dap, tmp, NULL);
if (retval != ERROR_OK)
break;
- if (tmp->ack == JTAG_ACK_OK_FAULT) {
- log_dap_cmd("FND", tmp);
+ /* The following check covers OK and FAULT ACKs for both ADIv5 and ADIv6 */
+ if (tmp->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && tmp->ack == JTAG_ACK_OK)) {
+ log_dap_cmd(dap, "FND", tmp);
if (el->invalue != el->invalue_buf) {
uint32_t invalue = le_to_h_u32(tmp->invalue);
memcpy(el->invalue, &invalue, sizeof(uint32_t));
@@ -486,7 +509,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
}
if (tmp->ack != JTAG_ACK_WAIT) {
LOG_ERROR("Invalid ACK (%1x) in DAP response", tmp->ack);
- log_dap_cmd("ERR", tmp);
+ log_dap_cmd(dap, "ERR", tmp);
retval = ERROR_JTAG_DEVICE_ERROR;
break;
}
@@ -495,7 +518,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
if (retval == ERROR_OK) {
/* timeout happened */
- if (tmp->ack != JTAG_ACK_OK_FAULT) {
+ if (tmp->ack == JTAG_ACK_WAIT) {
LOG_ERROR("Timeout during WAIT recovery");
dap->select = DP_SELECT_INVALID;
jtag_ap_q_abort(dap, NULL);
@@ -523,7 +546,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
/* move all remaining transactions over to the replay list */
list_for_each_entry_safe_from(el, tmp, &dap->cmd_journal, lh) {
- log_dap_cmd("REP", el);
+ log_dap_cmd(dap, "REP", el);
list_move_tail(&el->lh, &replay_list);
}
@@ -560,8 +583,8 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
retval = adi_jtag_dp_scan_cmd_sync(dap, el, NULL);
if (retval != ERROR_OK)
break;
- log_dap_cmd("REC", el);
- if (el->ack == JTAG_ACK_OK_FAULT) {
+ log_dap_cmd(dap, "REC", el);
+ if (el->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && el->ack == JTAG_ACK_OK)) {
if (el->invalue != el->invalue_buf) {
uint32_t invalue = le_to_h_u32(el->invalue);
memcpy(el->invalue, &invalue, sizeof(uint32_t));
@@ -570,7 +593,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
}
if (el->ack != JTAG_ACK_WAIT) {
LOG_ERROR("Invalid ACK (%1x) in DAP response", el->ack);
- log_dap_cmd("ERR", el);
+ log_dap_cmd(dap, "ERR", el);
retval = ERROR_JTAG_DEVICE_ERROR;
break;
}
@@ -584,7 +607,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap)
} while (timeval_ms() - time_now < 1000);
if (retval == ERROR_OK) {
- if (el->ack != JTAG_ACK_OK_FAULT) {
+ if (el->ack == JTAG_ACK_WAIT) {
LOG_ERROR("Timeout during WAIT recovery");
dap->select = DP_SELECT_INVALID;
jtag_ap_q_abort(dap, NULL);
@@ -640,10 +663,10 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
if (ctrlstat & SSTICKYORUN)
LOG_DEBUG("JTAG-DP STICKY OVERRUN");
- /* Clear Sticky Error Bits */
+ /* Clear Sticky Error and Sticky Overrun Bits */
retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
DP_CTRL_STAT, DPAP_WRITE,
- dap->dp_ctrl_stat | SSTICKYERR, NULL, 0);
+ dap->dp_ctrl_stat | SSTICKYERR | SSTICKYORUN, NULL, 0);
if (retval != ERROR_OK)
goto done;
@@ -722,15 +745,38 @@ static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg,
/** Select the AP register bank matching bits 7:4 of reg. */
static int jtag_ap_q_bankselect(struct adiv5_ap *ap, unsigned reg)
{
+ int retval;
struct adiv5_dap *dap = ap->dap;
- uint32_t sel = ((uint32_t)ap->ap_num << 24) | (reg & 0x000000F0);
+ uint64_t sel;
+
+ if (is_adiv6(dap)) {
+ sel = ap->ap_num | (reg & 0x00000FF0);
+ if (sel == (dap->select & ~0xfull))
+ return ERROR_OK;
+
+ if (dap->select != DP_SELECT_INVALID)
+ sel |= dap->select & 0xf;
+ dap->select = sel;
+ LOG_DEBUG("AP BANKSEL: %" PRIx64, sel);
+
+ retval = jtag_dp_q_write(dap, DP_SELECT, (uint32_t)sel);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (dap->asize > 32)
+ return jtag_dp_q_write(dap, DP_SELECT1, (uint32_t)(sel >> 32));
+ return ERROR_OK;
+ }
+
+ /* ADIv5 */
+ sel = (ap->ap_num << 24) | (reg & 0x000000F0);
if (sel == dap->select)
return ERROR_OK;
dap->select = sel;
- return jtag_dp_q_write(dap, DP_SELECT, sel);
+ return jtag_dp_q_write(dap, DP_SELECT, (uint32_t)sel);
}
static int jtag_ap_q_read(struct adiv5_ap *ap, unsigned reg,
diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c
index 6835042..979c643 100644
--- a/src/target/adi_v5_swd.c
+++ b/src/target/adi_v5_swd.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
*
* Copyright (C) 2010 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
***************************************************************************/
/**
@@ -29,6 +18,7 @@
* for details, see "ARM IHI 0031A"
* ARM Debug Interface v5 Architecture Specification
* especially section 5.3 for SWD protocol
+ * and "ARM IHI 0074C" ARM Debug Interface Architecture Specification ADIv6.0
*
* On many chips (most current Cortex-M3 parts) SWD is a run-time alternative
* to JTAG. Boards may support one or both. There are also SWD-only chips,
@@ -112,20 +102,20 @@ static inline int check_sync(struct adiv5_dap *dap)
/** Select the DP register bank matching bits 7:4 of reg. */
static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned int reg)
{
- /* Only register address 4 is banked. */
- if ((reg & 0xf) != 4)
+ /* Only register address 0 and 4 are banked. */
+ if ((reg & 0xf) > 4)
return ERROR_OK;
- uint32_t select_dp_bank = (reg & 0x000000F0) >> 4;
- uint32_t sel = select_dp_bank
- | (dap->select & (DP_SELECT_APSEL | DP_SELECT_APBANK));
+ uint64_t sel = (reg & 0x000000F0) >> 4;
+ if (dap->select != DP_SELECT_INVALID)
+ sel |= dap->select & ~0xfULL;
if (sel == dap->select)
return ERROR_OK;
dap->select = sel;
- int retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel);
+ int retval = swd_queue_dp_write_inner(dap, DP_SELECT, (uint32_t)sel);
if (retval != ERROR_OK)
dap->select = DP_SELECT_INVALID;
@@ -326,6 +316,21 @@ static int swd_connect_single(struct adiv5_dap *dap)
dap->do_reconnect = false;
dap_invalidate_cache(dap);
+ /* The sequences to enter in SWD (JTAG_TO_SWD and DORMANT_TO_SWD) end
+ * with a SWD line reset sequence (50 clk with SWDIO high).
+ * 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_read_inner(dap, DP_DPIDR, &dpidr);
if (retval == ERROR_OK) {
retval = swd_run_inner(dap);
@@ -337,6 +342,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) {
LOG_ERROR("Error connecting DP: cannot read IDR");
@@ -473,17 +479,42 @@ static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg,
/** Select the AP register bank matching bits 7:4 of reg. */
static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned reg)
{
+ int retval;
struct adiv5_dap *dap = ap->dap;
- uint32_t sel = ((uint32_t)ap->ap_num << 24)
- | (reg & 0x000000F0)
- | (dap->select & DP_SELECT_DPBANK);
+ uint64_t sel;
+
+ if (is_adiv6(dap)) {
+ sel = ap->ap_num | (reg & 0x00000FF0);
+ if (sel == (dap->select & ~0xfULL))
+ return ERROR_OK;
+
+ if (dap->select != DP_SELECT_INVALID)
+ sel |= dap->select & 0xf;
+ dap->select = sel;
+ LOG_DEBUG("AP BANKSEL: %" PRIx64, sel);
+
+ retval = swd_queue_dp_write(dap, DP_SELECT, (uint32_t)sel);
+
+ if (retval == ERROR_OK && dap->asize > 32)
+ retval = swd_queue_dp_write(dap, DP_SELECT1, (uint32_t)(sel >> 32));
+
+ if (retval != ERROR_OK)
+ dap->select = DP_SELECT_INVALID;
+
+ return retval;
+ }
+
+ /* ADIv5 */
+ sel = (ap->ap_num << 24) | (reg & 0x000000F0);
+ if (dap->select != DP_SELECT_INVALID)
+ sel |= dap->select & DP_SELECT_DPBANK;
if (sel == dap->select)
return ERROR_OK;
dap->select = sel;
- int retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel);
+ retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel);
if (retval != ERROR_OK)
dap->select = DP_SELECT_INVALID;
diff --git a/src/target/algorithm.c b/src/target/algorithm.c
index 9fc9386..64abffc 100644
--- a/src/target/algorithm.c
+++ b/src/target/algorithm.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/algorithm.h b/src/target/algorithm.h
index 0fc49d0..25f1a66 100644
--- a/src/target/algorithm.h
+++ b/src/target/algorithm.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ALGORITHM_H
diff --git a/src/target/arc.c b/src/target/arc.c
index 471f16a..9ae3ae6 100644
--- a/src/target/arc.c
+++ b/src/target/arc.c
@@ -1,11 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. *
* Frank Dols <frank.dols@synopsys.com> *
* Mischa Jonker <mischa.jonker@synopsys.com> *
* Anton Kolesov <anton.kolesov@synopsys.com> *
* Evgeniy Didin <didin@synopsys.com> *
- * *
- * SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
@@ -93,7 +93,7 @@ struct reg *arc_reg_get_by_name(struct reg_cache *first,
*
* @param target Target for which to reset caches states.
*/
-int arc_reset_caches_states(struct target *target)
+static int arc_reset_caches_states(struct target *target)
{
struct arc_common *arc = target_to_arc(target);
@@ -283,7 +283,7 @@ static int arc_set_register(struct reg *reg, uint8_t *buf)
return ERROR_OK;
}
-const struct reg_arch_type arc_reg_type = {
+static const struct reg_arch_type arc_reg_type = {
.get = arc_get_register,
.set = arc_set_register,
};
@@ -1401,7 +1401,7 @@ static int arc_target_create(struct target *target, Jim_Interp *interp)
* little endian, so different type of conversion should be done.
* Middle endian: instruction "aabbccdd", stored as "bbaaddcc"
*/
-int arc_write_instruction_u32(struct target *target, uint32_t address,
+static int arc_write_instruction_u32(struct target *target, uint32_t address,
uint32_t instr)
{
uint8_t value_buf[4];
@@ -1428,7 +1428,7 @@ int arc_write_instruction_u32(struct target *target, uint32_t address,
* case of little endian ARC instructions are in middle endian format, so
* different type of conversion should be done.
*/
-int arc_read_instruction_u32(struct target *target, uint32_t address,
+static int arc_read_instruction_u32(struct target *target, uint32_t address,
uint32_t *value)
{
uint8_t value_buf[4];
@@ -1694,7 +1694,7 @@ static int arc_remove_breakpoint(struct target *target,
return ERROR_OK;
}
-void arc_reset_actionpoints(struct target *target)
+static void arc_reset_actionpoints(struct target *target)
{
struct arc_common *arc = target_to_arc(target);
struct arc_actionpoint *ap_list = arc->actionpoints_list;
@@ -1965,7 +1965,7 @@ static int arc_hit_watchpoint(struct target *target, struct watchpoint **hit_wat
/* Helper function which switches core to single_step mode by
* doing aux r/w operations. */
-int arc_config_step(struct target *target, int enable_step)
+static int arc_config_step(struct target *target, int enable_step)
{
uint32_t value;
@@ -2001,7 +2001,7 @@ int arc_config_step(struct target *target, int enable_step)
return ERROR_OK;
}
-int arc_step(struct target *target, int current, target_addr_t address,
+static int arc_step(struct target *target, int current, target_addr_t address,
int handle_breakpoints)
{
/* get pointers to arch-specific information */
@@ -2165,7 +2165,7 @@ int arc_cache_invalidate(struct target *target)
* values directly from memory, bypassing cache, so if there are unflushed
* lines debugger will read invalid values, which will cause a lot of troubles.
* */
-int arc_dcache_flush(struct target *target)
+static int arc_dcache_flush(struct target *target)
{
uint32_t value, dc_ctrl_value;
bool has_to_set_dc_ctrl_im;
diff --git a/src/target/arc.h b/src/target/arc.h
index f0351bd..bb70a59 100644
--- a/src/target/arc.h
+++ b/src/target/arc.h
@@ -1,11 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. *
* Frank Dols <frank.dols@synopsys.com> *
* Mischa Jonker <mischa.jonker@synopsys.com> *
* Anton Kolesov <anton.kolesov@synopsys.com> *
* Evgeniy Didin <didin@synopsys.com> *
- * *
- * SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARC_H
@@ -27,7 +27,7 @@
#include "arc_cmd.h"
#include "arc_mem.h"
-#define ARC_COMMON_MAGIC 0xB32EB324 /* just a unique number */
+#define ARC_COMMON_MAGIC 0xB32EB324U /* just a unique number */
#define AUX_DEBUG_REG 0x5
#define AUX_PC_REG 0x6
@@ -183,7 +183,7 @@ struct arc_actionpoint {
};
struct arc_common {
- uint32_t common_magic;
+ unsigned int common_magic;
struct arc_jtag jtag_info;
diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c
index 26c67c6..7a80046 100644
--- a/src/target/arc_cmd.c
+++ b/src/target/arc_cmd.c
@@ -1,11 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. *
* Frank Dols <frank.dols@synopsys.com> *
* Mischa Jonker <mischa.jonker@synopsys.com> *
* Anton Kolesov <anton.kolesov@synopsys.com> *
* Evgeniy Didin <didin@synopsys.com> *
- * *
- * SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -975,7 +975,7 @@ static int jim_handle_actionpoints_num(Jim_Interp *interp, int argc,
/* ----- Exported target commands ------------------------------------------ */
-const struct command_registration arc_l2_cache_group_handlers[] = {
+static const struct command_registration arc_l2_cache_group_handlers[] = {
{
.name = "auto",
.handler = arc_l2_cache_disable_auto_cmd,
@@ -986,7 +986,7 @@ const struct command_registration arc_l2_cache_group_handlers[] = {
COMMAND_REGISTRATION_DONE
};
-const struct command_registration arc_cache_group_handlers[] = {
+static const struct command_registration arc_cache_group_handlers[] = {
{
.name = "auto",
.handler = arc_l1_cache_disable_auto_cmd,
diff --git a/src/target/arc_cmd.h b/src/target/arc_cmd.h
index b2264eb..f728bd5 100644
--- a/src/target/arc_cmd.h
+++ b/src/target/arc_cmd.h
@@ -1,11 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. *
* Frank Dols <frank.dols@synopsys.com> *
* Mischa Jonker <mischa.jonker@synopsys.com> *
* Anton Kolesov <anton.kolesov@synopsys.com> *
* Evgeniy Didin <didin@synopsys.com> *
- * *
- * SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARC_CMD_H
diff --git a/src/target/arc_jtag.c b/src/target/arc_jtag.c
index ca1a096..ddb4f62 100644
--- a/src/target/arc_jtag.c
+++ b/src/target/arc_jtag.c
@@ -1,11 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. *
* Frank Dols <frank.dols@synopsys.com> *
* Mischa Jonker <mischa.jonker@synopsys.com> *
* Anton Kolesov <anton.kolesov@synopsys.com> *
* Evgeniy Didin <didin@synopsys.com> *
- * *
- * SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arc_jtag.h b/src/target/arc_jtag.h
index 99795f5..c2dc7b7 100644
--- a/src/target/arc_jtag.h
+++ b/src/target/arc_jtag.h
@@ -1,11 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. *
* Frank Dols <frank.dols@synopsys.com> *
* Mischa Jonker <mischa.jonker@synopsys.com> *
* Anton Kolesov <anton.kolesov@synopsys.com> *
* Evgeniy Didin <didin@synopsys.com> *
- * *
- * SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARC_JTAG_H
diff --git a/src/target/arc_mem.c b/src/target/arc_mem.c
index 81d1ab2..c4814d2 100644
--- a/src/target/arc_mem.c
+++ b/src/target/arc_mem.c
@@ -1,11 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. *
* Frank Dols <frank.dols@synopsys.com> *
* Mischa Jonker <mischa.jonker@synopsys.com> *
* Anton Kolesov <anton.kolesov@synopsys.com> *
* Evgeniy Didin <didin@synopsys.com> *
- * *
- * SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arc_mem.h b/src/target/arc_mem.h
index 06e1c88..861823d 100644
--- a/src/target/arc_mem.h
+++ b/src/target/arc_mem.h
@@ -1,10 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. *
* Frank Dols <frank.dols@synopsys.com> *
* Anton Kolesov <anton.kolesov@synopsys.com> *
* Evgeniy Didin <didin@synopsys.com> *
- * *
- * SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARC_MEM_H
diff --git a/src/target/arm.h b/src/target/arm.h
index 1732789..de46ffb 100644
--- a/src/target/arm.h
+++ b/src/target/arm.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (C) 2005 by Dominic Rath
* Dominic.Rath@gmx.de
@@ -10,19 +12,6 @@
*
* Copyright (C) 2018 by Liviu Ionescu
* <ilg@livius.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENOCD_TARGET_ARM_H
@@ -166,7 +155,7 @@ enum arm_vfp_version {
ARM_VFP_V3,
};
-#define ARM_COMMON_MAGIC 0x0A450A45
+#define ARM_COMMON_MAGIC 0x0A450A45U
/**
* Represents a generic ARM core, with standard application registers.
@@ -176,7 +165,8 @@ enum arm_vfp_version {
* registers as traditional ARM cores, and only support Thumb2 instructions.
*/
struct arm {
- int common_magic;
+ unsigned int common_magic;
+
struct reg_cache *core_cache;
/** Handle to the PC; valid in all core modes. */
@@ -263,7 +253,7 @@ static inline bool is_arm(struct arm *arm)
}
struct arm_algorithm {
- int common_magic;
+ unsigned int common_magic;
enum arm_mode core_mode;
enum arm_state core_state;
@@ -283,6 +273,7 @@ void arm_free_reg_cache(struct arm *arm);
struct reg_cache *armv8_build_reg_cache(struct target *target);
extern const struct command_registration arm_command_handlers[];
+extern const struct command_registration arm_all_profiles_command_handlers[];
int arm_arch_state(struct target *target);
const char *arm_get_gdb_arch(struct target *target);
@@ -319,7 +310,4 @@ void arm_set_cpsr(struct arm *arm, uint32_t cpsr);
struct reg *arm_reg_current(struct arm *arm, unsigned regnum);
struct reg *armv8_reg_current(struct arm *arm, unsigned regnum);
-extern struct reg arm_gdb_dummy_fp_reg;
-extern struct reg arm_gdb_dummy_fps_reg;
-
#endif /* OPENOCD_TARGET_ARM_H */
diff --git a/src/target/arm11.c b/src/target/arm11.c
index e3b0975..e48bcf3 100644
--- a/src/target/arm11.c
+++ b/src/target/arm11.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 digenius technology GmbH. *
* Michael Bruck *
@@ -7,19 +9,6 @@
* Copyright (C) 2008 Georg Acher <acher@in.tum.de> *
* *
* Copyright (C) 2009 David Brownell *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm11.h b/src/target/arm11.h
index 77cc223..1f56f7b 100644
--- a/src/target/arm11.h
+++ b/src/target/arm11.h
@@ -1,21 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 digenius technology GmbH. *
* Michael Bruck *
* *
* Copyright (C) 2008 Georg Acher <acher@in.tum.de> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM11_H
diff --git a/src/target/arm11_dbgtap.c b/src/target/arm11_dbgtap.c
index fc35414..b670bd7 100644
--- a/src/target/arm11_dbgtap.c
+++ b/src/target/arm11_dbgtap.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 digenius technology GmbH. *
* Michael Bruck *
* *
* Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm11_dbgtap.h b/src/target/arm11_dbgtap.h
index c6b20a8..eeb174a 100644
--- a/src/target/arm11_dbgtap.h
+++ b/src/target/arm11_dbgtap.h
@@ -1,21 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 digenius technology GmbH. *
* Michael Bruck *
* *
* Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM11_DBGTAP_H
diff --git a/src/target/arm720t.c b/src/target/arm720t.c
index db75011..c330dff 100644
--- a/src/target/arm720t.c
+++ b/src/target/arm720t.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2009 by Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm720t.h b/src/target/arm720t.h
index 31dad9c..65bd78f 100644
--- a/src/target/arm720t.h
+++ b/src/target/arm720t.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM720T_H
@@ -22,11 +11,12 @@
#include "arm7tdmi.h"
#include "armv4_5_mmu.h"
-#define ARM720T_COMMON_MAGIC 0xa720a720
+#define ARM720T_COMMON_MAGIC 0xa720a720U
struct arm720t_common {
+ unsigned int common_magic;
+
struct arm7_9_common arm7_9_common;
- uint32_t common_magic;
struct armv4_5_mmu_common armv4_5_mmu;
uint32_t cp15_control_reg;
uint32_t fsr_reg;
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index da047c3..8f87d9c 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -12,19 +14,6 @@
* hontor@126.com *
* *
* Copyright (C) 2009 by David Brownell *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h
index 4961212..92d0fd5 100644
--- a/src/target/arm7_9_common.h
+++ b/src/target/arm7_9_common.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2008 by Hongtao Zheng *
* hontor@126.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM7_9_COMMON_H
@@ -31,14 +20,15 @@
#include "arm.h"
#include "arm_jtag.h"
-#define ARM7_9_COMMON_MAGIC 0x0a790a79 /**< */
+#define ARM7_9_COMMON_MAGIC 0x0a790a79U /**< */
/**
* Structure for items that are common between both ARM7 and ARM9 targets.
*/
struct arm7_9_common {
+ unsigned int common_magic;
+
struct arm arm;
- uint32_t common_magic;
struct arm_jtag jtag_info; /**< JTAG information for target */
struct reg_cache *eice_cache; /**< Embedded ICE register cache */
diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c
index b034839..393d3b4 100644
--- a/src/target/arm7tdmi.c
+++ b/src/target/arm7tdmi.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm7tdmi.h b/src/target/arm7tdmi.h
index 3cc3d4a..369a514 100644
--- a/src/target/arm7tdmi.h
+++ b/src/target/arm7tdmi.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM7TDMI_H
diff --git a/src/target/arm920t.c b/src/target/arm920t.c
index a6d626e..f4c3f42 100644
--- a/src/target/arm920t.c
+++ b/src/target/arm920t.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm920t.h b/src/target/arm920t.h
index 2e3b08c..eba768f 100644
--- a/src/target/arm920t.h
+++ b/src/target/arm920t.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM920T_H
@@ -22,11 +11,12 @@
#include "arm9tdmi.h"
#include "armv4_5_mmu.h"
-#define ARM920T_COMMON_MAGIC 0xa920a920
+#define ARM920T_COMMON_MAGIC 0xa920a920U
struct arm920t_common {
+ unsigned int common_magic;
+
struct arm7_9_common arm7_9_common;
- uint32_t common_magic;
struct armv4_5_mmu_common armv4_5_mmu;
uint32_t cp15_control_reg;
uint32_t d_fsr;
diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c
index ea0927b..807d211 100644
--- a/src/target/arm926ejs.c
+++ b/src/target/arm926ejs.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008,2009 by Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm926ejs.h b/src/target/arm926ejs.h
index 0cd523a..479128e 100644
--- a/src/target/arm926ejs.h
+++ b/src/target/arm926ejs.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM926EJS_H
@@ -22,11 +11,12 @@
#include "arm9tdmi.h"
#include "armv4_5_mmu.h"
-#define ARM926EJS_COMMON_MAGIC 0xa926a926
+#define ARM926EJS_COMMON_MAGIC 0xa926a926U
struct arm926ejs_common {
+ unsigned int common_magic;
+
struct arm7_9_common arm7_9_common;
- uint32_t common_magic;
struct armv4_5_mmu_common armv4_5_mmu;
int (*read_cp15)(struct target *target, uint32_t op1, uint32_t op2,
uint32_t crn, uint32_t crm, uint32_t *value);
diff --git a/src/target/arm946e.c b/src/target/arm946e.c
index 036e8ba..06dab4e 100644
--- a/src/target/arm946e.c
+++ b/src/target/arm946e.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2010 by Drasko DRASKOVIC *
* drasko.draskovic@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -55,7 +44,7 @@ static int arm946e_post_debug_entry(struct target *target);
static void arm946e_pre_restore_context(struct target *target);
static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value);
-int arm946e_init_arch_info(struct target *target,
+static int arm946e_init_arch_info(struct target *target,
struct arm946e_common *arm946e,
struct jtag_tap *tap)
{
@@ -184,7 +173,7 @@ static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *valu
return ERROR_OK;
}
-int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value)
+static int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value)
{
int retval = ERROR_OK;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
@@ -731,7 +720,7 @@ static const struct command_registration arm946e_exec_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
-const struct command_registration arm946e_command_handlers[] = {
+static const struct command_registration arm946e_command_handlers[] = {
{
.chain = arm9tdmi_command_handlers,
},
diff --git a/src/target/arm946e.h b/src/target/arm946e.h
index ee1ef32..0196c2b 100644
--- a/src/target/arm946e.h
+++ b/src/target/arm946e.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2010 by Drasko DRASKOVIC *
* drasko.draskovic@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM946E_H
@@ -27,11 +16,12 @@
#include "arm9tdmi.h"
-#define ARM946E_COMMON_MAGIC 0x20f920f9
+#define ARM946E_COMMON_MAGIC 0x20f920f9U
struct arm946e_common {
+ unsigned int common_magic;
+
struct arm7_9_common arm7_9_common;
- int common_magic;
uint32_t cp15_control_reg;
uint32_t cp15_cache_info;
};
@@ -42,10 +32,4 @@ static inline struct arm946e_common *target_to_arm946(struct target *target)
arm7_9_common.arm);
}
-int arm946e_init_arch_info(struct target *target,
- struct arm946e_common *arm946e, struct jtag_tap *tap);
-int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value);
-
-extern const struct command_registration arm946e_command_handlers[];
-
#endif /* OPENOCD_TARGET_ARM946E_H */
diff --git a/src/target/arm966e.c b/src/target/arm966e.c
index b6d3e50..3e60172 100644
--- a/src/target/arm966e.c
+++ b/src/target/arm966e.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm966e.h b/src/target/arm966e.h
index aa2e9bb..be2b339 100644
--- a/src/target/arm966e.h
+++ b/src/target/arm966e.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM966E_H
@@ -24,11 +13,12 @@
#include "arm9tdmi.h"
-#define ARM966E_COMMON_MAGIC 0x20f920f9
+#define ARM966E_COMMON_MAGIC 0x20f920f9U
struct arm966e_common {
+ unsigned int common_magic;
+
struct arm7_9_common arm7_9_common;
- int common_magic;
uint32_t cp15_control_reg;
};
diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c
index 2a32f11..805330f 100644
--- a/src/target/arm9tdmi.c
+++ b/src/target/arm9tdmi.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Hongtao Zheng *
* hontor@126.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm9tdmi.h b/src/target/arm9tdmi.h
index 56946f7..d2a2784 100644
--- a/src/target/arm9tdmi.h
+++ b/src/target/arm9tdmi.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM9TDMI_H
diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index 4d5f02b..c446428 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Magnus Lundin *
* lundin@mlu.mine.nu *
@@ -14,19 +16,6 @@
* andreas.fritiofson@gmail.com *
* *
* Copyright (C) 2019-2021, Ampere Computing LLC *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
@@ -107,7 +96,7 @@ static int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t csw)
if (csw != ap->csw_value) {
/* LOG_DEBUG("DAP: Set CSW %x",csw); */
- int retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW, csw);
+ int retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW(ap->dap), csw);
if (retval != ERROR_OK) {
ap->csw_value = 0;
return retval;
@@ -121,11 +110,11 @@ static int mem_ap_setup_tar(struct adiv5_ap *ap, target_addr_t tar)
{
if (!ap->tar_valid || tar != ap->tar_value) {
/* LOG_DEBUG("DAP: Set TAR %x",tar); */
- int retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR, (uint32_t)(tar & 0xffffffffUL));
+ 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))
- retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR64, (uint32_t)(tar >> 32));
+ retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR64(ap->dap), (uint32_t)(tar >> 32));
}
if (retval != ERROR_OK) {
ap->tar_valid = false;
@@ -142,9 +131,9 @@ static int mem_ap_read_tar(struct adiv5_ap *ap, target_addr_t *tar)
uint32_t lower;
uint32_t upper = 0;
- int retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR, &lower);
+ int retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR(ap->dap), &lower);
if (retval == ERROR_OK && is_64bit_ap(ap))
- retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR64, &upper);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR64(ap->dap), &upper);
if (retval != ERROR_OK) {
ap->tar_valid = false;
@@ -252,7 +241,7 @@ int mem_ap_read_u32(struct adiv5_ap *ap, target_addr_t address,
if (retval != ERROR_OK)
return retval;
- return dap_queue_ap_read(ap, MEM_AP_REG_BD0 | (address & 0xC), value);
+ return dap_queue_ap_read(ap, MEM_AP_REG_BD0(ap->dap) | (address & 0xC), value);
}
/**
@@ -304,7 +293,7 @@ int mem_ap_write_u32(struct adiv5_ap *ap, target_addr_t address,
if (retval != ERROR_OK)
return retval;
- return dap_queue_ap_write(ap, MEM_AP_REG_BD0 | (address & 0xC),
+ return dap_queue_ap_write(ap, MEM_AP_REG_BD0(ap->dap) | (address & 0xC),
value);
}
@@ -420,6 +409,26 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz
outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (drw_byte_idx & 3) ^ addr_xor);
break;
}
+ } else if (dap->nu_npcx_quirks) {
+ switch (this_size) {
+ case 4:
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);
+ break;
+ case 2:
+ outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*(buffer+1) << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);
+ break;
+ case 1:
+ outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);
+ }
} else {
switch (this_size) {
case 4:
@@ -436,7 +445,7 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz
nbytes -= this_size;
- retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW, outvalue);
+ retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW(dap), outvalue);
if (retval != ERROR_OK)
break;
@@ -533,7 +542,7 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint
if (retval != ERROR_OK)
break;
- retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW, read_ptr++);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW(dap), read_ptr++);
if (retval != ERROR_OK)
break;
@@ -780,7 +789,7 @@ int mem_ap_init(struct adiv5_ap *ap)
/* Set ap->cfg_reg before calling mem_ap_setup_transfer(). */
/* mem_ap_setup_transfer() needs to know if the MEM_AP supports LPAE. */
- retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &cfg);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG(dap), &cfg);
if (retval != ERROR_OK)
return retval;
@@ -795,7 +804,7 @@ int mem_ap_init(struct adiv5_ap *ap)
if (retval != ERROR_OK)
return retval;
- retval = dap_queue_ap_read(ap, MEM_AP_REG_CSW, &csw);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_CSW(dap), &csw);
if (retval != ERROR_OK)
return retval;
@@ -928,7 +937,9 @@ static const struct {
};
#define DEVARCH_ID_MASK (ARM_CS_C9_DEVARCH_ARCHITECT_MASK | ARM_CS_C9_DEVARCH_ARCHID_MASK)
+#define DEVARCH_MEM_AP ARCH_ID(ARM_ID, 0x0A17)
#define DEVARCH_ROM_C_0X9 ARCH_ID(ARM_ID, 0x0AF7)
+#define DEVARCH_UNKNOWN_V2 ARCH_ID(ARM_ID, 0x0A47)
static const char *class0x9_devarch_description(uint32_t devarch)
{
@@ -966,22 +977,57 @@ static const char *ap_type_to_description(enum ap_type type)
return "Unknown";
}
+bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num)
+{
+ if (!dap)
+ return false;
+
+ /* no autodetection, by now, so uninitialized is equivalent to ADIv5 for
+ * backward compatibility */
+ if (!is_adiv6(dap)) {
+ if (ap_num > DP_APSEL_MAX)
+ return false;
+ return true;
+ }
+
+ if (is_adiv6(dap)) {
+ if (ap_num & 0x0fffULL)
+ return false;
+ if (dap->asize != 0)
+ if (ap_num & ((~0ULL) << dap->asize))
+ return false;
+ return true;
+ }
+
+ return false;
+}
+
/*
* This function checks the ID for each access port to find the requested Access Port type
+ * It also calls dap_get_ap() to increment the AP refcount
*/
-int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out)
+int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out)
{
- int ap_num;
+ if (is_adiv6(dap)) {
+ /* TODO: scan the ROM table and detect the AP available */
+ LOG_DEBUG("On ADIv6 we cannot scan all the possible AP");
+ return ERROR_FAIL;
+ }
/* Maximum AP number is 255 since the SELECT register is 8 bits */
- for (ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) {
+ for (unsigned int ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) {
+ struct adiv5_ap *ap = dap_get_ap(dap, ap_num);
+ if (!ap)
+ continue;
/* read the IDR register of the Access Port */
uint32_t id_val = 0;
- int retval = dap_queue_ap_read(dap_ap(dap, ap_num), AP_REG_IDR, &id_val);
- if (retval != ERROR_OK)
+ int retval = dap_queue_ap_read(ap, AP_REG_IDR(dap), &id_val);
+ if (retval != ERROR_OK) {
+ dap_put_ap(ap);
return retval;
+ }
retval = dap_run(dap);
@@ -993,15 +1039,96 @@ int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_a
ap_type_to_description(type_to_find),
ap_num, id_val);
- *ap_out = &dap->ap[ap_num];
+ *ap_out = ap;
return ERROR_OK;
}
+ dap_put_ap(ap);
}
LOG_DEBUG("No %s found", ap_type_to_description(type_to_find));
return ERROR_FAIL;
}
+static inline bool is_ap_in_use(struct adiv5_ap *ap)
+{
+ return ap->refcount > 0 || ap->config_ap_never_release;
+}
+
+static struct adiv5_ap *_dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)
+{
+ if (!is_ap_num_valid(dap, ap_num)) {
+ LOG_ERROR("Invalid AP#0x%" PRIx64, ap_num);
+ return NULL;
+ }
+ if (is_adiv6(dap)) {
+ for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {
+ struct adiv5_ap *ap = &dap->ap[i];
+ if (is_ap_in_use(ap) && ap->ap_num == ap_num) {
+ ++ap->refcount;
+ return ap;
+ }
+ }
+ for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {
+ struct adiv5_ap *ap = &dap->ap[i];
+ if (!is_ap_in_use(ap)) {
+ ap->ap_num = ap_num;
+ ++ap->refcount;
+ return ap;
+ }
+ }
+ LOG_ERROR("No more AP available!");
+ return NULL;
+ }
+
+ /* ADIv5 */
+ struct adiv5_ap *ap = &dap->ap[ap_num];
+ ap->ap_num = ap_num;
+ ++ap->refcount;
+ return ap;
+}
+
+/* Return AP with specified ap_num. Increment AP refcount */
+struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)
+{
+ struct adiv5_ap *ap = _dap_get_ap(dap, ap_num);
+ if (ap)
+ LOG_DEBUG("refcount AP#0x%" PRIx64 " get %u", ap_num, ap->refcount);
+ return ap;
+}
+
+/* Return AP with specified ap_num. Increment AP refcount and keep it non-zero */
+struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num)
+{
+ struct adiv5_ap *ap = _dap_get_ap(dap, ap_num);
+ if (ap) {
+ ap->config_ap_never_release = true;
+ LOG_DEBUG("refcount AP#0x%" PRIx64 " get_config %u", ap_num, ap->refcount);
+ }
+ return ap;
+}
+
+/* Decrement AP refcount and release the AP when refcount reaches zero */
+int dap_put_ap(struct adiv5_ap *ap)
+{
+ if (ap->refcount == 0) {
+ LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " put underflow", ap->ap_num);
+ return ERROR_FAIL;
+ }
+
+ --ap->refcount;
+
+ LOG_DEBUG("refcount AP#0x%" PRIx64 " put %u", ap->ap_num, ap->refcount);
+ if (!is_ap_in_use(ap)) {
+ /* defaults from dap_instance_init() */
+ ap->ap_num = DP_APSEL_INVALID;
+ ap->memaccess_tck = 255;
+ ap->tar_autoincr_block = (1 << 10);
+ ap->csw_default = CSW_AHB_DEFAULT;
+ ap->cfg_reg = MEM_AP_REG_CFG_INVALID;
+ }
+ return ERROR_OK;
+}
+
static int dap_get_debugbase(struct adiv5_ap *ap,
target_addr_t *dbgbase, uint32_t *apid)
{
@@ -1010,19 +1137,19 @@ static int dap_get_debugbase(struct adiv5_ap *ap,
uint32_t baseptr_upper, baseptr_lower;
if (ap->cfg_reg == MEM_AP_REG_CFG_INVALID) {
- retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &ap->cfg_reg);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG(dap), &ap->cfg_reg);
if (retval != ERROR_OK)
return retval;
}
- retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseptr_lower);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE(dap), &baseptr_lower);
if (retval != ERROR_OK)
return retval;
- retval = dap_queue_ap_read(ap, AP_REG_IDR, apid);
+ retval = dap_queue_ap_read(ap, AP_REG_IDR(dap), apid);
if (retval != ERROR_OK)
return retval;
/* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then ignored on 32 bits AP */
if (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || is_64bit_ap(ap)) {
- retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, &baseptr_upper);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64(dap), &baseptr_upper);
if (retval != ERROR_OK)
return retval;
}
@@ -1038,6 +1165,43 @@ static int dap_get_debugbase(struct adiv5_ap *ap,
return ERROR_OK;
}
+int adiv6_dap_read_baseptr(struct command_invocation *cmd, struct adiv5_dap *dap, uint64_t *baseptr)
+{
+ uint32_t baseptr_lower, baseptr_upper = 0;
+ int retval;
+
+ if (dap->asize > 32) {
+ retval = dap_queue_dp_read(dap, DP_BASEPTR1, &baseptr_upper);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ retval = dap_dp_read_atomic(dap, DP_BASEPTR0, &baseptr_lower);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if ((baseptr_lower & DP_BASEPTR0_VALID) != DP_BASEPTR0_VALID) {
+ command_print(cmd, "System root table not present");
+ return ERROR_FAIL;
+ }
+
+ baseptr_lower &= ~0x0fff;
+ *baseptr = (((uint64_t)baseptr_upper) << 32) | baseptr_lower;
+
+ return ERROR_OK;
+}
+
+/**
+ * Method to access the CoreSight component.
+ * On ADIv5, CoreSight components are on the bus behind a MEM-AP.
+ * On ADIv6, CoreSight components can either be on the bus behind a MEM-AP
+ * or directly in the AP.
+ */
+enum coresight_access_mode {
+ CS_ACCESS_AP,
+ CS_ACCESS_MEM_AP,
+};
+
/** Holds registers and coordinates of a CoreSight component */
struct cs_component_vals {
struct adiv5_ap *ap;
@@ -1047,19 +1211,43 @@ struct cs_component_vals {
uint32_t devarch;
uint32_t devid;
uint32_t devtype_memtype;
+ enum coresight_access_mode mode;
};
/**
+ * Helper to read CoreSight component's registers, either on the bus
+ * behind a MEM-AP or directly in the AP.
+ *
+ * @param mode Method to access the component (AP or MEM-AP).
+ * @param ap Pointer to AP containing the component.
+ * @param component_base On MEM-AP access method, base address of the component.
+ * @param reg Offset of the component's register to read.
+ * @param value Pointer to the store the read value.
+ *
+ * @return ERROR_OK on success, else a fault code.
+ */
+static int dap_queue_read_reg(enum coresight_access_mode mode, struct adiv5_ap *ap,
+ uint64_t component_base, unsigned int reg, uint32_t *value)
+{
+ if (mode == CS_ACCESS_AP)
+ return dap_queue_ap_read(ap, reg, value);
+
+ /* mode == CS_ACCESS_MEM_AP */
+ return mem_ap_read_u32(ap, component_base + reg, value);
+}
+
+/**
* Read the CoreSight registers needed during ROM Table Parsing (RTP).
*
+ * @param mode Method to access the component (AP or MEM-AP).
* @param ap Pointer to AP containing the component.
* @param component_base On MEM-AP access method, base address of the component.
* @param v Pointer to the struct holding the value of registers.
*
* @return ERROR_OK on success, else a fault code.
*/
-static int rtp_read_cs_regs(struct adiv5_ap *ap, target_addr_t component_base,
- struct cs_component_vals *v)
+static int rtp_read_cs_regs(enum coresight_access_mode mode, struct adiv5_ap *ap,
+ target_addr_t component_base, struct cs_component_vals *v)
{
assert(IS_ALIGNED(component_base, ARM_CS_ALIGN));
assert(ap && v);
@@ -1070,6 +1258,7 @@ static int rtp_read_cs_regs(struct adiv5_ap *ap, target_addr_t component_base,
v->ap = ap;
v->component_base = component_base;
+ v->mode = mode;
/* sort by offset to gain speed */
@@ -1079,35 +1268,35 @@ static int rtp_read_cs_regs(struct adiv5_ap *ap, target_addr_t component_base,
* without triggering error. Read them for eventual use on Class 0x9.
*/
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_C9_DEVARCH, &v->devarch);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_C9_DEVARCH, &v->devarch);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_C9_DEVID, &v->devid);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_C9_DEVID, &v->devid);
/* Same address as ARM_CS_C1_MEMTYPE */
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_C9_DEVTYPE, &v->devtype_memtype);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_C9_DEVTYPE, &v->devtype_memtype);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR4, &pid4);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR4, &pid4);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR0, &pid0);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR0, &pid0);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR1, &pid1);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR1, &pid1);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR2, &pid2);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR2, &pid2);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_PIDR3, &pid3);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR3, &pid3);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_CIDR0, &cid0);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR0, &cid0);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_CIDR1, &cid1);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR1, &cid1);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_CIDR2, &cid2);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR2, &cid2);
if (retval == ERROR_OK)
- retval = mem_ap_read_u32(ap, component_base + ARM_CS_CIDR3, &cid3);
+ retval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR3, &cid3);
if (retval == ERROR_OK)
retval = dap_run(ap->dap);
@@ -1431,16 +1620,25 @@ static int dap_devtype_display(struct command_invocation *cmd, uint32_t devtype)
*/
struct rtp_ops {
/**
+ * Executed at the start of a new AP, typically to print the AP header.
+ * @param ap Pointer to AP.
+ * @param depth The current depth level of ROM table.
+ * @param priv Pointer to private data.
+ * @return ERROR_OK on success, else a fault code.
+ */
+ int (*ap_header)(struct adiv5_ap *ap, int depth, void *priv);
+ /**
* Executed at the start of a new MEM-AP, typically to print the MEM-AP header.
* @param retval Error encountered while reading AP.
* @param ap Pointer to AP.
* @param dbgbase Value of MEM-AP Debug Base Address register.
* @param apid Value of MEM-AP IDR Identification Register.
+ * @param depth The current depth level of ROM table.
* @param priv Pointer to private data.
* @return ERROR_OK on success, else a fault code.
*/
int (*mem_ap_header)(int retval, struct adiv5_ap *ap, uint64_t dbgbase,
- uint32_t apid, void *priv);
+ uint32_t apid, int depth, void *priv);
/**
* Executed when a CoreSight component is parsed, typically to print
* information on the component.
@@ -1470,16 +1668,28 @@ struct rtp_ops {
};
/**
+ * Wrapper around struct rtp_ops::ap_header.
+ */
+static int rtp_ops_ap_header(const struct rtp_ops *ops,
+ struct adiv5_ap *ap, int depth)
+{
+ if (ops->ap_header)
+ return ops->ap_header(ap, depth, ops->priv);
+
+ return ERROR_OK;
+}
+
+/**
* Wrapper around struct rtp_ops::mem_ap_header.
* Input parameter @a retval is propagated.
*/
static int rtp_ops_mem_ap_header(const struct rtp_ops *ops,
- int retval, struct adiv5_ap *ap, uint64_t dbgbase, uint32_t apid)
+ int retval, struct adiv5_ap *ap, uint64_t dbgbase, uint32_t apid, int depth)
{
if (!ops->mem_ap_header)
return retval;
- int retval1 = ops->mem_ap_header(retval, ap, dbgbase, apid, ops->priv);
+ int retval1 = ops->mem_ap_header(retval, ap, dbgbase, apid, depth, ops->priv);
if (retval != ERROR_OK)
return retval;
return retval1;
@@ -1528,13 +1738,18 @@ static int rtp_ops_rom_table_entry(const struct rtp_ops *ops,
*/
#define CORESIGHT_COMPONENT_FOUND (1)
-static int rtp_cs_component(const struct rtp_ops *ops,
- struct adiv5_ap *ap, target_addr_t dbgbase, int depth);
+static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap, int depth);
+static int rtp_cs_component(enum coresight_access_mode mode, const struct rtp_ops *ops,
+ struct adiv5_ap *ap, target_addr_t dbgbase, bool *is_mem_ap, int depth);
-static int rtp_rom_loop(const struct rtp_ops *ops,
+static int rtp_rom_loop(enum coresight_access_mode mode, const struct rtp_ops *ops,
struct adiv5_ap *ap, target_addr_t base_address, int depth,
unsigned int width, unsigned int max_entries)
{
+ /* ADIv6 AP ROM table provide offset from current AP */
+ if (mode == CS_ACCESS_AP)
+ base_address = ap->ap_num;
+
assert(IS_ALIGNED(base_address, ARM_CS_ALIGN));
unsigned int offset = 0;
@@ -1544,10 +1759,10 @@ static int rtp_rom_loop(const struct rtp_ops *ops,
target_addr_t component_base;
unsigned int saved_offset = offset;
- int retval = mem_ap_read_u32(ap, base_address + offset, &romentry_low);
+ int retval = dap_queue_read_reg(mode, ap, base_address, offset, &romentry_low);
offset += 4;
if (retval == ERROR_OK && width == 64) {
- retval = mem_ap_read_u32(ap, base_address + offset, &romentry_high);
+ retval = dap_queue_read_reg(mode, ap, base_address, offset, &romentry_high);
offset += 4;
}
if (retval == ERROR_OK)
@@ -1581,7 +1796,18 @@ static int rtp_rom_loop(const struct rtp_ops *ops,
continue;
/* Recurse */
- retval = rtp_cs_component(ops, ap, component_base, depth + 1);
+ if (mode == CS_ACCESS_AP) {
+ struct adiv5_ap *next_ap = dap_get_ap(ap->dap, component_base);
+ if (!next_ap) {
+ LOG_DEBUG("Wrong AP # 0x%" PRIx64, component_base);
+ continue;
+ }
+ retval = rtp_ap(ops, next_ap, depth + 1);
+ dap_put_ap(next_ap);
+ } else {
+ /* mode == CS_ACCESS_MEM_AP */
+ retval = rtp_cs_component(mode, ops, ap, component_base, NULL, depth + 1);
+ }
if (retval == CORESIGHT_COMPONENT_FOUND)
return CORESIGHT_COMPONENT_FOUND;
if (retval != ERROR_OK) {
@@ -1594,18 +1820,21 @@ static int rtp_rom_loop(const struct rtp_ops *ops,
return ERROR_OK;
}
-static int rtp_cs_component(const struct rtp_ops *ops,
- struct adiv5_ap *ap, target_addr_t base_address, int depth)
+static int rtp_cs_component(enum coresight_access_mode mode, const struct rtp_ops *ops,
+ struct adiv5_ap *ap, target_addr_t base_address, bool *is_mem_ap, int depth)
{
struct cs_component_vals v;
int retval;
assert(IS_ALIGNED(base_address, ARM_CS_ALIGN));
+ if (is_mem_ap)
+ *is_mem_ap = false;
+
if (depth > ROM_TABLE_MAX_DEPTH)
retval = ERROR_FAIL;
else
- retval = rtp_read_cs_regs(ap, base_address, &v);
+ retval = rtp_read_cs_regs(mode, ap, base_address, &v);
retval = rtp_ops_cs_component(ops, retval, &v, depth);
if (retval == CORESIGHT_COMPONENT_FOUND)
@@ -1619,37 +1848,64 @@ static int rtp_cs_component(const struct rtp_ops *ops,
const unsigned int class = ARM_CS_CIDR_CLASS(v.cid);
if (class == ARM_CS_CLASS_0X1_ROM_TABLE)
- return rtp_rom_loop(ops, ap, base_address, depth, 32, 960);
+ return rtp_rom_loop(mode, ops, ap, base_address, depth, 32, 960);
if (class == ARM_CS_CLASS_0X9_CS_COMPONENT) {
if ((v.devarch & ARM_CS_C9_DEVARCH_PRESENT) == 0)
return ERROR_OK;
+ if (is_mem_ap) {
+ if ((v.devarch & DEVARCH_ID_MASK) == DEVARCH_MEM_AP)
+ *is_mem_ap = true;
+
+ /* SoC-600 APv1 Adapter */
+ if ((v.devarch & DEVARCH_ID_MASK) == DEVARCH_UNKNOWN_V2 &&
+ ARM_CS_PIDR_DESIGNER(v.pid) == ARM_ID &&
+ ARM_CS_PIDR_PART(v.pid) == 0x9e5)
+ *is_mem_ap = true;
+ }
+
/* quit if not ROM table */
if ((v.devarch & DEVARCH_ID_MASK) != DEVARCH_ROM_C_0X9)
return ERROR_OK;
if ((v.devid & ARM_CS_C9_DEVID_FORMAT_MASK) == ARM_CS_C9_DEVID_FORMAT_64BIT)
- return rtp_rom_loop(ops, ap, base_address, depth, 64, 256);
+ return rtp_rom_loop(mode, ops, ap, base_address, depth, 64, 256);
else
- return rtp_rom_loop(ops, ap, base_address, depth, 32, 512);
+ return rtp_rom_loop(mode, ops, ap, base_address, depth, 32, 512);
}
/* Class other than 0x1 and 0x9 */
return ERROR_OK;
}
-static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap)
+static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap, int depth)
{
- int retval;
uint32_t apid;
target_addr_t dbgbase, invalid_entry;
+ int retval = rtp_ops_ap_header(ops, ap, depth);
+ if (retval != ERROR_OK || depth > ROM_TABLE_MAX_DEPTH)
+ return ERROR_OK; /* Don't abort recursion */
+
+ if (is_adiv6(ap->dap)) {
+ bool is_mem_ap;
+ retval = rtp_cs_component(CS_ACCESS_AP, ops, ap, 0, &is_mem_ap, depth);
+ if (retval == CORESIGHT_COMPONENT_FOUND)
+ return CORESIGHT_COMPONENT_FOUND;
+ if (retval != ERROR_OK)
+ return ERROR_OK; /* Don't abort recursion */
+
+ if (!is_mem_ap)
+ return ERROR_OK;
+ /* Continue for an ADIv6 MEM-AP or SoC-600 APv1 Adapter */
+ }
+
/* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
retval = dap_get_debugbase(ap, &dbgbase, &apid);
if (retval != ERROR_OK)
return retval;
- retval = rtp_ops_mem_ap_header(ops, retval, ap, dbgbase, apid);
+ retval = rtp_ops_mem_ap_header(ops, retval, ap, dbgbase, apid, depth);
if (retval != ERROR_OK)
return retval;
@@ -1668,7 +1924,8 @@ static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap)
invalid_entry = 0xFFFFFFFFul;
if (dbgbase != invalid_entry && (dbgbase & 0x3) != 0x2) {
- retval = rtp_cs_component(ops, ap, dbgbase & 0xFFFFFFFFFFFFF000ull, 0);
+ retval = rtp_cs_component(CS_ACCESS_MEM_AP, ops, ap,
+ dbgbase & 0xFFFFFFFFFFFFF000ull, NULL, depth);
if (retval == CORESIGHT_COMPONENT_FOUND)
return CORESIGHT_COMPONENT_FOUND;
}
@@ -1679,24 +1936,46 @@ static int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap)
/* Actions for command "dap info" */
+static int dap_info_ap_header(struct adiv5_ap *ap, int depth, void *priv)
+{
+ struct command_invocation *cmd = priv;
+
+ if (depth > ROM_TABLE_MAX_DEPTH) {
+ command_print(cmd, "\tTables too deep");
+ return ERROR_FAIL;
+ }
+
+ command_print(cmd, "%sAP # 0x%" PRIx64, (depth) ? "\t\t" : "", ap->ap_num);
+ return ERROR_OK;
+}
+
static int dap_info_mem_ap_header(int retval, struct adiv5_ap *ap,
- target_addr_t dbgbase, uint32_t apid, void *priv)
+ target_addr_t dbgbase, uint32_t apid, int depth, void *priv)
{
struct command_invocation *cmd = priv;
target_addr_t invalid_entry;
+ char tabs[17] = "";
if (retval != ERROR_OK) {
command_print(cmd, "\t\tCan't read MEM-AP, the corresponding core might be turned off");
return retval;
}
- command_print(cmd, "AP ID register 0x%8.8" PRIx32, apid);
+ if (depth > ROM_TABLE_MAX_DEPTH) {
+ command_print(cmd, "\tTables too deep");
+ return ERROR_FAIL;
+ }
+
+ if (depth)
+ snprintf(tabs, sizeof(tabs), "\t[L%02d] ", depth);
+
+ command_print(cmd, "\t\tAP ID register 0x%8.8" PRIx32, apid);
if (apid == 0) {
- command_print(cmd, "No AP found at this ap 0x%x", ap->ap_num);
+ command_print(cmd, "\t\tNo AP found at this AP#0x%" PRIx64, ap->ap_num);
return ERROR_FAIL;
}
- command_print(cmd, "\tType is %s", ap_type_to_description(apid & AP_TYPE_MASK));
+ command_print(cmd, "\t\tType is %s", ap_type_to_description(apid & AP_TYPE_MASK));
/* NOTE: a MEM-AP may have a single CoreSight component that's
* not a ROM table ... or have no such components at all.
@@ -1709,15 +1988,15 @@ static int dap_info_mem_ap_header(int retval, struct adiv5_ap *ap,
else
invalid_entry = 0xFFFFFFFFul;
- command_print(cmd, "MEM-AP BASE " TARGET_ADDR_FMT, dbgbase);
+ command_print(cmd, "%sMEM-AP BASE " TARGET_ADDR_FMT, tabs, dbgbase);
if (dbgbase == invalid_entry || (dbgbase & 0x3) == 0x2) {
- command_print(cmd, "\tNo ROM table present");
+ command_print(cmd, "\t\tNo ROM table present");
} else {
if (dbgbase & 0x01)
- command_print(cmd, "\tValid ROM table present");
+ command_print(cmd, "\t\tValid ROM table present");
else
- command_print(cmd, "\tROM table in legacy format");
+ command_print(cmd, "\t\tROM table in legacy format");
}
}
@@ -1733,7 +2012,8 @@ static int dap_info_cs_component(int retval, struct cs_component_vals *v, int de
return ERROR_FAIL;
}
- command_print(cmd, "\t\tComponent base address " TARGET_ADDR_FMT, v->component_base);
+ if (v->mode == CS_ACCESS_MEM_AP)
+ command_print(cmd, "\t\tComponent base address " TARGET_ADDR_FMT, v->component_base);
if (retval != ERROR_OK) {
command_print(cmd, "\t\tCan't read component, the corresponding core might be turned off");
@@ -1844,13 +2124,14 @@ static int dap_info_rom_table_entry(int retval, int depth,
int dap_info_command(struct command_invocation *cmd, struct adiv5_ap *ap)
{
struct rtp_ops dap_info_ops = {
+ .ap_header = dap_info_ap_header,
.mem_ap_header = dap_info_mem_ap_header,
.cs_component = dap_info_cs_component,
.rom_table_entry = dap_info_rom_table_entry,
.priv = cmd,
};
- return rtp_ap(&dap_info_ops, ap);
+ return rtp_ap(&dap_info_ops, ap, 0);
}
/* Actions for dap_lookup_cs_component() */
@@ -1861,6 +2142,7 @@ struct dap_lookup_data {
unsigned int type;
/* output */
uint64_t component_base;
+ uint64_t ap_num;
};
static int dap_lookup_cs_component_cs_component(int retval,
@@ -1889,6 +2171,7 @@ static int dap_lookup_cs_component_cs_component(int retval,
/* Found! */
lookup->component_base = v->component_base;
+ lookup->ap_num = v->ap->ap_num;
return CORESIGHT_COMPONENT_FOUND;
}
@@ -1900,14 +2183,20 @@ int dap_lookup_cs_component(struct adiv5_ap *ap, uint8_t type,
.idx = core_id,
};
struct rtp_ops dap_lookup_cs_component_ops = {
+ .ap_header = NULL,
.mem_ap_header = NULL,
.cs_component = dap_lookup_cs_component_cs_component,
.rom_table_entry = NULL,
.priv = &lookup,
};
- int retval = rtp_ap(&dap_lookup_cs_component_ops, ap);
+ int retval = rtp_ap(&dap_lookup_cs_component_ops, ap, 0);
if (retval == CORESIGHT_COMPONENT_FOUND) {
+ if (lookup.ap_num != ap->ap_num) {
+ /* TODO: handle search from root ROM table */
+ LOG_DEBUG("CS lookup ended in AP # 0x%" PRIx64 ". Ignore it", lookup.ap_num);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
LOG_DEBUG("CS lookup found at 0x%" PRIx64, lookup.component_base);
*addr = lookup.component_base;
return ERROR_OK;
@@ -1936,7 +2225,7 @@ static const struct jim_nvp nvp_config_opts[] = {
};
static int adiv5_jim_spot_configure(struct jim_getopt_info *goi,
- struct adiv5_dap **dap_p, int *ap_num_p, uint32_t *base_p)
+ struct adiv5_dap **dap_p, uint64_t *ap_num_p, uint32_t *base_p)
{
assert(dap_p && ap_num_p);
@@ -1991,11 +2280,13 @@ static int adiv5_jim_spot_configure(struct jim_getopt_info *goi,
case CFG_AP_NUM:
if (goi->isconfigure) {
+ /* jim_wide is a signed 64 bits int, ap_num is unsigned with max 52 bits */
jim_wide ap_num;
e = jim_getopt_wide(goi, &ap_num);
if (e != JIM_OK)
return e;
- if (ap_num < 0 || ap_num > DP_APSEL_MAX) {
+ /* we still don't know dap->adi_version */
+ if (ap_num < 0 || (ap_num > DP_APSEL_MAX && (ap_num & 0xfff))) {
Jim_SetResultString(goi->interp, "Invalid AP number!", -1);
return JIM_ERR;
}
@@ -2100,15 +2391,27 @@ int adiv5_mem_ap_spot_init(struct adiv5_mem_ap_spot *p)
COMMAND_HANDLER(handle_dap_info_command)
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
- uint32_t apsel;
+ uint64_t apsel;
switch (CMD_ARGC) {
case 0:
apsel = dap->apsel;
break;
case 1:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
- if (apsel > DP_APSEL_MAX) {
+ if (!strcmp(CMD_ARGV[0], "root")) {
+ if (!is_adiv6(dap)) {
+ command_print(CMD, "Option \"root\" not allowed with ADIv5 DAP");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+ int retval = adiv6_dap_read_baseptr(CMD, dap, &apsel);
+ if (retval != ERROR_OK) {
+ command_print(CMD, "Failed reading DAP baseptr");
+ return retval;
+ }
+ break;
+ }
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);
+ if (!is_ap_num_valid(dap, apsel)) {
command_print(CMD, "Invalid AP number");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
@@ -2117,13 +2420,22 @@ COMMAND_HANDLER(handle_dap_info_command)
return ERROR_COMMAND_SYNTAX_ERROR;
}
- return dap_info_command(CMD, &dap->ap[apsel]);
+ struct adiv5_ap *ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_info_command(CMD, ap);
+ dap_put_ap(ap);
+ return retval;
}
COMMAND_HANDLER(dap_baseaddr_command)
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
- uint32_t apsel, baseaddr_lower, baseaddr_upper;
+ uint64_t apsel;
+ uint32_t baseaddr_lower, baseaddr_upper;
struct adiv5_ap *ap;
target_addr_t baseaddr;
int retval;
@@ -2135,9 +2447,8 @@ COMMAND_HANDLER(dap_baseaddr_command)
apsel = dap->apsel;
break;
case 1:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
- /* AP address is in bits 31:24 of DP_SELECT */
- if (apsel > DP_APSEL_MAX) {
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);
+ if (!is_ap_num_valid(dap, apsel)) {
command_print(CMD, "Invalid AP number");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
@@ -2152,19 +2463,25 @@ COMMAND_HANDLER(dap_baseaddr_command)
* use the ID register to verify it's a MEM-AP.
*/
- ap = dap_ap(dap, apsel);
- retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseaddr_lower);
+ ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE(dap), &baseaddr_lower);
if (retval == ERROR_OK && ap->cfg_reg == MEM_AP_REG_CFG_INVALID)
- retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &ap->cfg_reg);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG(dap), &ap->cfg_reg);
if (retval == ERROR_OK && (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || is_64bit_ap(ap))) {
/* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then ignored on 32 bits AP */
- retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, &baseaddr_upper);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64(dap), &baseaddr_upper);
}
if (retval == ERROR_OK)
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK)
return retval;
@@ -2180,22 +2497,35 @@ COMMAND_HANDLER(dap_baseaddr_command)
COMMAND_HANDLER(dap_memaccess_command)
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
+ struct adiv5_ap *ap;
uint32_t memaccess_tck;
switch (CMD_ARGC) {
case 0:
- memaccess_tck = dap->ap[dap->apsel].memaccess_tck;
+ ap = dap_get_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ memaccess_tck = ap->memaccess_tck;
break;
case 1:
+ ap = dap_get_config_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck);
+ ap->memaccess_tck = memaccess_tck;
break;
default:
return ERROR_COMMAND_SYNTAX_ERROR;
}
- dap->ap[dap->apsel].memaccess_tck = memaccess_tck;
+
+ dap_put_ap(ap);
command_print(CMD, "memory bus access delay set to %" PRIu32 " tck",
- dap->ap[dap->apsel].memaccess_tck);
+ memaccess_tck);
return ERROR_OK;
}
@@ -2203,16 +2533,15 @@ COMMAND_HANDLER(dap_memaccess_command)
COMMAND_HANDLER(dap_apsel_command)
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
- uint32_t apsel;
+ uint64_t apsel;
switch (CMD_ARGC) {
case 0:
- command_print(CMD, "%" PRIu32, dap->apsel);
+ command_print(CMD, "0x%" PRIx64, dap->apsel);
return ERROR_OK;
case 1:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
- /* AP address is in bits 31:24 of DP_SELECT */
- if (apsel > DP_APSEL_MAX) {
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);
+ if (!is_ap_num_valid(dap, apsel)) {
command_print(CMD, "Invalid AP number");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
@@ -2228,14 +2557,19 @@ COMMAND_HANDLER(dap_apsel_command)
COMMAND_HANDLER(dap_apcsw_command)
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
- uint32_t apcsw = dap->ap[dap->apsel].csw_default;
+ struct adiv5_ap *ap;
uint32_t csw_val, csw_mask;
switch (CMD_ARGC) {
case 0:
- command_print(CMD, "ap %" PRIu32 " selected, csw 0x%8.8" PRIx32,
- dap->apsel, apcsw);
- return ERROR_OK;
+ ap = dap_get_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ command_print(CMD, "AP#0x%" PRIx64 " selected, csw 0x%8.8" PRIx32,
+ dap->apsel, ap->csw_default);
+ break;
case 1:
if (strcmp(CMD_ARGV[0], "default") == 0)
csw_val = CSW_AHB_DEFAULT;
@@ -2246,7 +2580,12 @@ COMMAND_HANDLER(dap_apcsw_command)
LOG_ERROR("CSW value cannot include 'Size' and 'AddrInc' bit-fields");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
- apcsw = csw_val;
+ ap = dap_get_config_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ ap->csw_default = csw_val;
break;
case 2:
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], csw_val);
@@ -2255,14 +2594,19 @@ COMMAND_HANDLER(dap_apcsw_command)
LOG_ERROR("CSW mask cannot include 'Size' and 'AddrInc' bit-fields");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
- apcsw = (apcsw & ~csw_mask) | (csw_val & csw_mask);
+ ap = dap_get_config_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ ap->csw_default = (ap->csw_default & ~csw_mask) | (csw_val & csw_mask);
break;
default:
return ERROR_COMMAND_SYNTAX_ERROR;
}
- dap->ap[dap->apsel].csw_default = apcsw;
+ dap_put_ap(ap);
- return 0;
+ return ERROR_OK;
}
@@ -2270,7 +2614,8 @@ COMMAND_HANDLER(dap_apcsw_command)
COMMAND_HANDLER(dap_apid_command)
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
- uint32_t apsel, apid;
+ uint64_t apsel;
+ uint32_t apid;
int retval;
switch (CMD_ARGC) {
@@ -2278,9 +2623,8 @@ COMMAND_HANDLER(dap_apid_command)
apsel = dap->apsel;
break;
case 1:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
- /* AP address is in bits 31:24 of DP_SELECT */
- if (apsel > DP_APSEL_MAX) {
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);
+ if (!is_ap_num_valid(dap, apsel)) {
command_print(CMD, "Invalid AP number");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
@@ -2289,10 +2633,18 @@ COMMAND_HANDLER(dap_apid_command)
return ERROR_COMMAND_SYNTAX_ERROR;
}
- retval = dap_queue_ap_read(dap_ap(dap, apsel), AP_REG_IDR, &apid);
- if (retval != ERROR_OK)
+ struct adiv5_ap *ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ retval = dap_queue_ap_read(ap, AP_REG_IDR(dap), &apid);
+ if (retval != ERROR_OK) {
+ dap_put_ap(ap);
return retval;
+ }
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK)
return retval;
@@ -2304,38 +2656,47 @@ COMMAND_HANDLER(dap_apid_command)
COMMAND_HANDLER(dap_apreg_command)
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
- uint32_t apsel, reg, value;
- struct adiv5_ap *ap;
+ uint64_t apsel;
+ uint32_t reg, value;
int retval;
if (CMD_ARGC < 2 || CMD_ARGC > 3)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
- /* AP address is in bits 31:24 of DP_SELECT */
- if (apsel > DP_APSEL_MAX) {
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);
+ if (!is_ap_num_valid(dap, apsel)) {
command_print(CMD, "Invalid AP number");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
- ap = dap_ap(dap, apsel);
-
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg);
- if (reg >= 256 || (reg & 3)) {
- command_print(CMD, "Invalid reg value (should be less than 256 and 4 bytes aligned)");
- return ERROR_COMMAND_ARGUMENT_INVALID;
+ if (is_adiv6(dap)) {
+ if (reg >= 4096 || (reg & 3)) {
+ command_print(CMD, "Invalid reg value (should be less than 4096 and 4 bytes aligned)");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+ } else { /* ADI version 5 */
+ if (reg >= 256 || (reg & 3)) {
+ command_print(CMD, "Invalid reg value (should be less than 256 and 4 bytes aligned)");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+ }
+
+ struct adiv5_ap *ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
}
if (CMD_ARGC == 3) {
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
- switch (reg) {
- case MEM_AP_REG_CSW:
+ /* see if user supplied register address is a match for the CSW or TAR register */
+ if (reg == MEM_AP_REG_CSW(dap)) {
ap->csw_value = 0; /* invalid, in case write fails */
retval = dap_queue_ap_write(ap, reg, value);
if (retval == ERROR_OK)
ap->csw_value = value;
- break;
- case MEM_AP_REG_TAR:
+ } else if (reg == MEM_AP_REG_TAR(dap)) {
retval = dap_queue_ap_write(ap, reg, value);
if (retval == ERROR_OK)
ap->tar_value = (ap->tar_value & ~0xFFFFFFFFull) | value;
@@ -2346,8 +2707,7 @@ COMMAND_HANDLER(dap_apreg_command)
/* if tar_valid is false. */
ap->tar_valid = false;
}
- break;
- case MEM_AP_REG_TAR64:
+ } else if (reg == MEM_AP_REG_TAR64(dap)) {
retval = dap_queue_ap_write(ap, reg, value);
if (retval == ERROR_OK)
ap->tar_value = (ap->tar_value & 0xFFFFFFFFull) | (((target_addr_t)value) << 32);
@@ -2355,10 +2715,8 @@ COMMAND_HANDLER(dap_apreg_command)
/* See above comment for the MEM_AP_REG_TAR failed write case */
ap->tar_valid = false;
}
- break;
- default:
+ } else {
retval = dap_queue_ap_write(ap, reg, value);
- break;
}
} else {
retval = dap_queue_ap_read(ap, reg, &value);
@@ -2366,6 +2724,8 @@ COMMAND_HANDLER(dap_apreg_command)
if (retval == ERROR_OK)
retval = dap_run(dap);
+ dap_put_ap(ap);
+
if (retval != ERROR_OK)
return retval;
@@ -2415,14 +2775,21 @@ COMMAND_HANDLER(dap_ti_be_32_quirks_command)
"TI BE-32 quirks mode");
}
+COMMAND_HANDLER(dap_nu_npcx_quirks_command)
+{
+ struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
+ return CALL_COMMAND_HANDLER(handle_command_parse_bool, &dap->nu_npcx_quirks,
+ "Nuvoton NPCX quirks mode");
+}
+
const struct command_registration dap_instance_commands[] = {
{
.name = "info",
.handler = handle_dap_info_command,
.mode = COMMAND_EXEC,
- .help = "display ROM table for MEM-AP "
- "(default currently selected AP)",
- .usage = "[ap_num]",
+ .help = "display ROM table for specified MEM-AP (default currently selected AP) "
+ "or the ADIv6 root ROM table",
+ .usage = "[ap_num | 'root']",
},
{
.name = "apsel",
@@ -2487,5 +2854,12 @@ const struct command_registration dap_instance_commands[] = {
.help = "set/get quirks mode for TI TMS450/TMS570 processors",
.usage = "[enable]",
},
+ {
+ .name = "nu_npcx_quirks",
+ .handler = dap_nu_npcx_quirks_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set/get quirks mode for Nuvoton NPCX controllers",
+ .usage = "[enable]",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index 8c9a60f..3eddbc0 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2006 by Magnus Lundin *
* lundin@mlu.mine.nu *
@@ -5,18 +7,7 @@
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ * Copyright (C) 2019-2021, Ampere Computing LLC *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM_ADI_V5_H
@@ -53,11 +44,15 @@
*/
#define DP_DPIDR BANK_REG(0x0, 0x0) /* DPv1+: ro */
#define DP_ABORT BANK_REG(0x0, 0x0) /* DPv1+: SWD: wo */
+#define DP_DPIDR1 BANK_REG(0x1, 0x0) /* DPv3: ro */
+#define DP_BASEPTR0 BANK_REG(0x2, 0x0) /* DPv3: ro */
+#define DP_BASEPTR1 BANK_REG(0x3, 0x0) /* DPv3: ro */
#define DP_CTRL_STAT BANK_REG(0x0, 0x4) /* DPv0+: rw */
#define DP_DLCR BANK_REG(0x1, 0x4) /* DPv1+: SWD: rw */
#define DP_TARGETID BANK_REG(0x2, 0x4) /* DPv2: ro */
#define DP_DLPIDR BANK_REG(0x3, 0x4) /* DPv2: ro */
#define DP_EVENTSTAT BANK_REG(0x4, 0x4) /* DPv2: ro */
+#define DP_SELECT1 BANK_REG(0x5, 0x4) /* DPv3: ro */
#define DP_RESEND BANK_REG(0x0, 0x8) /* DPv1+: SWD: ro */
#define DP_SELECT BANK_REG(0x0, 0x8) /* DPv0+: JTAG: rw; SWD: wo */
#define DP_RDBUFF BANK_REG(0x0, 0xC) /* DPv0+: ro */
@@ -76,6 +71,13 @@
#define WDERRCLR (1UL << 3) /* SWD-only */
#define ORUNERRCLR (1UL << 4) /* SWD-only */
+/* Fields of register DP_DPIDR1 */
+#define DP_DPIDR1_ASIZE_MASK (0x7F)
+#define DP_DPIDR1_ERRMODE BIT(7)
+
+/* Fields of register DP_BASEPTR0 */
+#define DP_BASEPTR0_VALID BIT(0)
+
/* Fields of the DP's CTRL/STAT register */
#define CORUNDETECT (1UL << 0)
#define SSTICKYORUN (1UL << 1)
@@ -100,8 +102,8 @@
#define DP_SELECT_DPBANK 0x0000000F
#define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */
-#define DP_APSEL_MAX (255)
-#define DP_APSEL_INVALID (-1)
+#define DP_APSEL_MAX (255) /* for ADIv5 only */
+#define DP_APSEL_INVALID 0xF00 /* more than DP_APSEL_MAX and not ADIv6 aligned 4k */
#define DP_TARGETSEL_INVALID 0xFFFFFFFFU
#define DP_TARGETSEL_DPID_MASK 0x0FFFFFFFU
@@ -110,20 +112,49 @@
/* MEM-AP register addresses */
-#define MEM_AP_REG_CSW 0x00
-#define MEM_AP_REG_TAR 0x04
-#define MEM_AP_REG_TAR64 0x08 /* RW: Large Physical Address Extension */
-#define MEM_AP_REG_DRW 0x0C /* RW: Data Read/Write register */
-#define MEM_AP_REG_BD0 0x10 /* RW: Banked Data register 0-3 */
-#define MEM_AP_REG_BD1 0x14
-#define MEM_AP_REG_BD2 0x18
-#define MEM_AP_REG_BD3 0x1C
-#define MEM_AP_REG_MBT 0x20 /* --: Memory Barrier Transfer register */
-#define MEM_AP_REG_BASE64 0xF0 /* RO: Debug Base Address (LA) register */
-#define MEM_AP_REG_CFG 0xF4 /* RO: Configuration register */
-#define MEM_AP_REG_BASE 0xF8 /* RO: Debug Base Address register */
+#define ADIV5_MEM_AP_REG_CSW (0x00)
+#define ADIV5_MEM_AP_REG_TAR (0x04)
+#define ADIV5_MEM_AP_REG_TAR64 (0x08) /* RW: Large Physical Address Extension */
+#define ADIV5_MEM_AP_REG_DRW (0x0C) /* RW: Data Read/Write register */
+#define ADIV5_MEM_AP_REG_BD0 (0x10) /* RW: Banked Data register 0-3 */
+#define ADIV5_MEM_AP_REG_BD1 (0x14)
+#define ADIV5_MEM_AP_REG_BD2 (0x18)
+#define ADIV5_MEM_AP_REG_BD3 (0x1C)
+#define ADIV5_MEM_AP_REG_MBT (0x20) /* --: Memory Barrier Transfer register */
+#define ADIV5_MEM_AP_REG_BASE64 (0xF0) /* RO: Debug Base Address (LA) register */
+#define ADIV5_MEM_AP_REG_CFG (0xF4) /* RO: Configuration register */
+#define ADIV5_MEM_AP_REG_BASE (0xF8) /* RO: Debug Base Address register */
+
+#define ADIV6_MEM_AP_REG_CSW (0xD00 + ADIV5_MEM_AP_REG_CSW)
+#define ADIV6_MEM_AP_REG_TAR (0xD00 + ADIV5_MEM_AP_REG_TAR)
+#define ADIV6_MEM_AP_REG_TAR64 (0xD00 + ADIV5_MEM_AP_REG_TAR64)
+#define ADIV6_MEM_AP_REG_DRW (0xD00 + ADIV5_MEM_AP_REG_DRW)
+#define ADIV6_MEM_AP_REG_BD0 (0xD00 + ADIV5_MEM_AP_REG_BD0)
+#define ADIV6_MEM_AP_REG_BD1 (0xD00 + ADIV5_MEM_AP_REG_BD1)
+#define ADIV6_MEM_AP_REG_BD2 (0xD00 + ADIV5_MEM_AP_REG_BD2)
+#define ADIV6_MEM_AP_REG_BD3 (0xD00 + ADIV5_MEM_AP_REG_BD3)
+#define ADIV6_MEM_AP_REG_MBT (0xD00 + ADIV5_MEM_AP_REG_MBT)
+#define ADIV6_MEM_AP_REG_BASE64 (0xD00 + ADIV5_MEM_AP_REG_BASE64)
+#define ADIV6_MEM_AP_REG_CFG (0xD00 + ADIV5_MEM_AP_REG_CFG)
+#define ADIV6_MEM_AP_REG_BASE (0xD00 + ADIV5_MEM_AP_REG_BASE)
+
+#define MEM_AP_REG_CSW(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_CSW : ADIV5_MEM_AP_REG_CSW)
+#define MEM_AP_REG_TAR(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_TAR : ADIV5_MEM_AP_REG_TAR)
+#define MEM_AP_REG_TAR64(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_TAR64 : ADIV5_MEM_AP_REG_TAR64)
+#define MEM_AP_REG_DRW(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_DRW : ADIV5_MEM_AP_REG_DRW)
+#define MEM_AP_REG_BD0(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD0 : ADIV5_MEM_AP_REG_BD0)
+#define MEM_AP_REG_BD1(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD1 : ADIV5_MEM_AP_REG_BD1)
+#define MEM_AP_REG_BD2(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD2 : ADIV5_MEM_AP_REG_BD2)
+#define MEM_AP_REG_BD3(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD3 : ADIV5_MEM_AP_REG_BD3)
+#define MEM_AP_REG_MBT(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_MBT : ADIV5_MEM_AP_REG_MBT)
+#define MEM_AP_REG_BASE64(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BASE64 : ADIV5_MEM_AP_REG_BASE64)
+#define MEM_AP_REG_CFG(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_CFG : ADIV5_MEM_AP_REG_CFG)
+#define MEM_AP_REG_BASE(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BASE : ADIV5_MEM_AP_REG_BASE)
+
/* Generic AP register address */
-#define AP_REG_IDR 0xFC /* RO: Identification Register */
+#define ADIV5_AP_REG_IDR (0xFC) /* RO: Identification Register */
+#define ADIV6_AP_REG_IDR (0xD00 + ADIV5_AP_REG_IDR)
+#define AP_REG_IDR(dap) (is_adiv6(dap) ? ADIV6_AP_REG_IDR : ADIV5_AP_REG_IDR)
/* Fields of the MEM-AP's CSW register */
#define CSW_SIZE_MASK 7
@@ -216,9 +247,11 @@ struct adiv5_ap {
struct adiv5_dap *dap;
/**
- * Number of this AP.
+ * ADIv5: Number of this AP (0~255)
+ * ADIv6: Base address of this AP (4k aligned)
+ * TODO: to be more coherent, it should be renamed apsel
*/
- uint8_t ap_num;
+ uint64_t ap_num;
/**
* Default value for (MEM-AP) AP_REG_CSW register.
@@ -259,6 +292,12 @@ struct adiv5_ap {
/* MEM AP configuration register indicating LPAE support */
uint32_t cfg_reg;
+
+ /* references counter */
+ unsigned int refcount;
+
+ /* AP referenced during config. Never put it, even when refcount reaches zero */
+ bool config_ap_never_release;
};
@@ -297,13 +336,13 @@ struct adiv5_dap {
struct adiv5_ap ap[DP_APSEL_MAX + 1];
/* The current manually selected AP by the "dap apsel" command */
- uint32_t apsel;
+ uint64_t apsel;
/**
* Cache for DP_SELECT register. A value of DP_SELECT_INVALID
* indicates no cached value and forces rewrite of the register.
*/
- uint32_t select;
+ uint64_t select;
/* information about current pending SWjDP-AHBAP transaction */
uint8_t ack;
@@ -320,6 +359,10 @@ struct adiv5_dap {
* swizzle appropriately. */
bool ti_be_32_quirks;
+ /* The Nuvoton NPCX M4 has an issue with writing to non-4-byte-aligned mmios.
+ * The work around is to repeat the data in all 4 bytes of DRW */
+ bool nu_npcx_quirks;
+
/**
* STLINK adapter need to know if last AP operation was read or write, and
* in case of write has to flush it with a dummy read from DP_RDBUFF
@@ -347,6 +390,12 @@ struct adiv5_dap {
* Record if enter in SWD required passing through DORMANT
*/
bool switch_through_dormant;
+
+ /** Indicates ADI version (5, 6 or 0 for unknown) being used */
+ unsigned int adi_version;
+
+ /* ADIv6 only field indicating ROM Table address size */
+ unsigned int asize;
};
/**
@@ -421,6 +470,18 @@ static inline bool is_64bit_ap(struct adiv5_ap *ap)
}
/**
+ * Check if DAP is ADIv6
+ *
+ * @param dap The DAP to test
+ *
+ * @return true for ADIv6, false for either ADIv5 or unknown version
+ */
+static inline bool is_adiv6(const struct adiv5_dap *dap)
+{
+ return dap->adi_version == 6;
+}
+
+/**
* Send an adi-v5 sequence to the DAP.
*
* @param dap The DAP used for reading.
@@ -486,6 +547,10 @@ static inline int dap_queue_ap_read(struct adiv5_ap *ap,
unsigned reg, uint32_t *data)
{
assert(ap->dap->ops);
+ if (ap->refcount == 0) {
+ ap->refcount = 1;
+ LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " used without get", ap->ap_num);
+ }
return ap->dap->ops->queue_ap_read(ap, reg, data);
}
@@ -502,6 +567,10 @@ static inline int dap_queue_ap_write(struct adiv5_ap *ap,
unsigned reg, uint32_t data)
{
assert(ap->dap->ops);
+ if (ap->refcount == 0) {
+ ap->refcount = 1;
+ LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " used without get", ap->ap_num);
+ }
return ap->dap->ops->queue_ap_write(ap, reg, data);
}
@@ -619,15 +688,25 @@ int mem_ap_init(struct adiv5_ap *ap);
/* Invalidate cached DP select and cached TAR and CSW of all APs */
void dap_invalidate_cache(struct adiv5_dap *dap);
-/* Probe Access Ports to find a particular type */
-int dap_find_ap(struct adiv5_dap *dap,
+/* read ADIv6 baseptr register */
+int adiv6_dap_read_baseptr(struct command_invocation *cmd, struct adiv5_dap *dap, target_addr_t *baseptr);
+
+/* test if ap_num is valid, based on current knowledge of dap */
+bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num);
+
+/* Probe Access Ports to find a particular type. Increment AP refcount */
+int dap_find_get_ap(struct adiv5_dap *dap,
enum ap_type type_to_find,
struct adiv5_ap **ap_out);
-static inline struct adiv5_ap *dap_ap(struct adiv5_dap *dap, uint8_t ap_num)
-{
- return &dap->ap[ap_num];
-}
+/* Return AP with specified ap_num. Increment AP refcount */
+struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num);
+
+/* Return AP with specified ap_num. Increment AP refcount and keep it non-zero */
+struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num);
+
+/* Decrement AP refcount and release the AP when refcount reaches zero */
+int dap_put_ap(struct adiv5_ap *ap);
/** Check if SWD multidrop configuration is valid */
static inline bool dap_is_multidrop(struct adiv5_dap *dap)
@@ -660,7 +739,7 @@ extern const struct swd_driver *adiv5_dap_swd_driver(struct adiv5_dap *self);
extern int dap_cleanup_all(void);
struct adiv5_private_config {
- int ap_num;
+ uint64_t ap_num;
struct adiv5_dap *dap;
};
@@ -669,7 +748,7 @@ extern int adiv5_jim_configure(struct target *target, struct jim_getopt_info *go
struct adiv5_mem_ap_spot {
struct adiv5_dap *dap;
- int ap_num;
+ uint64_t ap_num;
uint32_t base;
};
diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c
index 96927bf..3612874 100644
--- a/src/target/arm_cti.c
+++ b/src/target/arm_cti.c
@@ -1,20 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2016 by Matthias Welwarsky *
* *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -34,6 +22,7 @@ struct arm_cti {
struct list_head lh;
char *name;
struct adiv5_mem_ap_spot spot;
+ struct adiv5_ap *ap;
};
static LIST_HEAD(all_cti);
@@ -65,7 +54,7 @@ struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t mask, uint32_t value)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
+ struct adiv5_ap *ap = self->ap;
uint32_t tmp;
/* Read register */
@@ -84,15 +73,14 @@ static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t
int arm_cti_enable(struct arm_cti *self, bool enable)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
uint32_t val = enable ? 1 : 0;
- return mem_ap_write_atomic_u32(ap, self->spot.base + CTI_CTR, val);
+ return mem_ap_write_atomic_u32(self->ap, self->spot.base + CTI_CTR, val);
}
int arm_cti_ack_events(struct arm_cti *self, uint32_t event)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
+ struct adiv5_ap *ap = self->ap;
int retval;
uint32_t tmp;
@@ -134,19 +122,15 @@ int arm_cti_ungate_channel(struct arm_cti *self, uint32_t channel)
int arm_cti_write_reg(struct arm_cti *self, unsigned int reg, uint32_t value)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
-
- return mem_ap_write_atomic_u32(ap, self->spot.base + reg, value);
+ return mem_ap_write_atomic_u32(self->ap, self->spot.base + reg, value);
}
int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *p_value)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
-
if (!p_value)
return ERROR_COMMAND_ARGUMENT_INVALID;
- return mem_ap_read_atomic_u32(ap, self->spot.base + reg, p_value);
+ return mem_ap_read_atomic_u32(self->ap, self->spot.base + reg, p_value);
}
int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel)
@@ -228,6 +212,8 @@ int arm_cti_cleanup_all(void)
struct arm_cti *obj, *tmp;
list_for_each_entry_safe(obj, tmp, &all_cti, lh) {
+ if (obj->ap)
+ dap_put_ap(obj->ap);
free(obj->name);
free(obj);
}
@@ -238,7 +224,7 @@ int arm_cti_cleanup_all(void)
COMMAND_HANDLER(handle_cti_dump)
{
struct arm_cti *cti = CMD_DATA;
- struct adiv5_ap *ap = dap_ap(cti->spot.dap, cti->spot.ap_num);
+ struct adiv5_ap *ap = cti->ap;
int retval = ERROR_OK;
for (int i = 0; (retval == ERROR_OK) && (i < (int)ARRAY_SIZE(cti_names)); i++)
@@ -518,6 +504,12 @@ static int cti_create(struct jim_getopt_info *goi)
list_add_tail(&cti->lh, &all_cti);
+ cti->ap = dap_get_ap(cti->spot.dap, cti->spot.ap_num);
+ if (!cti->ap) {
+ Jim_SetResultString(goi->interp, "Cannot get AP", -1);
+ return JIM_ERR;
+ }
+
return JIM_OK;
}
diff --git a/src/target/arm_cti.h b/src/target/arm_cti.h
index 7c4f7eb..cfcde65 100644
--- a/src/target/arm_cti.h
+++ b/src/target/arm_cti.h
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2016 by Matthias Welwarsky *
* *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM_CTI_H
diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c
index 2dba45d..e21136d 100644
--- a/src/target/arm_dap.c
+++ b/src/target/arm_dap.c
@@ -1,20 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2016 by Matthias Welwarsky *
* *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -50,7 +38,7 @@ static void dap_instance_init(struct adiv5_dap *dap)
/* Set up with safe defaults */
for (i = 0; i <= DP_APSEL_MAX; i++) {
dap->ap[i].dap = dap;
- dap->ap[i].ap_num = i;
+ dap->ap[i].ap_num = DP_APSEL_INVALID;
/* memaccess_tck max is 255 */
dap->ap[i].memaccess_tck = 255;
/* Number of bits for tar autoincrement, impl. dep. at least 10 */
@@ -58,6 +46,8 @@ static void dap_instance_init(struct adiv5_dap *dap)
/* default CSW value */
dap->ap[i].csw_default = CSW_AHB_DEFAULT;
dap->ap[i].cfg_reg = MEM_AP_REG_CFG_INVALID; /* mem_ap configuration reg (large physical addr, etc.) */
+ dap->ap[i].refcount = 0;
+ dap->ap[i].config_ap_never_release = false;
}
INIT_LIST_HEAD(&dap->cmd_journal);
INIT_LIST_HEAD(&dap->cmd_pool);
@@ -127,9 +117,34 @@ static int dap_init_all(void)
} else
dap->ops = &jtag_dp_ops;
+ if (dap->adi_version == 0) {
+ LOG_DEBUG("DAP %s configured by default to use ADIv5 protocol", jtag_tap_name(dap->tap));
+ dap->adi_version = 5;
+ } else {
+ LOG_DEBUG("DAP %s configured to use %s protocol by user cfg file", jtag_tap_name(dap->tap),
+ is_adiv6(dap) ? "ADIv6" : "ADIv5");
+ }
+
retval = dap->ops->connect(dap);
if (retval != ERROR_OK)
return retval;
+
+ /* see if address size of ROM Table is greater than 32-bits */
+ if (is_adiv6(dap)) {
+ uint32_t dpidr1;
+
+ retval = dap->ops->queue_dp_read(dap, DP_DPIDR1, &dpidr1);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("DAP read of DPIDR1 failed...");
+ return retval;
+ }
+ retval = dap_run(dap);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("DAP read of DPIDR1 failed...");
+ return retval;
+ }
+ dap->asize = dpidr1 & DP_DPIDR1_ASIZE_MASK;
+ }
}
return ERROR_OK;
@@ -142,6 +157,10 @@ int dap_cleanup_all(void)
list_for_each_entry_safe(obj, tmp, &all_dap, lh) {
dap = &obj->dap;
+ for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {
+ if (dap->ap[i].refcount != 0)
+ LOG_ERROR("BUG: refcount AP#%u still %u at exit", i, dap->ap[i].refcount);
+ }
if (dap->ops && dap->ops->quit)
dap->ops->quit(dap);
@@ -157,6 +176,8 @@ enum dap_cfg_param {
CFG_IGNORE_SYSPWRUPACK,
CFG_DP_ID,
CFG_INSTANCE_ID,
+ CFG_ADIV6,
+ CFG_ADIV5,
};
static const struct jim_nvp nvp_config_opts[] = {
@@ -164,6 +185,8 @@ static const struct jim_nvp nvp_config_opts[] = {
{ .name = "-ignore-syspwrupack", .value = CFG_IGNORE_SYSPWRUPACK },
{ .name = "-dp-id", .value = CFG_DP_ID },
{ .name = "-instance-id", .value = CFG_INSTANCE_ID },
+ { .name = "-adiv6", .value = CFG_ADIV6 },
+ { .name = "-adiv5", .value = CFG_ADIV5 },
{ .name = NULL, .value = -1 }
};
@@ -243,6 +266,12 @@ static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap
dap->dap.multidrop_instance_id_valid = true;
break;
}
+ case CFG_ADIV6:
+ dap->dap.adi_version = 6;
+ break;
+ case CFG_ADIV5:
+ dap->dap.adi_version = 5;
+ break;
default:
break;
}
@@ -418,7 +447,7 @@ COMMAND_HANDLER(handle_dap_info_command)
struct target *target = get_current_target(CMD_CTX);
struct arm *arm = target_to_arm(target);
struct adiv5_dap *dap = arm->dap;
- uint32_t apsel;
+ uint64_t apsel;
if (!dap) {
LOG_ERROR("DAP instance not available. Probably a HLA target...");
@@ -430,15 +459,34 @@ COMMAND_HANDLER(handle_dap_info_command)
apsel = dap->apsel;
break;
case 1:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
- if (apsel > DP_APSEL_MAX)
+ if (!strcmp(CMD_ARGV[0], "root")) {
+ if (!is_adiv6(dap)) {
+ command_print(CMD, "Option \"root\" not allowed with ADIv5 DAP");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+ int retval = adiv6_dap_read_baseptr(CMD, dap, &apsel);
+ if (retval != ERROR_OK) {
+ command_print(CMD, "Failed reading DAP baseptr");
+ return retval;
+ }
+ break;
+ }
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);
+ if (!is_ap_num_valid(dap, apsel))
return ERROR_COMMAND_SYNTAX_ERROR;
break;
default:
return ERROR_COMMAND_SYNTAX_ERROR;
}
- return dap_info_command(CMD, &dap->ap[apsel]);
+ struct adiv5_ap *ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ int retval = dap_info_command(CMD, ap);
+ dap_put_ap(ap);
+ return retval;
}
static const struct command_registration dap_subcommand_handlers[] = {
@@ -467,9 +515,9 @@ static const struct command_registration dap_subcommand_handlers[] = {
.name = "info",
.handler = handle_dap_info_command,
.mode = COMMAND_EXEC,
- .help = "display ROM table for MEM-AP of current target "
- "(default currently selected AP)",
- .usage = "[ap_num]",
+ .help = "display ROM table for specified MEM-AP (default MEM-AP of current target) "
+ "or the ADIv6 root ROM table of current target's DAP",
+ .usage = "[ap_num | 'root']",
},
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c
index d3d27a9..749274f 100644
--- a/src/target/arm_disassembler.c
+++ b/src/target/arm_disassembler.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2009 by David Brownell *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm_disassembler.h b/src/target/arm_disassembler.h
index 6f15f4b..1be5674 100644
--- a/src/target/arm_disassembler.h
+++ b/src/target/arm_disassembler.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM_DISASSEMBLER_H
diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c
index e60ef22..5f7e929 100644
--- a/src/target/arm_dpm.c
+++ b/src/target/arm_dpm.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2009 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm_dpm.h b/src/target/arm_dpm.h
index 0172d9a..d35e9f6 100644
--- a/src/target/arm_dpm.h
+++ b/src/target/arm_dpm.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (C) 2009 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENOCD_TARGET_ARM_DPM_H
diff --git a/src/target/arm_jtag.c b/src/target/arm_jtag.c
index 6a27e32..c1ec473 100644
--- a/src/target/arm_jtag.c
+++ b/src/target/arm_jtag.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm_jtag.h b/src/target/arm_jtag.h
index f3e0bc2..11b7c3e 100644
--- a/src/target/arm_jtag.h
+++ b/src/target/arm_jtag.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007-2010 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM_JTAG_H
diff --git a/src/target/arm_opcodes.h b/src/target/arm_opcodes.h
index 00035f5..c182f41 100644
--- a/src/target/arm_opcodes.h
+++ b/src/target/arm_opcodes.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (C) 2005 by Dominic Rath
* Dominic.Rath@gmx.de
@@ -10,19 +12,6 @@
*
* Copyright (C) 2009 by Øyvind Harboe
* oyvind.harboe@zylin.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENOCD_TARGET_ARM_OPCODES_H
diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c
index 507d1cd..b557589 100644
--- a/src/target/arm_semihosting.c
+++ b/src/target/arm_semihosting.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Marvell Technology Group Ltd. *
* Written by Nicolas Pitre <nico@marvell.com> *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2018 by Liviu Ionescu *
* <ilg@livius.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
diff --git a/src/target/arm_semihosting.h b/src/target/arm_semihosting.h
index cf1f8de..0a912a7 100644
--- a/src/target/arm_semihosting.h
+++ b/src/target/arm_semihosting.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Marvell Technology Group Ltd. *
* Written by Nicolas Pitre <nico@marvell.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM_SEMIHOSTING_H
diff --git a/src/target/arm_simulator.c b/src/target/arm_simulator.c
index 480d9bc..058e3d3 100644
--- a/src/target/arm_simulator.c
+++ b/src/target/arm_simulator.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2008 by Hongtao Zheng *
* hontor@126.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm_simulator.h b/src/target/arm_simulator.h
index 5bdbf56..e4a25d8 100644
--- a/src/target/arm_simulator.h
+++ b/src/target/arm_simulator.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM_SIMULATOR_H
diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c
index fba3fec..7096db3 100644
--- a/src/target/arm_tpiu_swo.c
+++ b/src/target/arm_tpiu_swo.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/**
* @file
@@ -90,6 +90,7 @@ struct arm_tpiu_swo_event_action {
struct arm_tpiu_swo_object {
struct list_head lh;
struct adiv5_mem_ap_spot spot;
+ struct adiv5_ap *ap;
char *name;
struct arm_tpiu_swo_event_action *event_action;
/* record enable before init */
@@ -233,6 +234,9 @@ int arm_tpiu_swo_cleanup_all(void)
ea = next;
}
+ if (obj->ap)
+ dap_put_ap(obj->ap);
+
free(obj->name);
free(obj->out_filename);
free(obj);
@@ -596,7 +600,6 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
struct command *c = jim_to_command(interp);
struct arm_tpiu_swo_object *obj = c->jim_handler_data;
struct command_context *cmd_ctx = current_command_context(interp);
- struct adiv5_ap *tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num);
uint32_t value;
int retval;
@@ -614,8 +617,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
if (obj->enabled)
return JIM_OK;
- if (transport_is_hla() && obj->spot.ap_num > 0) {
- LOG_ERROR("Invalid access port %d. Only AP#0 allowed with hla transport", obj->spot.ap_num);
+ if (transport_is_hla() && obj->spot.ap_num != 0) {
+ LOG_ERROR("Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", obj->spot.ap_num);
return JIM_ERR;
}
@@ -644,21 +647,28 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
struct cortex_m_common *cm = target_to_cm(target);
obj->recheck_ap_cur_target = false;
obj->spot.ap_num = cm->armv7m.debug_ap->ap_num;
- tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num);
if (obj->spot.ap_num == 0)
LOG_INFO(MSG "Confirmed TPIU %s is on AP 0", obj->name);
else
- LOG_INFO(MSG "Target %s is on AP %d. Revised command is "
- "\'tpiu create %s -dap %s -ap-num %d\'",
+ LOG_INFO(MSG "Target %s is on AP#0x%" PRIx64 ". Revised command is "
+ "\'tpiu create %s -dap %s -ap-num 0x%" PRIx64 "\'",
target_name(target), obj->spot.ap_num,
obj->name, adiv5_dap_name(obj->spot.dap), obj->spot.ap_num);
}
/* END_DEPRECATED_TPIU */
+ if (!obj->ap) {
+ obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num);
+ if (!obj->ap) {
+ LOG_ERROR("Cannot get AP");
+ return JIM_ERR;
+ }
+ }
+
/* trigger the event before any attempt to R/W in the TPIU/SWO */
arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_ENABLE);
- retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);
+ retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);
if (retval != ERROR_OK) {
LOG_ERROR("Unable to read %s", obj->name);
return JIM_ERR;
@@ -684,7 +694,7 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
}
if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) {
- retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value);
+ retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value);
if (retval != ERROR_OK) {
LOG_ERROR("Cannot read TPIU register SSPSR");
return JIM_ERR;
@@ -759,26 +769,26 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
obj->swo_pin_freq = swo_pin_freq;
}
- retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1));
+ retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1));
if (retval != ERROR_OK)
goto error_exit;
- retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1);
+ retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1);
if (retval != ERROR_OK)
goto error_exit;
- retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol);
+ retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol);
if (retval != ERROR_OK)
goto error_exit;
- retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_FFCR_OFFSET, &value);
+ retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, &value);
if (retval != ERROR_OK)
goto error_exit;
if (obj->en_formatter)
value |= BIT(1);
else
value &= ~BIT(1);
- retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_FFCR_OFFSET, value);
+ retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, value);
if (retval != ERROR_OK)
goto error_exit;
@@ -1037,7 +1047,7 @@ COMMAND_HANDLER(handle_tpiu_deprecated_config_command)
struct cortex_m_common *cm = target_to_cm(target);
struct adiv5_private_config *pc = target->private_config;
struct adiv5_dap *dap = pc->dap;
- int ap_num = pc->ap_num;
+ uint64_t ap_num = pc->ap_num;
bool set_recheck_ap_cur_target = false;
LOG_INFO(MSG "Adding a TPIU \'%s.tpiu\' in the configuration", target_name(target));
@@ -1055,10 +1065,10 @@ COMMAND_HANDLER(handle_tpiu_deprecated_config_command)
set_recheck_ap_cur_target = true;
}
- LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num %d\'",
+ LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64 "\'",
target_name(target), adiv5_dap_name(dap), ap_num);
- retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num %d",
+ retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64,
target_name(target), adiv5_dap_name(dap), ap_num);
if (retval != ERROR_OK)
return retval;
diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c
index b861cf5..48af503 100644
--- a/src/target/armv4_5.c
+++ b/src/target/armv4_5.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2018 by Liviu Ionescu *
* <ilg@livius.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -546,7 +535,7 @@ static struct reg_feature arm_gdb_dummy_fp_features = {
* Modern ARM cores use Vector Floating Point (VFP), if they
* have any floating point support. VFP is not FPA-compatible.
*/
-struct reg arm_gdb_dummy_fp_reg = {
+static struct reg arm_gdb_dummy_fp_reg = {
.name = "GDB dummy FPA register",
.value = (uint8_t *) arm_gdb_dummy_fp_value,
.valid = true,
@@ -563,7 +552,7 @@ static const uint8_t arm_gdb_dummy_fps_value[4];
* Dummy FPA status registers are required to support GDB on ARM.
* Register packets require an obsolete FPA status register.
*/
-struct reg arm_gdb_dummy_fps_reg = {
+static struct reg arm_gdb_dummy_fps_reg = {
.name = "GDB dummy FPA status register",
.value = (uint8_t *) arm_gdb_dummy_fps_value,
.valid = true,
@@ -916,32 +905,33 @@ COMMAND_HANDLER(handle_armv4_5_reg_command)
return ERROR_OK;
}
-COMMAND_HANDLER(handle_armv4_5_core_state_command)
+COMMAND_HANDLER(handle_arm_core_state_command)
{
struct target *target = get_current_target(CMD_CTX);
struct arm *arm = target_to_arm(target);
+ int ret = ERROR_OK;
if (!is_arm(arm)) {
command_print(CMD, "current target isn't an ARM");
return ERROR_FAIL;
}
- if (arm->core_type == ARM_CORE_TYPE_M_PROFILE) {
- /* armv7m not supported */
- command_print(CMD, "Unsupported Command");
- return ERROR_OK;
- }
-
if (CMD_ARGC > 0) {
- if (strcmp(CMD_ARGV[0], "arm") == 0)
- arm->core_state = ARM_STATE_ARM;
+ if (strcmp(CMD_ARGV[0], "arm") == 0) {
+ if (arm->core_type == ARM_CORE_TYPE_M_PROFILE) {
+ command_print(CMD, "arm mode not supported on Cortex-M");
+ ret = ERROR_FAIL;
+ } else {
+ arm->core_state = ARM_STATE_ARM;
+ }
+ }
if (strcmp(CMD_ARGV[0], "thumb") == 0)
arm->core_state = ARM_STATE_THUMB;
}
command_print(CMD, "core state: %s", arm_state_strings[arm->core_state]);
- return ERROR_OK;
+ return ret;
}
COMMAND_HANDLER(handle_arm_disassemble_command)
@@ -1127,8 +1117,6 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
return JIM_OK;
}
-extern const struct command_registration semihosting_common_handlers[];
-
static const struct command_registration arm_exec_command_handlers[] = {
{
.name = "reg",
@@ -1138,20 +1126,6 @@ static const struct command_registration arm_exec_command_handlers[] = {
.usage = "",
},
{
- .name = "core_state",
- .handler = handle_armv4_5_core_state_command,
- .mode = COMMAND_EXEC,
- .usage = "['arm'|'thumb']",
- .help = "display/change ARM core state",
- },
- {
- .name = "disassemble",
- .handler = handle_arm_disassemble_command,
- .mode = COMMAND_EXEC,
- .usage = "address [count ['thumb']]",
- .help = "disassemble instructions",
- },
- {
.name = "mcr",
.mode = COMMAND_EXEC,
.jim_handler = &jim_mcrmrc,
@@ -1166,10 +1140,32 @@ static const struct command_registration arm_exec_command_handlers[] = {
.usage = "cpnum op1 CRn CRm op2",
},
{
+ .chain = arm_all_profiles_command_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+const struct command_registration arm_all_profiles_command_handlers[] = {
+ {
+ .name = "core_state",
+ .handler = handle_arm_core_state_command,
+ .mode = COMMAND_EXEC,
+ .usage = "['arm'|'thumb']",
+ .help = "display/change ARM core state",
+ },
+ {
+ .name = "disassemble",
+ .handler = handle_arm_disassemble_command,
+ .mode = COMMAND_EXEC,
+ .usage = "address [count ['thumb']]",
+ .help = "disassemble instructions",
+ },
+ {
.chain = semihosting_common_handlers,
},
COMMAND_REGISTRATION_DONE
};
+
const struct command_registration arm_command_handlers[] = {
{
.name = "arm",
diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h
index bef1cfe..250fa82 100644
--- a/src/target/armv4_5.h
+++ b/src/target/armv4_5.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2009 by Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARMV4_5_H
diff --git a/src/target/armv4_5_cache.c b/src/target/armv4_5_cache.c
index eda8cb7..e12c43d 100644
--- a/src/target/armv4_5_cache.c
+++ b/src/target/armv4_5_cache.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv4_5_cache.h b/src/target/armv4_5_cache.h
index 985a3a7..3659941 100644
--- a/src/target/armv4_5_cache.h
+++ b/src/target/armv4_5_cache.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARMV4_5_CACHE_H
diff --git a/src/target/armv4_5_mmu.c b/src/target/armv4_5_mmu.c
index 115a489..9942f49 100644
--- a/src/target/armv4_5_mmu.c
+++ b/src/target/armv4_5_mmu.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv4_5_mmu.h b/src/target/armv4_5_mmu.h
index 7beaf4e..774f105 100644
--- a/src/target/armv4_5_mmu.h
+++ b/src/target/armv4_5_mmu.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARMV4_5_MMU_H
diff --git a/src/target/armv7a.c b/src/target/armv7a.c
index 1e425aa..82f4be5 100644
--- a/src/target/armv7a.c
+++ b/src/target/armv7a.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by David Brownell *
* *
* Copyright (C) ST-Ericsson SA 2011 michel.jaouen@stericsson.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv7a.h b/src/target/armv7a.h
index c282554..6b9c2a6 100644
--- a/src/target/armv7a.h
+++ b/src/target/armv7a.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by David Brownell *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARMV7A_H
@@ -30,7 +19,7 @@ enum {
ARM_CPSR = 16
};
-#define ARMV7_COMMON_MAGIC 0x0A450999
+#define ARMV7_COMMON_MAGIC 0x0A450999U
/* VA to PA translation operations opc2 values*/
#define V2PCWPR 0
@@ -98,8 +87,9 @@ struct armv7a_mmu_common {
};
struct armv7a_common {
+ unsigned int common_magic;
+
struct arm arm;
- int common_magic;
struct reg_cache *core_cache;
/* Core Debug Unit */
diff --git a/src/target/armv7a_cache.c b/src/target/armv7a_cache.c
index ba6f076..995a856 100644
--- a/src/target/armv7a_cache.c
+++ b/src/target/armv7a_cache.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by Oleksij Rempel *
* linux@rempel-privat.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv7a_cache.h b/src/target/armv7a_cache.h
index 8d8ca2d..17ec5e6 100644
--- a/src/target/armv7a_cache.h
+++ b/src/target/armv7a_cache.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2015 Oleksij Rempel *
* linux@rempel-privat.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM7A_CACHE_H
diff --git a/src/target/armv7a_cache_l2x.c b/src/target/armv7a_cache_l2x.c
index c26d051..39c503f 100644
--- a/src/target/armv7a_cache_l2x.c
+++ b/src/target/armv7a_cache_l2x.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by Oleksij Rempel *
* linux@rempel-privat.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv7a_cache_l2x.h b/src/target/armv7a_cache_l2x.h
index f98b554..d5f1a6f 100644
--- a/src/target/armv7a_cache_l2x.h
+++ b/src/target/armv7a_cache_l2x.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2015 Oleksij Rempel *
* linux@rempel-privat.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARM7A_CACHE_L2X_H
diff --git a/src/target/armv7a_mmu.c b/src/target/armv7a_mmu.c
index 98a0065..c4d294e 100644
--- a/src/target/armv7a_mmu.c
+++ b/src/target/armv7a_mmu.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2016 by Matthias Welwarsky *
* matthias.welwarsky@sysgo.com *
* *
* Copyright (C) ST-Ericsson SA 2011 michel.jaouen@stericsson.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv7a_mmu.h b/src/target/armv7a_mmu.h
index 36cd9d1..d93d3c6 100644
--- a/src/target/armv7a_mmu.h
+++ b/src/target/armv7a_mmu.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2016 by Matthias Welwarsky *
* matthias.welwarsky@sysgo.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARMV7A_MMU_H
diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index 0a51ad4..2db2ce2 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -17,19 +19,6 @@
* Copyright (C) 2019 by Tomas Vanek *
* vanekt@fbl.cz *
* *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- * *
* ARMv7-M Architecture, Application Level Reference Manual *
* ARM DDI 0405C (September 2008) *
* *
@@ -64,7 +53,7 @@ const int armv7m_psp_reg_map[ARMV7M_NUM_CORE_REGS] = {
ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7,
ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11,
ARMV7M_R12, ARMV7M_PSP, ARMV7M_R14, ARMV7M_PC,
- ARMV7M_xPSR,
+ ARMV7M_XPSR,
};
/* MSP is used in handler and some thread modes */
@@ -73,7 +62,7 @@ const int armv7m_msp_reg_map[ARMV7M_NUM_CORE_REGS] = {
ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7,
ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11,
ARMV7M_R12, ARMV7M_MSP, ARMV7M_R14, ARMV7M_PC,
- ARMV7M_xPSR,
+ ARMV7M_XPSR,
};
/*
@@ -108,7 +97,7 @@ static const struct {
{ ARMV7M_R13, "sp", 32, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.m-profile" },
{ ARMV7M_R14, "lr", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" },
{ ARMV7M_PC, "pc", 32, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.m-profile" },
- { ARMV7M_xPSR, "xPSR", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" },
+ { ARMV7M_XPSR, "xPSR", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" },
{ ARMV7M_MSP, "msp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" },
{ ARMV7M_PSP, "psp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" },
@@ -256,7 +245,7 @@ uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id)
switch (arm_reg_id) {
case ARMV7M_R0 ... ARMV7M_R14:
case ARMV7M_PC:
- case ARMV7M_xPSR:
+ case ARMV7M_XPSR:
case ARMV7M_MSP:
case ARMV7M_PSP:
/* NOTE: we "know" here that the register identifiers
@@ -590,7 +579,7 @@ int armv7m_start_algorithm(struct target *target,
* Because xPSR.T is populated on reset from the vector table,
* it might be 0 if the vector table has "bad" data in it.
*/
- struct reg *reg = &armv7m->arm.core_cache->reg_list[ARMV7M_xPSR];
+ struct reg *reg = &armv7m->arm.core_cache->reg_list[ARMV7M_XPSR];
buf_set_u32(reg->value, 0, 32, 0x01000000);
reg->valid = true;
reg->dirty = true;
@@ -814,7 +803,7 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target)
LOG_ERROR("unable to allocate reg type list");
}
- arm->cpsr = reg_list + ARMV7M_xPSR;
+ arm->cpsr = reg_list + ARMV7M_XPSR;
arm->pc = reg_list + ARMV7M_PC;
arm->core_cache = cache;
@@ -865,6 +854,7 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m)
/* Enable stimulus port #0 by default */
armv7m->trace_config.itm_ter[0] = 1;
+ arm->core_state = ARM_STATE_THUMB;
arm->core_type = ARM_CORE_TYPE_M_PROFILE;
arm->arch_info = armv7m;
arm->setup_semihosting = armv7m_setup_semihosting;
@@ -1095,7 +1085,11 @@ int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found)
const struct command_registration armv7m_command_handlers[] = {
{
- .chain = arm_command_handlers,
+ .name = "arm",
+ .mode = COMMAND_ANY,
+ .help = "ARM command group",
+ .usage = "",
+ .chain = arm_all_profiles_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index 9ac121a..188bd56 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARMV7M_H
@@ -57,7 +46,7 @@ enum {
ARMV7M_REGSEL_R14,
ARMV7M_REGSEL_PC = 15,
- ARMV7M_REGSEL_xPSR = 16,
+ ARMV7M_REGSEL_XPSR = 16,
ARMV7M_REGSEL_MSP,
ARMV7M_REGSEL_PSP,
@@ -135,7 +124,7 @@ enum {
ARMV7M_R14 = ARMV7M_REGSEL_R14,
ARMV7M_PC = ARMV7M_REGSEL_PC,
- ARMV7M_xPSR = ARMV7M_REGSEL_xPSR,
+ ARMV7M_XPSR = ARMV7M_REGSEL_XPSR,
ARMV7M_MSP = ARMV7M_REGSEL_MSP,
ARMV7M_PSP = ARMV7M_REGSEL_PSP,
@@ -210,7 +199,7 @@ enum {
/* for convenience add registers' block delimiters */
ARMV7M_LAST_REG,
ARMV7M_CORE_FIRST_REG = ARMV7M_R0,
- ARMV7M_CORE_LAST_REG = ARMV7M_xPSR,
+ ARMV7M_CORE_LAST_REG = ARMV7M_XPSR,
ARMV7M_FPU_FIRST_REG = ARMV7M_D0,
ARMV7M_FPU_LAST_REG = ARMV7M_FPSCR,
ARMV8M_FIRST_REG = ARMV8M_MSP_NS,
@@ -226,12 +215,13 @@ enum {
#define ARMV7M_NUM_CORE_REGS (ARMV7M_CORE_LAST_REG - ARMV7M_CORE_FIRST_REG + 1)
-#define ARMV7M_COMMON_MAGIC 0x2A452A45
+#define ARMV7M_COMMON_MAGIC 0x2A452A45U
struct armv7m_common {
+ unsigned int common_magic;
+
struct arm arm;
- int common_magic;
int exception_number;
/* AP this processor is connected to in the DAP */
@@ -300,7 +290,7 @@ target_to_armv7m_safe(struct target *target)
}
struct armv7m_algorithm {
- int common_magic;
+ unsigned int common_magic;
enum arm_mode core_mode;
diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c
index 74ffaf5..45117d2 100644
--- a/src/target/armv7m_trace.c
+++ b/src/target/armv7m_trace.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 Paul Fertser <fercerpav@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv7m_trace.h b/src/target/armv7m_trace.h
index 7e4977a..5abb0b9 100644
--- a/src/target/armv7m_trace.h
+++ b/src/target/armv7m_trace.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2015 Paul Fertser <fercerpav@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARMV7M_TRACE_H
diff --git a/src/target/armv8.c b/src/target/armv8.c
index 2de1157..de0bddb 100644
--- a/src/target/armv8.c
+++ b/src/target/armv8.c
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2015 by David Ung *
* *
* Copyright (C) 2018 by Liviu Ionescu *
* <ilg@livius.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -146,7 +134,7 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv
retval = dpm->instr_read_data_r0_64(dpm,
ARMV8_MRS_DLR(0), &value_64);
break;
- case ARMV8_xPSR:
+ case ARMV8_XPSR:
retval = dpm->instr_read_data_r0(dpm,
ARMV8_MRS_DSPSR(0), &value);
value_64 = value;
@@ -261,7 +249,7 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu
ARMV8_MSR_DLR(0),
value_64);
break;
- case ARMV8_xPSR:
+ case ARMV8_XPSR:
value = value_64;
retval = dpm->instr_write_data_r0(dpm,
ARMV8_MSR_DSPSR(0),
@@ -376,7 +364,7 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re
ARMV8_MRC_DLR(0),
&value);
break;
- case ARMV8_xPSR:
+ case ARMV8_XPSR:
retval = dpm->instr_read_data_r0(dpm,
ARMV8_MRC_DSPSR(0),
&value);
@@ -411,17 +399,17 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re
break;
case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */
retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS_xPSR_T1(1, 0),
+ ARMV8_MRS_XPSR_T1(1, 0),
&value);
break;
case ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */
retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS_xPSR_T1(1, 0),
+ ARMV8_MRS_XPSR_T1(1, 0),
&value);
break;
case ARMV8_SPSR_EL3: /* mapped to SPSR_mon */
retval = dpm->instr_read_data_r0(dpm,
- ARMV8_MRS_xPSR_T1(1, 0),
+ ARMV8_MRS_XPSR_T1(1, 0),
&value);
break;
case ARMV8_FPSR:
@@ -512,7 +500,7 @@ static int armv8_write_reg32(struct armv8_common *armv8, int regnum, uint64_t va
retval = dpm->instr_write_data_r0(dpm,
ARMV8_MCR_DLR(0), value);
break;
- case ARMV8_xPSR: /* CPSR */
+ case ARMV8_XPSR: /* CPSR */
/* read r0 from DCC, then "MCR r0, DSPSR" */
retval = dpm->instr_write_data_r0(dpm,
ARMV8_MCR_DSPSR(0), value);
@@ -547,17 +535,17 @@ static int armv8_write_reg32(struct armv8_common *armv8, int regnum, uint64_t va
break;
case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */
retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
+ ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
value);
break;
case ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */
retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
+ ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
value);
break;
case ARMV8_SPSR_EL3: /* mapped to SPSR_mon */
retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
+ ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
value);
break;
case ARMV8_FPSR:
@@ -1376,7 +1364,7 @@ static const struct {
{ ARMV8_SP, "sp", 64, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.aarch64.core", NULL},
{ ARMV8_PC, "pc", 64, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.aarch64.core", NULL},
- { ARMV8_xPSR, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED,
+ { ARMV8_XPSR, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED,
"general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr},
{ ARMV8_V0, "v0", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
{ ARMV8_V1, "v1", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
@@ -1461,7 +1449,7 @@ static const struct {
{ ARMV8_R13, 0, "sp", 32, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.core" },
{ ARMV8_R14, 0, "lr", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
{ ARMV8_PC, 0, "pc", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
- { ARMV8_xPSR, 0, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
+ { ARMV8_XPSR, 0, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
{ ARMV8_V0, 0, "d0", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
{ ARMV8_V0, 8, "d1", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
{ ARMV8_V1, 0, "d2", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
@@ -1664,7 +1652,7 @@ struct reg_cache *armv8_build_reg_cache(struct target *target)
LOG_ERROR("unable to allocate reg type list");
}
- arm->cpsr = reg_list + ARMV8_xPSR;
+ arm->cpsr = reg_list + ARMV8_XPSR;
arm->pc = reg_list + ARMV8_PC;
arm->core_cache = cache;
diff --git a/src/target/armv8.h b/src/target/armv8.h
index c30739c..2ed3a65 100644
--- a/src/target/armv8.h
+++ b/src/target/armv8.h
@@ -1,19 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2015 by David Ung *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARMV8_H
@@ -61,7 +49,7 @@ enum {
ARMV8_SP = 31,
ARMV8_PC = 32,
- ARMV8_xPSR = 33,
+ ARMV8_XPSR = 33,
ARMV8_V0 = 34,
ARMV8_V1,
@@ -120,7 +108,7 @@ enum run_control_op {
ARMV8_RUNCONTROL_STEP = 3,
};
-#define ARMV8_COMMON_MAGIC 0x0A450AAA
+#define ARMV8_COMMON_MAGIC 0x0A450AAAU
/* VA to PA translation operations opc2 values*/
#define V2PCWPR 0
@@ -190,8 +178,9 @@ struct armv8_mmu_common {
};
struct armv8_common {
+ unsigned int common_magic;
+
struct arm arm;
- int common_magic;
struct reg_cache *core_cache;
/* Core Debug Unit */
diff --git a/src/target/armv8_cache.c b/src/target/armv8_cache.c
index 5b58d3f..cf71119 100644
--- a/src/target/armv8_cache.c
+++ b/src/target/armv8_cache.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2016 by Matthias Welwarsky *
* matthias.welwarsky@sysgo.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv8_cache.h b/src/target/armv8_cache.h
index fa46e16..7a12aa1 100644
--- a/src/target/armv8_cache.h
+++ b/src/target/armv8_cache.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2016 by Matthias Welwarsky *
* matthias.welwarsky@sysgo.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARMV8_CACHE_H_
#define OPENOCD_TARGET_ARMV8_CACHE_H_
diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c
index 765f1b7..f40beb8 100644
--- a/src/target/armv8_dpm.c
+++ b/src/target/armv8_dpm.c
@@ -1,16 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2009 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#ifdef HAVE_CONFIG_H
@@ -610,7 +601,7 @@ int armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)
/* load SPSR with the desired mode and execute DRPS */
LOG_DEBUG("SPSR = 0x%08"PRIx32, cpsr);
retval = dpm->instr_write_data_r0(dpm,
- ARMV8_MSR_GP_xPSR_T1(1, 0, 15), cpsr);
+ ARMV8_MSR_GP_XPSR_T1(1, 0, 15), cpsr);
if (retval == ERROR_OK)
retval = dpm->instr_execute(dpm, armv8_opcode(armv8, ARMV8_OPC_DRPS));
}
@@ -926,7 +917,7 @@ int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
if (!cache->reg_list[i].exist)
continue;
/* skip PC and CPSR */
- if (i == ARMV8_PC || i == ARMV8_xPSR)
+ if (i == ARMV8_PC || i == ARMV8_XPSR)
continue;
/* skip invalid */
if (!cache->reg_list[i].valid)
@@ -948,7 +939,7 @@ int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
/* flush CPSR and PC */
if (retval == ERROR_OK)
- retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_xPSR], ARMV8_xPSR);
+ retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_XPSR], ARMV8_XPSR);
if (retval == ERROR_OK)
retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_PC], ARMV8_PC);
/* flush R0 -- it's *very* dirty by now */
@@ -1302,9 +1293,9 @@ void armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore)
unsigned int el;
static const int clobbered_regs_by_el[3][5] = {
- { ARMV8_PC, ARMV8_xPSR, ARMV8_ELR_EL1, ARMV8_ESR_EL1, ARMV8_SPSR_EL1 },
- { ARMV8_PC, ARMV8_xPSR, ARMV8_ELR_EL2, ARMV8_ESR_EL2, ARMV8_SPSR_EL2 },
- { ARMV8_PC, ARMV8_xPSR, ARMV8_ELR_EL3, ARMV8_ESR_EL3, ARMV8_SPSR_EL3 },
+ { ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL1, ARMV8_ESR_EL1, ARMV8_SPSR_EL1 },
+ { ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL2, ARMV8_ESR_EL2, ARMV8_SPSR_EL2 },
+ { ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL3, ARMV8_ESR_EL3, ARMV8_SPSR_EL3 },
};
el = (dpm->dscr >> 8) & 3;
@@ -1319,7 +1310,7 @@ void armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore)
mem_ap_write_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
- armv8->read_reg_u64(armv8, ARMV8_xPSR, &dlr);
+ armv8->read_reg_u64(armv8, ARMV8_XPSR, &dlr);
dspsr = dlr;
armv8->read_reg_u64(armv8, ARMV8_PC, &dlr);
diff --git a/src/target/armv8_dpm.h b/src/target/armv8_dpm.h
index c30b04f..19b33da 100644
--- a/src/target/armv8_dpm.h
+++ b/src/target/armv8_dpm.h
@@ -1,15 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (C) 2009 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#ifndef OPENOCD_TARGET_ARMV8_DPM_H
diff --git a/src/target/armv8_opcodes.c b/src/target/armv8_opcodes.c
index 96db728..7afcc52 100644
--- a/src/target/armv8_opcodes.c
+++ b/src/target/armv8_opcodes.c
@@ -1,16 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2015 by Matthias Welwarsky <matthias.welwarsky@sysgo.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv8_opcodes.h b/src/target/armv8_opcodes.h
index 8c213ef..8c9652b 100644
--- a/src/target/armv8_opcodes.h
+++ b/src/target/armv8_opcodes.h
@@ -1,17 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
- * Copyright (C) 2015 by pierrr kuo
- * vichy.kuo@gmail.com
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
+ * Copyright (C) 2015 by pierrr kuo <vichy.kuo@gmail.com>
*/
+
#ifndef OPENOCD_TARGET_ARMV8_OPCODES_H
#define OPENOCD_TARGET_ARMV8_OPCODES_H
@@ -146,9 +138,9 @@
(0xd500401f | ((op1) << 16) | ((crm) << 8) | ((op2) << 5))
#define ARMV8_MRS_T1(r, m1, rd, m) (0xF3E08020 | (r << 20) | (m1 << 16) | (rd << 8) | (m << 4))
-#define ARMV8_MRS_xPSR_T1(r, rd) (0xF3EF8000 | (r << 20) | (rd << 8))
+#define ARMV8_MRS_XPSR_T1(r, rd) (0xF3EF8000 | (r << 20) | (rd << 8))
#define ARMV8_MSR_GP_T1(r, m1, rd, m) (0xF3808020 | (r << 20) | (m1 << 8) | (rd << 16) | (m << 4))
-#define ARMV8_MSR_GP_xPSR_T1(r, rn, mask) (0xF3808000 | (r << 20) | (rn << 16) | (mask << 8))
+#define ARMV8_MSR_GP_XPSR_T1(r, rn, mask) (0xF3808000 | (r << 20) | (rn << 16) | (mask << 8))
#define ARMV8_BKPT(im) (0xD4200000 | ((im & 0xffff) << 5))
#define ARMV8_HLT(im) (0x0D4400000 | ((im & 0xffff) << 5))
diff --git a/src/target/avr32_ap7k.c b/src/target/avr32_ap7k.c
index 4cf0276..bf1445b 100644
--- a/src/target/avr32_ap7k.c
+++ b/src/target/avr32_ap7k.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
* Based on mips_m4k code: *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2008 by David T.L. Wong *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/avr32_ap7k.h b/src/target/avr32_ap7k.h
index 65b856e..ac35754 100644
--- a/src/target/avr32_ap7k.h
+++ b/src/target/avr32_ap7k.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_AVR32_AP7K_H
@@ -20,9 +9,11 @@
struct target;
-#define AP7K_COMMON_MAGIC 0x4150374b
+#define AP7K_COMMON_MAGIC 0x4150374bU
+
struct avr32_ap7k_common {
- int common_magic;
+ unsigned int common_magic;
+
struct avr32_jtag jtag;
struct reg_cache *core_cache;
uint32_t core_regs[AVR32NUMCOREREGS];
diff --git a/src/target/avr32_jtag.c b/src/target/avr32_jtag.c
index a23ddf7..a9c4f8d 100644
--- a/src/target/avr32_jtag.c
+++ b/src/target/avr32_jtag.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/avr32_jtag.h b/src/target/avr32_jtag.h
index b431ef4..382b245 100644
--- a/src/target/avr32_jtag.h
+++ b/src/target/avr32_jtag.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_AVR32_JTAG_H
diff --git a/src/target/avr32_mem.c b/src/target/avr32_mem.c
index 8f38a18..835a501 100644
--- a/src/target/avr32_mem.c
+++ b/src/target/avr32_mem.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/avr32_mem.h b/src/target/avr32_mem.h
index f60a121..4a8019a 100644
--- a/src/target/avr32_mem.h
+++ b/src/target/avr32_mem.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_AVR32_MEM_H
diff --git a/src/target/avr32_regs.c b/src/target/avr32_regs.c
index 7273822..d6fd0e0 100644
--- a/src/target/avr32_regs.c
+++ b/src/target/avr32_regs.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/avr32_regs.h b/src/target/avr32_regs.h
index cb492a9..9004657 100644
--- a/src/target/avr32_regs.h
+++ b/src/target/avr32_regs.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_AVR32_REGS_H
diff --git a/src/target/avrt.c b/src/target/avrt.c
index feceec6..61bef32 100644
--- a/src/target/avrt.c
+++ b/src/target/avrt.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Simon Qian *
* SimonQian@SimonQian.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/avrt.h b/src/target/avrt.h
index 3610eb5..615cb8a 100644
--- a/src/target/avrt.h
+++ b/src/target/avrt.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Simon Qian *
* SimonQian@SimonQian.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_AVRT_H
diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c
index 1055ed9..7bdb2a6 100644
--- a/src/target/breakpoints.c
+++ b/src/target/breakpoints.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) ST-Ericsson SA 2011 *
* michel.jaouen@stericsson.com : smp minimum support *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -404,7 +393,7 @@ struct breakpoint *breakpoint_find(struct target *target, target_addr_t address)
return NULL;
}
-int watchpoint_add_internal(struct target *target, target_addr_t address,
+static int watchpoint_add_internal(struct target *target, target_addr_t address,
uint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask)
{
struct watchpoint *watchpoint = target->watchpoints;
@@ -514,7 +503,7 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint
free(watchpoint);
}
-int watchpoint_remove_internal(struct target *target, target_addr_t address)
+static int watchpoint_remove_internal(struct target *target, target_addr_t address)
{
struct watchpoint *watchpoint = target->watchpoints;
diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h
index fc5b50b..8a3fbb2 100644
--- a/src/target/breakpoints.h
+++ b/src/target/breakpoints.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_BREAKPOINTS_H
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 20b2e51..7286a30 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -26,19 +28,6 @@
* Copyright (C) 2016 Chengyu Zheng *
* chengyu.zheng@polimi.it : watchpoint support *
* *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- * *
* Cortex-A8(tm) TRM, ARM DDI 0344H *
* Cortex-A9(tm) TRM, ARM DDI 0407F *
* Cortex-A4(tm) TRM, ARM DDI 0363E *
@@ -818,11 +807,11 @@ static int cortex_a_internal_restore(struct target *target, int current,
armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = true;
/* Make sure we are in Thumb mode */
- buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
- buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0,
+ buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_XPSR].value, 0, 32,
+ buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_XPSR].value, 0,
32) | (1 << 24));
- armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = true;
- armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = true;
+ armv7m->core_cache->reg_list[ARMV7M_XPSR].dirty = true;
+ armv7m->core_cache->reg_list[ARMV7M_XPSR].valid = true;
}
#endif
@@ -2885,15 +2874,24 @@ 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_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap);
+ 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_ap(swjdp, pc->ap_num);
+ armv7a->debug_ap = dap_get_ap(swjdp, pc->ap_num);
+ if (!armv7a->debug_ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
retval = mem_ap_init(armv7a->debug_ap);
@@ -3172,6 +3170,9 @@ static void cortex_a_deinit_target(struct target *target)
dscr & ~DSCR_HALT_DBG_MODE);
}
+ if (armv7a->debug_ap)
+ dap_put_ap(armv7a->debug_ap);
+
free(cortex_a->wrp_list);
free(cortex_a->brp_list);
arm_free_reg_cache(dpm->arm);
diff --git a/src/target/cortex_a.h b/src/target/cortex_a.h
index 685621c..37fba1a 100644
--- a/src/target/cortex_a.h
+++ b/src/target/cortex_a.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2009 by Dirk Behme *
* dirk.behme@gmail.com - copy from cortex_m3 *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_CORTEX_A_H
@@ -30,8 +19,7 @@
#include "armv7a.h"
-#define CORTEX_A_COMMON_MAGIC 0x411fc082
-#define CORTEX_A15_COMMON_MAGIC 0x413fc0f1
+#define CORTEX_A_COMMON_MAGIC 0x411fc082U
#define CORTEX_A5_PARTNUM 0xc05
#define CORTEX_A7_PARTNUM 0xc07
@@ -79,7 +67,9 @@ struct cortex_a_wrp {
};
struct cortex_a_common {
- int common_magic;
+ unsigned int common_magic;
+
+ struct armv7a_common armv7a_common;
/* Context information */
uint32_t cpudbg_dscr;
@@ -108,9 +98,6 @@ struct cortex_a_common {
enum cortex_a_isrmasking_mode isrmasking_mode;
enum cortex_a_dacrfixup_mode dacrfixup_mode;
-
- struct armv7a_common armv7a_common;
-
};
static inline struct cortex_a_common *
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 344cfcf..23d9065 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -8,19 +10,6 @@
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- * *
* *
* Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
* *
@@ -114,6 +103,12 @@ static const struct cortex_m_part_info cortex_m_parts[] = {
.arch = ARM_ARCH_V8M,
.flags = CORTEX_M_F_HAS_FPV5,
},
+ {
+ .partno = STAR_MC1_PARTNO,
+ .name = "STAR-MC1",
+ .arch = ARM_ARCH_V8M,
+ .flags = CORTEX_M_F_HAS_FPV5,
+ },
};
/* forward declarations */
@@ -663,6 +658,11 @@ static int cortex_m_endreset_event(struct target *target)
register_cache_invalidate(armv7m->arm.core_cache);
+ /* TODO: invalidate also working areas (needed in the case of detected reset).
+ * Doing so will require flash drivers to test if working area
+ * is still valid in all target algo calling loops.
+ */
+
/* make sure we have latest dhcsr flags */
retval = cortex_m_read_dhcsr_atomic_sticky(target);
if (retval != ERROR_OK)
@@ -775,7 +775,7 @@ static int cortex_m_examine_exception_reason(struct target *target)
static int cortex_m_debug_entry(struct target *target)
{
- uint32_t xPSR;
+ uint32_t xpsr;
int retval;
struct cortex_m_common *cortex_m = target_to_cm(target);
struct armv7m_common *armv7m = &cortex_m->armv7m;
@@ -826,11 +826,11 @@ static int cortex_m_debug_entry(struct target *target)
return retval;
r = arm->cpsr;
- xPSR = buf_get_u32(r->value, 0, 32);
+ xpsr = buf_get_u32(r->value, 0, 32);
/* Are we in an exception handler */
- if (xPSR & 0x1FF) {
- armv7m->exception_number = (xPSR & 0x1FF);
+ if (xpsr & 0x1FF) {
+ armv7m->exception_number = (xpsr & 0x1FF);
arm->core_mode = ARM_MODE_HANDLER;
arm->map = armv7m_msp_reg_map;
@@ -879,6 +879,16 @@ 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) {
@@ -1904,7 +1914,7 @@ int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpo
return ERROR_OK;
}
-int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
+static int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
{
if (target->debug_reason != DBG_REASON_WATCHPOINT)
return ERROR_FAIL;
@@ -1984,6 +1994,10 @@ static int cortex_m_init_target(struct command_context *cmd_ctx,
void cortex_m_deinit_target(struct target *target)
{
struct cortex_m_common *cortex_m = target_to_cm(target);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+
+ if (!armv7m->is_hla_target && armv7m->debug_ap)
+ dap_put_ap(armv7m->debug_ap);
free(cortex_m->fp_comparator_list);
@@ -2262,10 +2276,10 @@ static void cortex_m_dwt_free(struct target *target)
static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,
struct adiv5_ap **debug_ap)
{
- if (dap_find_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
+ if (dap_find_get_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
return ERROR_OK;
- return dap_find_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
+ return dap_find_get_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
}
int cortex_m_examine(struct target *target)
@@ -2279,6 +2293,11 @@ 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);
@@ -2287,7 +2306,11 @@ int cortex_m_examine(struct target *target)
return retval;
}
} else {
- armv7m->debug_ap = dap_ap(swjdp, cortex_m->apsel);
+ armv7m->debug_ap = dap_get_ap(swjdp, cortex_m->apsel);
+ if (!armv7m->debug_ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
armv7m->debug_ap->memaccess_tck = 8;
@@ -2384,6 +2407,20 @@ int cortex_m_examine(struct target *target)
retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr);
if (retval != ERROR_OK)
return retval;
+
+ /* Don't cumulate sticky S_RESET_ST at the very first read of DHCSR
+ * as S_RESET_ST may indicate a reset that happened long time ago
+ * (most probably the power-on reset before OpenOCD was started).
+ * As we are just initializing the debug system we do not need
+ * to call cortex_m_endreset_event() in the following poll.
+ */
+ if (!cortex_m->dcb_dhcsr_sticky_is_recent) {
+ cortex_m->dcb_dhcsr_sticky_is_recent = true;
+ if (cortex_m->dcb_dhcsr & S_RESET_ST) {
+ LOG_TARGET_DEBUG(target, "reset happened some time ago, ignore");
+ cortex_m->dcb_dhcsr &= ~S_RESET_ST;
+ }
+ }
cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr);
if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {
diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h
index 5554014..b1de26e 100644
--- a/src/target/cortex_m.h
+++ b/src/target/cortex_m.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_CORTEX_M_H
@@ -28,7 +17,7 @@
#include "armv7m.h"
#include "helper/bits.h"
-#define CORTEX_M_COMMON_MAGIC 0x1A451A45
+#define CORTEX_M_COMMON_MAGIC 0x1A451A45U
#define SYSTEM_CONTROL_BASE 0x400FE000
@@ -47,6 +36,7 @@
enum cortex_m_partno {
CORTEX_M_PARTNO_INVALID,
+ STAR_MC1_PARTNO = 0x132,
CORTEX_M0_PARTNO = 0xC20,
CORTEX_M1_PARTNO = 0xC21,
CORTEX_M3_PARTNO = 0xC23,
@@ -210,11 +200,15 @@ enum cortex_m_isrmasking_mode {
};
struct cortex_m_common {
- int common_magic;
+ unsigned int common_magic;
+
+ struct armv7m_common armv7m;
/* Context information */
uint32_t dcb_dhcsr;
uint32_t dcb_dhcsr_cumulated_sticky;
+ /* DCB DHCSR has been at least once read, so the sticky bits have been reset */
+ bool dcb_dhcsr_sticky_is_recent;
uint32_t nvic_dfsr; /* Debug Fault Status Register - shows reason for debug halt */
uint32_t nvic_icsr; /* Interrupt Control State Register - shows active and pending IRQ */
@@ -237,11 +231,10 @@ struct cortex_m_common {
enum cortex_m_isrmasking_mode isrmasking_mode;
const struct cortex_m_part_info *core_info;
- struct armv7m_common armv7m;
bool slow_register_read; /* A register has not been ready, poll S_REGRDY */
- int apsel;
+ uint64_t apsel;
/* Whether this target has the erratum that makes C_MASKINTS not apply to
* already pending interrupts */
diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c
index fdec95f..9db54fb 100644
--- a/src/target/dsp563xx.c
+++ b/src/target/dsp563xx.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009-2011 by Mathias Kuester *
* mkdorg@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -2151,7 +2140,7 @@ COMMAND_HANDLER(dsp563xx_mem_command)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count);
}
- buffer = calloc(count, sizeof(uint32_t));
+ buffer = calloc(count, 4);
if (read_mem == 1) {
err = dsp563xx_read_memory(target, mem_type, address, sizeof(uint32_t),
diff --git a/src/target/dsp563xx.h b/src/target/dsp563xx.h
index 5c3e1d3..9468bf3 100644
--- a/src/target/dsp563xx.h
+++ b/src/target/dsp563xx.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009-2011 by Mathias Kuester *
* mkdorg@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_DSP563XX_H
diff --git a/src/target/dsp563xx_once.c b/src/target/dsp563xx_once.c
index 624474d..2244506 100644
--- a/src/target/dsp563xx_once.c
+++ b/src/target/dsp563xx_once.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Mathias Kuester *
* mkdorg@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/dsp563xx_once.h b/src/target/dsp563xx_once.h
index 811c086..8715488 100644
--- a/src/target/dsp563xx_once.h
+++ b/src/target/dsp563xx_once.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2009 by Mathias Kuester *
* mkdorg@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_DSP563XX_ONCE_H
diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c
index 939b09d..37cf059 100644
--- a/src/target/dsp5680xx.c
+++ b/src/target/dsp5680xx.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Rodrigo L. Rosa *
* rodrigorosa.LG@gmail.com *
* *
* Based on dsp563xx_once.h written by Mathias Kuester *
* mkdorg@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -27,7 +16,7 @@
#include "target_type.h"
#include "dsp5680xx.h"
-struct dsp5680xx_common dsp5680xx_context;
+static struct dsp5680xx_common dsp5680xx_context;
#define _E "DSP5680XX_ERROR:%d\nAt:%s:%d:%s"
#define err_check(r, c, m) if (r != ERROR_OK) {LOG_ERROR(_E, c, __func__, __LINE__, m); return r; }
diff --git a/src/target/dsp5680xx.h b/src/target/dsp5680xx.h
index b969417..152f446 100644
--- a/src/target/dsp5680xx.h
+++ b/src/target/dsp5680xx.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Rodrigo L. Rosa *
* rodrigorosa.LG@gmail.com *
* *
* Based on dsp563xx_once.h written by Mathias Kuester *
* mkdorg@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_DSP5680XX_H
@@ -289,8 +278,6 @@ struct dsp5680xx_common {
bool debug_mode_enabled;
};
-extern struct dsp5680xx_common dsp5680xx_context;
-
static inline struct dsp5680xx_common *target_to_dsp5680xx(struct target
*target)
{
diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c
index a29508b..7aef153 100644
--- a/src/target/embeddedice.c
+++ b/src/target/embeddedice.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/embeddedice.h b/src/target/embeddedice.h
index f57f141..32acd70 100644
--- a/src/target/embeddedice.h
+++ b/src/target/embeddedice.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005, 2006 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_EMBEDDEDICE_H
diff --git a/src/target/esirisc.c b/src/target/esirisc.c
index aadd111..f86d28d 100644
--- a/src/target/esirisc.c
+++ b/src/target/esirisc.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* James Zhao <hjz@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/esirisc.h b/src/target/esirisc.h
index ad14223..7496b1e 100644
--- a/src/target/esirisc.h
+++ b/src/target/esirisc.h
@@ -1,20 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2018 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* James Zhao <hjz@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ESIRISC_H
diff --git a/src/target/esirisc_jtag.c b/src/target/esirisc_jtag.c
index dd5cd5a..54abc40 100644
--- a/src/target/esirisc_jtag.c
+++ b/src/target/esirisc_jtag.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* James Zhao <hjz@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/esirisc_jtag.h b/src/target/esirisc_jtag.h
index 5f8fe66..98ec8af 100644
--- a/src/target/esirisc_jtag.h
+++ b/src/target/esirisc_jtag.h
@@ -1,20 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2018 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* James Zhao <hjz@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ESIRISC_JTAG_H
diff --git a/src/target/esirisc_regs.h b/src/target/esirisc_regs.h
index 6ccda50..51e7e61 100644
--- a/src/target/esirisc_regs.h
+++ b/src/target/esirisc_regs.h
@@ -1,20 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2018 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* James Zhao <hjz@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ESIRISC_REGS_H
diff --git a/src/target/esirisc_trace.c b/src/target/esirisc_trace.c
index d17a65d..376ea1d 100644
--- a/src/target/esirisc_trace.c
+++ b/src/target/esirisc_trace.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/esirisc_trace.h b/src/target/esirisc_trace.h
index c3cc6e9..9c08d96 100644
--- a/src/target/esirisc_trace.h
+++ b/src/target/esirisc_trace.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2018 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ESIRISC_TRACE_H
diff --git a/src/target/espressif/Makefile.am b/src/target/espressif/Makefile.am
index c681e09..8367a38 100644
--- a/src/target/espressif/Makefile.am
+++ b/src/target/espressif/Makefile.am
@@ -1,6 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libespressif.la
%C%_libespressif_la_SOURCES = \
%D%/esp_xtensa.c \
%D%/esp_xtensa.h \
+ %D%/esp_xtensa_smp.c \
+ %D%/esp_xtensa_smp.h \
+ %D%/esp_xtensa_semihosting.c \
+ %D%/esp_xtensa_semihosting.h \
+ %D%/esp32.c \
%D%/esp32s2.c \
- %D%/esp32s2.h
+ %D%/esp32s3.c \
+ %D%/esp_semihosting.c \
+ %D%/esp_semihosting.h
diff --git a/src/target/espressif/esp32.c b/src/target/espressif/esp32.c
new file mode 100644
index 0000000..63055cf
--- /dev/null
+++ b/src/target/espressif/esp32.c
@@ -0,0 +1,503 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * ESP32 target API for OpenOCD *
+ * Copyright (C) 2016-2019 Espressif Systems Ltd. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <helper/time_support.h>
+#include <target/target.h>
+#include <target/target_type.h>
+#include <target/smp.h>
+#include <target/semihosting_common.h>
+#include "assert.h"
+#include "esp_xtensa_smp.h"
+
+/*
+This is a JTAG driver for the ESP32, the are two Tensilica cores inside
+the ESP32 chip. For more information please have a look into ESP32 target
+implementation.
+*/
+
+/* ESP32 memory map */
+#define ESP32_DRAM_LOW 0x3ffae000
+#define ESP32_DRAM_HIGH 0x40000000
+#define ESP32_IROM_MASK_LOW 0x40000000
+#define ESP32_IROM_MASK_HIGH 0x40064f00
+#define ESP32_IRAM_LOW 0x40070000
+#define ESP32_IRAM_HIGH 0x400a0000
+#define ESP32_RTC_IRAM_LOW 0x400c0000
+#define ESP32_RTC_IRAM_HIGH 0x400c2000
+#define ESP32_RTC_DRAM_LOW 0x3ff80000
+#define ESP32_RTC_DRAM_HIGH 0x3ff82000
+#define ESP32_RTC_DATA_LOW 0x50000000
+#define ESP32_RTC_DATA_HIGH 0x50002000
+#define ESP32_EXTRAM_DATA_LOW 0x3f800000
+#define ESP32_EXTRAM_DATA_HIGH 0x3fc00000
+#define ESP32_DR_REG_LOW 0x3ff00000
+#define ESP32_DR_REG_HIGH 0x3ff71000
+#define ESP32_SYS_RAM_LOW 0x60000000UL
+#define ESP32_SYS_RAM_HIGH (ESP32_SYS_RAM_LOW + 0x20000000UL)
+#define ESP32_RTC_SLOW_MEM_BASE ESP32_RTC_DATA_LOW
+
+/* ESP32 WDT */
+#define ESP32_WDT_WKEY_VALUE 0x50d83aa1
+#define ESP32_TIMG0_BASE 0x3ff5f000
+#define ESP32_TIMG1_BASE 0x3ff60000
+#define ESP32_TIMGWDT_CFG0_OFF 0x48
+#define ESP32_TIMGWDT_PROTECT_OFF 0x64
+#define ESP32_TIMG0WDT_CFG0 (ESP32_TIMG0_BASE + ESP32_TIMGWDT_CFG0_OFF)
+#define ESP32_TIMG1WDT_CFG0 (ESP32_TIMG1_BASE + ESP32_TIMGWDT_CFG0_OFF)
+#define ESP32_TIMG0WDT_PROTECT (ESP32_TIMG0_BASE + ESP32_TIMGWDT_PROTECT_OFF)
+#define ESP32_TIMG1WDT_PROTECT (ESP32_TIMG1_BASE + ESP32_TIMGWDT_PROTECT_OFF)
+#define ESP32_RTCCNTL_BASE 0x3ff48000
+#define ESP32_RTCWDT_CFG_OFF 0x8C
+#define ESP32_RTCWDT_PROTECT_OFF 0xA4
+#define ESP32_RTCWDT_CFG (ESP32_RTCCNTL_BASE + ESP32_RTCWDT_CFG_OFF)
+#define ESP32_RTCWDT_PROTECT (ESP32_RTCCNTL_BASE + ESP32_RTCWDT_PROTECT_OFF)
+
+#define ESP32_TRACEMEM_BLOCK_SZ 0x4000
+
+/* ESP32 dport regs */
+#define ESP32_DR_REG_DPORT_BASE ESP32_DR_REG_LOW
+#define ESP32_DPORT_APPCPU_CTRL_B_REG (ESP32_DR_REG_DPORT_BASE + 0x030)
+#define ESP32_DPORT_APPCPU_CLKGATE_EN BIT(0)
+/* ESP32 RTC regs */
+#define ESP32_RTC_CNTL_SW_CPU_STALL_REG (ESP32_RTCCNTL_BASE + 0xac)
+#define ESP32_RTC_CNTL_SW_CPU_STALL_DEF 0x0
+
+/* 0 - don't care, 1 - TMS low, 2 - TMS high */
+enum esp32_flash_bootstrap {
+ FBS_DONTCARE = 0,
+ FBS_TMSLOW,
+ FBS_TMSHIGH,
+};
+
+struct esp32_common {
+ struct esp_xtensa_smp_common esp_xtensa_smp;
+ enum esp32_flash_bootstrap flash_bootstrap;
+};
+
+static inline struct esp32_common *target_to_esp32(struct target *target)
+{
+ return container_of(target->arch_info, struct esp32_common, esp_xtensa_smp);
+}
+
+/* Reset ESP32 peripherals.
+ * Postconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted,
+ * APP CPU is in reset
+ * How this works:
+ * 0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt
+ * 1. set CPU initial PC to 0x50000000 (ESP32_SMP_RTC_DATA_LOW) by clearing RTC_CNTL_{PRO,APP}CPU_STAT_VECTOR_SEL
+ * 2. load stub code into ESP32_SMP_RTC_DATA_LOW; once executed, stub code will disable watchdogs and
+ * make CPU spin in an idle loop.
+ * 3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit
+ * 4. wait for the OCD to be reset
+ * 5. halt the target and wait for it to be halted (at this point CPU is in the idle loop)
+ * 6. restore initial PC and the contents of ESP32_SMP_RTC_DATA_LOW
+ * TODO: some state of RTC_CNTL is not reset during SW_SYS_RST. Need to reset that manually. */
+
+static const uint8_t esp32_reset_stub_code[] = {
+#include "../../../contrib/loaders/reset/espressif/esp32/cpu_reset_handler_code.inc"
+};
+
+static int esp32_soc_reset(struct target *target)
+{
+ int res;
+ struct target_list *head;
+ struct xtensa *xtensa;
+
+ LOG_DEBUG("start");
+ /* In order to write to peripheral registers, target must be halted first */
+ if (target->state != TARGET_HALTED) {
+ LOG_DEBUG("Target not halted before SoC reset, trying to halt it first");
+ xtensa_halt(target);
+ res = target_wait_state(target, TARGET_HALTED, 1000);
+ if (res != ERROR_OK) {
+ LOG_DEBUG("Couldn't halt target before SoC reset, trying to do reset-halt");
+ res = xtensa_assert_reset(target);
+ if (res != ERROR_OK) {
+ LOG_ERROR(
+ "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
+ res);
+ return res;
+ }
+ alive_sleep(10);
+ xtensa_poll(target);
+ bool reset_halt_save = target->reset_halt;
+ target->reset_halt = true;
+ res = xtensa_deassert_reset(target);
+ target->reset_halt = reset_halt_save;
+ if (res != ERROR_OK) {
+ LOG_ERROR(
+ "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
+ res);
+ return res;
+ }
+ alive_sleep(10);
+ xtensa_poll(target);
+ xtensa_halt(target);
+ res = target_wait_state(target, TARGET_HALTED, 1000);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Couldn't halt target before SoC reset");
+ return res;
+ }
+ }
+ }
+
+ if (target->smp) {
+ foreach_smp_target(head, target->smp_targets) {
+ xtensa = target_to_xtensa(head->target);
+ /* if any of the cores is stalled unstall them */
+ if (xtensa_dm_core_is_stalled(&xtensa->dbg_mod)) {
+ LOG_TARGET_DEBUG(head->target, "Unstall CPUs before SW reset!");
+ res = target_write_u32(target,
+ ESP32_RTC_CNTL_SW_CPU_STALL_REG,
+ ESP32_RTC_CNTL_SW_CPU_STALL_DEF);
+ if (res != ERROR_OK) {
+ LOG_TARGET_ERROR(head->target, "Failed to unstall CPUs before SW reset!");
+ return res;
+ }
+ break; /* both cores are unstalled now, so exit the loop */
+ }
+ }
+ }
+
+ LOG_DEBUG("Loading stub code into RTC RAM");
+ uint8_t slow_mem_save[sizeof(esp32_reset_stub_code)];
+
+ /* Save contents of RTC_SLOW_MEM which we are about to overwrite */
+ res = target_read_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to save contents of RTC_SLOW_MEM (%d)!", res);
+ return res;
+ }
+
+ /* Write stub code into RTC_SLOW_MEM */
+ res = target_write_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(esp32_reset_stub_code), esp32_reset_stub_code);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write stub (%d)!", res);
+ return res;
+ }
+
+ LOG_DEBUG("Resuming the target");
+ xtensa = target_to_xtensa(target);
+ xtensa->suppress_dsr_errors = true;
+ res = xtensa_resume(target, 0, ESP32_RTC_SLOW_MEM_BASE + 4, 0, 0);
+ xtensa->suppress_dsr_errors = false;
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to run stub (%d)!", res);
+ return res;
+ }
+ LOG_DEBUG("resume done, waiting for the target to come alive");
+
+ /* Wait for SoC to reset */
+ alive_sleep(100);
+ int64_t timeout = timeval_ms() + 100;
+ bool get_timeout = false;
+ while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
+ alive_sleep(10);
+ xtensa_poll(target);
+ if (timeval_ms() >= timeout) {
+ LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d",
+ target->state);
+ get_timeout = true;
+ break;
+ }
+ }
+
+ /* Halt the CPU again */
+ LOG_DEBUG("halting the target");
+ xtensa_halt(target);
+ res = target_wait_state(target, TARGET_HALTED, 1000);
+ if (res == ERROR_OK) {
+ LOG_DEBUG("restoring RTC_SLOW_MEM");
+ res = target_write_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);
+ if (res != ERROR_OK)
+ LOG_TARGET_ERROR(target, "Failed to restore contents of RTC_SLOW_MEM (%d)!", res);
+ } else {
+ LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be halted after SoC reset");
+ }
+
+ return get_timeout ? ERROR_TARGET_TIMEOUT : res;
+}
+
+static int esp32_disable_wdts(struct target *target)
+{
+ /* TIMG1 WDT */
+ int res = target_write_u32(target, ESP32_TIMG0WDT_PROTECT, ESP32_WDT_WKEY_VALUE);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_TIMG0WDT_PROTECT (%d)!", res);
+ return res;
+ }
+ res = target_write_u32(target, ESP32_TIMG0WDT_CFG0, 0);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_TIMG0WDT_CFG0 (%d)!", res);
+ return res;
+ }
+ /* TIMG2 WDT */
+ res = target_write_u32(target, ESP32_TIMG1WDT_PROTECT, ESP32_WDT_WKEY_VALUE);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_TIMG1WDT_PROTECT (%d)!", res);
+ return res;
+ }
+ res = target_write_u32(target, ESP32_TIMG1WDT_CFG0, 0);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_TIMG1WDT_CFG0 (%d)!", res);
+ return res;
+ }
+ /* RTC WDT */
+ res = target_write_u32(target, ESP32_RTCWDT_PROTECT, ESP32_WDT_WKEY_VALUE);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_RTCWDT_PROTECT (%d)!", res);
+ return res;
+ }
+ res = target_write_u32(target, ESP32_RTCWDT_CFG, 0);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_RTCWDT_CFG (%d)!", res);
+ return res;
+ }
+ return ERROR_OK;
+}
+
+static int esp32_on_halt(struct target *target)
+{
+ return esp32_disable_wdts(target);
+}
+
+static int esp32_arch_state(struct target *target)
+{
+ return ERROR_OK;
+}
+
+static int esp32_virt2phys(struct target *target,
+ target_addr_t virtual, target_addr_t *physical)
+{
+ if (physical) {
+ *physical = virtual;
+ return ERROR_OK;
+ }
+ return ERROR_FAIL;
+}
+
+/* The TDI pin is also used as a flash Vcc bootstrap pin. If we reset the CPU externally, the last state of the TDI pin
+ * can allow the power to an 1.8V flash chip to be raised to 3.3V, or the other way around. Users can use the
+ * esp32 flashbootstrap command to set a level, and this routine will make sure the tdi line will return to
+ * that when the jtag port is idle. */
+
+static void esp32_queue_tdi_idle(struct target *target)
+{
+ struct esp32_common *esp32 = target_to_esp32(target);
+ static uint32_t value;
+ uint8_t t[4] = { 0, 0, 0, 0 };
+
+ if (esp32->flash_bootstrap == FBS_TMSLOW)
+ /* Make sure tdi is 0 at the exit of queue execution */
+ value = 0;
+ else if (esp32->flash_bootstrap == FBS_TMSHIGH)
+ /* Make sure tdi is 1 at the exit of queue execution */
+ value = 1;
+ else
+ return;
+
+ /* Scan out 1 bit, do not move from IRPAUSE after we're done. */
+ buf_set_u32(t, 0, 1, value);
+ jtag_add_plain_ir_scan(1, t, NULL, TAP_IRPAUSE);
+}
+
+static int esp32_target_init(struct command_context *cmd_ctx, struct target *target)
+{
+ return esp_xtensa_smp_target_init(cmd_ctx, target);
+}
+
+static const struct xtensa_debug_ops esp32_dbg_ops = {
+ .queue_enable = xtensa_dm_queue_enable,
+ .queue_reg_read = xtensa_dm_queue_reg_read,
+ .queue_reg_write = xtensa_dm_queue_reg_write
+};
+
+static const struct xtensa_power_ops esp32_pwr_ops = {
+ .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
+ .queue_reg_write = xtensa_dm_queue_pwr_reg_write
+};
+
+static const struct esp_xtensa_smp_chip_ops esp32_chip_ops = {
+ .reset = esp32_soc_reset,
+ .on_halt = esp32_on_halt
+};
+
+static const struct esp_semihost_ops esp32_semihost_ops = {
+ .prepare = esp32_disable_wdts
+};
+
+static int esp32_target_create(struct target *target, Jim_Interp *interp)
+{
+ struct xtensa_debug_module_config esp32_dm_cfg = {
+ .dbg_ops = &esp32_dbg_ops,
+ .pwr_ops = &esp32_pwr_ops,
+ .tap = target->tap,
+ .queue_tdi_idle = esp32_queue_tdi_idle,
+ .queue_tdi_idle_arg = target
+ };
+
+ struct esp32_common *esp32 = calloc(1, sizeof(struct esp32_common));
+ if (!esp32) {
+ LOG_ERROR("Failed to alloc memory for arch info!");
+ return ERROR_FAIL;
+ }
+
+ int ret = esp_xtensa_smp_init_arch_info(target, &esp32->esp_xtensa_smp,
+ &esp32_dm_cfg, &esp32_chip_ops, &esp32_semihost_ops);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Failed to init arch info!");
+ free(esp32);
+ return ret;
+ }
+ esp32->flash_bootstrap = FBS_DONTCARE;
+
+ /* Assume running target. If different, the first poll will fix this. */
+ target->state = TARGET_RUNNING;
+ target->debug_reason = DBG_REASON_NOTHALTED;
+ return ERROR_OK;
+}
+
+static COMMAND_HELPER(esp32_cmd_flashbootstrap_do, struct esp32_common *esp32)
+{
+ int state = -1;
+
+ if (CMD_ARGC < 1) {
+ const char *st;
+ state = esp32->flash_bootstrap;
+ if (state == FBS_DONTCARE)
+ st = "Don't care";
+ else if (state == FBS_TMSLOW)
+ st = "Low (3.3V)";
+ else if (state == FBS_TMSHIGH)
+ st = "High (1.8V)";
+ else
+ st = "None";
+ command_print(CMD, "Current idle tms state: %s", st);
+ return ERROR_OK;
+ }
+
+ if (!strcasecmp(CMD_ARGV[0], "none"))
+ state = FBS_DONTCARE;
+ else if (!strcasecmp(CMD_ARGV[0], "1.8"))
+ state = FBS_TMSHIGH;
+ else if (!strcasecmp(CMD_ARGV[0], "3.3"))
+ state = FBS_TMSLOW;
+ else if (!strcasecmp(CMD_ARGV[0], "high"))
+ state = FBS_TMSHIGH;
+ else if (!strcasecmp(CMD_ARGV[0], "low"))
+ state = FBS_TMSLOW;
+
+ if (state == -1) {
+ command_print(CMD,
+ "Argument unknown. Please pick one of none, high, low, 1.8 or 3.3");
+ return ERROR_FAIL;
+ }
+ esp32->flash_bootstrap = state;
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(esp32_cmd_flashbootstrap)
+{
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (target->smp) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do,
+ target_to_esp32(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do,
+ target_to_esp32(target));
+}
+
+static const struct command_registration esp32_any_command_handlers[] = {
+ {
+ .name = "flashbootstrap",
+ .handler = esp32_cmd_flashbootstrap,
+ .mode = COMMAND_ANY,
+ .help =
+ "Set the idle state of the TMS pin, which at reset also is the voltage selector for the flash chip.",
+ .usage = "none|1.8|3.3|high|low",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration esp32_command_handlers[] = {
+ {
+ .chain = esp_xtensa_smp_command_handlers,
+ },
+ {
+ .name = "esp32",
+ .usage = "",
+ .chain = smp_command_handlers,
+ },
+ {
+ .name = "esp32",
+ .usage = "",
+ .chain = esp32_any_command_handlers,
+ },
+ {
+ .name = "arm",
+ .mode = COMMAND_ANY,
+ .help = "ARM Command Group",
+ .usage = "",
+ .chain = semihosting_common_handlers
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+/** Holds methods for Xtensa targets. */
+struct target_type esp32_target = {
+ .name = "esp32",
+
+ .poll = esp_xtensa_smp_poll,
+ .arch_state = esp32_arch_state,
+
+ .halt = xtensa_halt,
+ .resume = esp_xtensa_smp_resume,
+ .step = esp_xtensa_smp_step,
+
+ .assert_reset = esp_xtensa_smp_assert_reset,
+ .deassert_reset = esp_xtensa_smp_deassert_reset,
+ .soft_reset_halt = esp_xtensa_smp_soft_reset_halt,
+
+ .virt2phys = esp32_virt2phys,
+ .mmu = xtensa_mmu_is_enabled,
+ .read_memory = xtensa_read_memory,
+ .write_memory = xtensa_write_memory,
+
+ .read_buffer = xtensa_read_buffer,
+ .write_buffer = xtensa_write_buffer,
+
+ .checksum_memory = xtensa_checksum_memory,
+
+ .get_gdb_arch = xtensa_get_gdb_arch,
+ .get_gdb_reg_list = xtensa_get_gdb_reg_list,
+
+ .add_breakpoint = esp_xtensa_breakpoint_add,
+ .remove_breakpoint = esp_xtensa_breakpoint_remove,
+
+ .add_watchpoint = esp_xtensa_smp_watchpoint_add,
+ .remove_watchpoint = esp_xtensa_smp_watchpoint_remove,
+
+ .target_create = esp32_target_create,
+ .init_target = esp32_target_init,
+ .examine = xtensa_examine,
+ .deinit_target = esp_xtensa_target_deinit,
+
+ .commands = esp32_command_handlers,
+};
diff --git a/src/target/espressif/esp32s2.c b/src/target/espressif/esp32s2.c
index 212533f..62d1ddb 100644
--- a/src/target/espressif/esp32s2.c
+++ b/src/target/espressif/esp32s2.c
@@ -1,31 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* ESP32-S2 target for OpenOCD *
* Copyright (C) 2019 Espressif Systems Ltd. *
- * Author: Alexey Gerenkov <alexey@espressif.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include <helper/time_support.h>
#include "assert.h"
#include <target/target.h>
#include <target/target_type.h>
+#include <target/semihosting_common.h>
#include "esp_xtensa.h"
-#include "esp32s2.h"
+#include "esp_xtensa_semihosting.h"
/* Overall memory map
* TODO: read memory configuration from target registers */
@@ -100,190 +90,6 @@
#define ESP32_S2_DR_REG_UART_BASE 0x3f400000
#define ESP32_S2_REG_UART_BASE(i) (ESP32_S2_DR_REG_UART_BASE + (i) * 0x10000)
#define ESP32_S2_UART_DATE_REG(i) (ESP32_S2_REG_UART_BASE(i) + 0x74)
-
-/* this should map local reg IDs to GDB reg mapping as defined in xtensa-config.c 'rmap' in
- * xtensa-overlay */
-static const unsigned int esp32s2_gdb_regs_mapping[ESP32_S2_NUM_REGS] = {
- XT_REG_IDX_PC,
- XT_REG_IDX_AR0, XT_REG_IDX_AR1, XT_REG_IDX_AR2, XT_REG_IDX_AR3,
- XT_REG_IDX_AR4, XT_REG_IDX_AR5, XT_REG_IDX_AR6, XT_REG_IDX_AR7,
- XT_REG_IDX_AR8, XT_REG_IDX_AR9, XT_REG_IDX_AR10, XT_REG_IDX_AR11,
- XT_REG_IDX_AR12, XT_REG_IDX_AR13, XT_REG_IDX_AR14, XT_REG_IDX_AR15,
- XT_REG_IDX_AR16, XT_REG_IDX_AR17, XT_REG_IDX_AR18, XT_REG_IDX_AR19,
- XT_REG_IDX_AR20, XT_REG_IDX_AR21, XT_REG_IDX_AR22, XT_REG_IDX_AR23,
- XT_REG_IDX_AR24, XT_REG_IDX_AR25, XT_REG_IDX_AR26, XT_REG_IDX_AR27,
- XT_REG_IDX_AR28, XT_REG_IDX_AR29, XT_REG_IDX_AR30, XT_REG_IDX_AR31,
- XT_REG_IDX_AR32, XT_REG_IDX_AR33, XT_REG_IDX_AR34, XT_REG_IDX_AR35,
- XT_REG_IDX_AR36, XT_REG_IDX_AR37, XT_REG_IDX_AR38, XT_REG_IDX_AR39,
- XT_REG_IDX_AR40, XT_REG_IDX_AR41, XT_REG_IDX_AR42, XT_REG_IDX_AR43,
- XT_REG_IDX_AR44, XT_REG_IDX_AR45, XT_REG_IDX_AR46, XT_REG_IDX_AR47,
- XT_REG_IDX_AR48, XT_REG_IDX_AR49, XT_REG_IDX_AR50, XT_REG_IDX_AR51,
- XT_REG_IDX_AR52, XT_REG_IDX_AR53, XT_REG_IDX_AR54, XT_REG_IDX_AR55,
- XT_REG_IDX_AR56, XT_REG_IDX_AR57, XT_REG_IDX_AR58, XT_REG_IDX_AR59,
- XT_REG_IDX_AR60, XT_REG_IDX_AR61, XT_REG_IDX_AR62, XT_REG_IDX_AR63,
- XT_REG_IDX_SAR,
- XT_REG_IDX_WINDOWBASE, XT_REG_IDX_WINDOWSTART, XT_REG_IDX_CONFIGID0, XT_REG_IDX_CONFIGID1,
- XT_REG_IDX_PS, XT_REG_IDX_THREADPTR,
- ESP32_S2_REG_IDX_GPIOOUT,
- XT_REG_IDX_MMID, XT_REG_IDX_IBREAKENABLE, XT_REG_IDX_OCD_DDR,
- XT_REG_IDX_IBREAKA0, XT_REG_IDX_IBREAKA1, XT_REG_IDX_DBREAKA0, XT_REG_IDX_DBREAKA1,
- XT_REG_IDX_DBREAKC0, XT_REG_IDX_DBREAKC1,
- XT_REG_IDX_EPC1, XT_REG_IDX_EPC2, XT_REG_IDX_EPC3, XT_REG_IDX_EPC4,
- XT_REG_IDX_EPC5, XT_REG_IDX_EPC6, XT_REG_IDX_EPC7, XT_REG_IDX_DEPC,
- XT_REG_IDX_EPS2, XT_REG_IDX_EPS3, XT_REG_IDX_EPS4, XT_REG_IDX_EPS5,
- XT_REG_IDX_EPS6, XT_REG_IDX_EPS7,
- XT_REG_IDX_EXCSAVE1, XT_REG_IDX_EXCSAVE2, XT_REG_IDX_EXCSAVE3, XT_REG_IDX_EXCSAVE4,
- XT_REG_IDX_EXCSAVE5, XT_REG_IDX_EXCSAVE6, XT_REG_IDX_EXCSAVE7, XT_REG_IDX_CPENABLE,
- XT_REG_IDX_INTERRUPT, XT_REG_IDX_INTSET, XT_REG_IDX_INTCLEAR, XT_REG_IDX_INTENABLE,
- XT_REG_IDX_VECBASE, XT_REG_IDX_EXCCAUSE, XT_REG_IDX_DEBUGCAUSE, XT_REG_IDX_CCOUNT,
- XT_REG_IDX_PRID, XT_REG_IDX_ICOUNT, XT_REG_IDX_ICOUNTLEVEL, XT_REG_IDX_EXCVADDR,
- XT_REG_IDX_CCOMPARE0, XT_REG_IDX_CCOMPARE1, XT_REG_IDX_CCOMPARE2,
- XT_REG_IDX_MISC0, XT_REG_IDX_MISC1, XT_REG_IDX_MISC2, XT_REG_IDX_MISC3,
- XT_REG_IDX_A0, XT_REG_IDX_A1, XT_REG_IDX_A2, XT_REG_IDX_A3,
- XT_REG_IDX_A4, XT_REG_IDX_A5, XT_REG_IDX_A6, XT_REG_IDX_A7,
- XT_REG_IDX_A8, XT_REG_IDX_A9, XT_REG_IDX_A10, XT_REG_IDX_A11,
- XT_REG_IDX_A12, XT_REG_IDX_A13, XT_REG_IDX_A14, XT_REG_IDX_A15,
- XT_REG_IDX_PWRCTL, XT_REG_IDX_PWRSTAT, XT_REG_IDX_ERISTAT,
- XT_REG_IDX_CS_ITCTRL, XT_REG_IDX_CS_CLAIMSET, XT_REG_IDX_CS_CLAIMCLR,
- XT_REG_IDX_CS_LOCKACCESS, XT_REG_IDX_CS_LOCKSTATUS, XT_REG_IDX_CS_AUTHSTATUS,
- XT_REG_IDX_FAULT_INFO,
- XT_REG_IDX_TRAX_ID, XT_REG_IDX_TRAX_CTRL, XT_REG_IDX_TRAX_STAT,
- XT_REG_IDX_TRAX_DATA, XT_REG_IDX_TRAX_ADDR, XT_REG_IDX_TRAX_PCTRIGGER,
- XT_REG_IDX_TRAX_PCMATCH, XT_REG_IDX_TRAX_DELAY, XT_REG_IDX_TRAX_MEMSTART,
- XT_REG_IDX_TRAX_MEMEND,
- XT_REG_IDX_PMG, XT_REG_IDX_PMPC, XT_REG_IDX_PM0, XT_REG_IDX_PM1,
- XT_REG_IDX_PMCTRL0, XT_REG_IDX_PMCTRL1, XT_REG_IDX_PMSTAT0, XT_REG_IDX_PMSTAT1,
- XT_REG_IDX_OCD_ID, XT_REG_IDX_OCD_DCRCLR, XT_REG_IDX_OCD_DCRSET, XT_REG_IDX_OCD_DSR,
-};
-
-static const struct xtensa_user_reg_desc esp32s2_user_regs[ESP32_S2_NUM_REGS - XT_NUM_REGS] = {
- { "gpio_out", 0x00, 0, 32, &xtensa_user_reg_u32_type },
-};
-
-static const struct xtensa_config esp32s2_xtensa_cfg = {
- .density = true,
- .aregs_num = XT_AREGS_NUM_MAX,
- .windowed = true,
- .coproc = true,
- .miscregs_num = 4,
- .reloc_vec = true,
- .proc_id = true,
- .threadptr = true,
- .user_regs_num = ARRAY_SIZE(esp32s2_user_regs),
- .user_regs = esp32s2_user_regs,
- .fetch_user_regs = xtensa_fetch_user_regs_u32,
- .queue_write_dirty_user_regs = xtensa_queue_write_dirty_user_regs_u32,
- .gdb_general_regs_num = ESP32_S2_NUM_REGS_G_COMMAND,
- .gdb_regs_mapping = esp32s2_gdb_regs_mapping,
- .irom = {
- .count = 2,
- .regions = {
- {
- .base = ESP32_S2_IROM_LOW,
- .size = ESP32_S2_IROM_HIGH - ESP32_S2_IROM_LOW,
- .access = XT_MEM_ACCESS_READ,
- },
- {
- .base = ESP32_S2_IROM_MASK_LOW,
- .size = ESP32_S2_IROM_MASK_HIGH - ESP32_S2_IROM_MASK_LOW,
- .access = XT_MEM_ACCESS_READ,
- },
- }
- },
- .iram = {
- .count = 2,
- .regions = {
- {
- .base = ESP32_S2_IRAM_LOW,
- .size = ESP32_S2_IRAM_HIGH - ESP32_S2_IRAM_LOW,
- .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
- },
- {
- .base = ESP32_S2_RTC_IRAM_LOW,
- .size = ESP32_S2_RTC_IRAM_HIGH - ESP32_S2_RTC_IRAM_LOW,
- .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
- },
- }
- },
- .drom = {
- .count = 2,
- .regions = {
- {
- .base = ESP32_S2_DROM0_LOW,
- .size = ESP32_S2_DROM0_HIGH - ESP32_S2_DROM0_LOW,
- .access = XT_MEM_ACCESS_READ,
- },
- {
- .base = ESP32_S2_DROM1_LOW,
- .size = ESP32_S2_DROM1_HIGH - ESP32_S2_DROM1_LOW,
- .access = XT_MEM_ACCESS_READ,
- },
- }
- },
- .dram = {
- .count = 6,
- .regions = {
- {
- .base = ESP32_S2_DRAM_LOW,
- .size = ESP32_S2_DRAM_HIGH - ESP32_S2_DRAM_LOW,
- .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
- },
- {
- .base = ESP32_S2_RTC_DRAM_LOW,
- .size = ESP32_S2_RTC_DRAM_HIGH - ESP32_S2_RTC_DRAM_LOW,
- .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
- },
- {
- .base = ESP32_S2_RTC_DATA_LOW,
- .size = ESP32_S2_RTC_DATA_HIGH - ESP32_S2_RTC_DATA_LOW,
- .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
- },
- {
- .base = ESP32_S2_EXTRAM_DATA_LOW,
- .size = ESP32_S2_EXTRAM_DATA_HIGH - ESP32_S2_EXTRAM_DATA_LOW,
- .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
- },
- {
- .base = ESP32_S2_DR_REG_LOW,
- .size = ESP32_S2_DR_REG_HIGH - ESP32_S2_DR_REG_LOW,
- .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
- },
- {
- .base = ESP32_S2_SYS_RAM_LOW,
- .size = ESP32_S2_SYS_RAM_HIGH - ESP32_S2_SYS_RAM_LOW,
- .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
- },
- }
- },
- .exc = {
- .enabled = true,
- },
- .irq = {
- .enabled = true,
- .irq_num = 32,
- },
- .high_irq = {
- .enabled = true,
- .excm_level = 3,
- .nmi_num = 1,
- },
- .tim_irq = {
- .enabled = true,
- .comp_num = 3,
- },
- .debug = {
- .enabled = true,
- .irq_level = 6,
- .ibreaks_num = 2,
- .dbreaks_num = 2,
- .icount_sz = 32,
- },
- .trace = {
- .enabled = true,
- .mem_sz = ESP32_S2_TRACEMEM_BLOCK_SZ,
- },
-};
-
struct esp32s2_common {
struct esp_xtensa_common esp_xtensa;
};
@@ -316,7 +122,7 @@ static int esp32s2_deassert_reset(struct target *target)
return ERROR_OK;
}
-int esp32s2_soft_reset_halt(struct target *target)
+static int esp32s2_soft_reset_halt(struct target *target)
{
LOG_TARGET_DEBUG(target, "begin");
@@ -324,7 +130,7 @@ int esp32s2_soft_reset_halt(struct target *target)
int res = esp32s2_soc_reset(target);
if (res != ERROR_OK)
return res;
- return xtensa_assert_reset(target);
+ return xtensa_soft_reset_halt(target);
}
static int esp32s2_set_peri_reg_mask(struct target *target,
@@ -474,7 +280,7 @@ static int esp32s2_soc_reset(struct target *target)
res = esp32s2_set_peri_reg_mask(target,
ESP32_S2_OPTIONS0,
ESP32_S2_SW_SYS_RST_M,
- 1U << ESP32_S2_SW_SYS_RST_S);
+ BIT(ESP32_S2_SW_SYS_RST_S));
xtensa->suppress_dsr_errors = false;
if (res != ERROR_OK) {
LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res);
@@ -482,15 +288,17 @@ static int esp32s2_soc_reset(struct target *target)
}
/* Wait for SoC to reset */
alive_sleep(100);
- int timeout = 100;
- while (target->state != TARGET_RESET && target->state != TARGET_RUNNING && --timeout > 0) {
+ int64_t timeout = timeval_ms() + 100;
+ while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
alive_sleep(10);
xtensa_poll(target);
+ if (timeval_ms() >= timeout) {
+ LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d",
+ target->state);
+ return ERROR_TARGET_TIMEOUT;
+ }
}
- if (timeout == 0) {
- LOG_ERROR("Timed out waiting for CPU to be reset, target->state=%d", target->state);
- return ERROR_TARGET_TIMEOUT;
- }
+
xtensa_halt(target);
res = target_wait_state(target, TARGET_HALTED, 1000);
if (res != ERROR_OK) {
@@ -600,6 +408,19 @@ static int esp32s2_poll(struct target *target)
if (old_state == TARGET_DEBUG_RUNNING) {
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
} else {
+ if (esp_xtensa_semihosting(target, &ret) == SEMIHOSTING_HANDLED) {
+ struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);
+ if (ret == ERROR_OK && esp_xtensa->semihost.need_resume) {
+ esp_xtensa->semihost.need_resume = false;
+ /* Resume xtensa_resume will handle BREAK instruction. */
+ ret = target_resume(target, 1, 0, 1, 0);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Failed to resume target");
+ return ret;
+ }
+ }
+ return ret;
+ }
esp32s2_on_halt(target);
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
}
@@ -617,7 +438,11 @@ static int esp32s2_virt2phys(struct target *target,
static int esp32s2_target_init(struct command_context *cmd_ctx, struct target *target)
{
- return esp_xtensa_target_init(cmd_ctx, target);
+ int ret = esp_xtensa_target_init(cmd_ctx, target);
+ if (ret != ERROR_OK)
+ return ret;
+
+ return esp_xtensa_semihosting_init(target);
}
static const struct xtensa_debug_ops esp32s2_dbg_ops = {
@@ -631,6 +456,10 @@ static const struct xtensa_power_ops esp32s2_pwr_ops = {
.queue_reg_write = xtensa_dm_queue_pwr_reg_write
};
+static const struct esp_semihost_ops esp32s2_semihost_ops = {
+ .prepare = esp32s2_disable_wdts
+};
+
static int esp32s2_target_create(struct target *target, Jim_Interp *interp)
{
struct xtensa_debug_module_config esp32s2_dm_cfg = {
@@ -648,7 +477,7 @@ static int esp32s2_target_create(struct target *target, Jim_Interp *interp)
return ERROR_FAIL;
}
- int ret = esp_xtensa_init_arch_info(target, &esp32->esp_xtensa, &esp32s2_xtensa_cfg, &esp32s2_dm_cfg);
+ int ret = esp_xtensa_init_arch_info(target, &esp32->esp_xtensa, &esp32s2_dm_cfg, &esp32s2_semihost_ops);
if (ret != ERROR_OK) {
LOG_ERROR("Failed to init arch info!");
free(esp32);
@@ -663,11 +492,14 @@ static int esp32s2_target_create(struct target *target, Jim_Interp *interp)
static const struct command_registration esp32s2_command_handlers[] = {
{
- .name = "xtensa",
+ .chain = xtensa_command_handlers,
+ },
+ {
+ .name = "arm",
.mode = COMMAND_ANY,
- .help = "Xtensa commands group",
+ .help = "ARM Command Group",
.usage = "",
- .chain = xtensa_command_handlers,
+ .chain = semihosting_common_handlers
},
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/espressif/esp32s2.h b/src/target/espressif/esp32s2.h
deleted file mode 100644
index 2c43e3e..0000000
--- a/src/target/espressif/esp32s2.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/***************************************************************************
- * ESP32-S2 target for OpenOCD *
- * Copyright (C) 2019 Espressif Systems Ltd. *
- * Author: Alexey Gerenkov <alexey@espressif.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#ifndef OPENOCD_TARGET_ESP32S2_H
-#define OPENOCD_TARGET_ESP32S2_H
-
-#include <target/xtensa/xtensa_regs.h>
-
-#define ESP32_S2_DROM_LOW 0x3f000000
-#define ESP32_S2_DROM_HIGH 0x3ff80000
-#define ESP32_S2_IROM_LOW 0x40080000
-#define ESP32_S2_IROM_HIGH 0x40800000
-
-/* Number of registers returned directly by the G command
- * Corresponds to the amount of regs listed in regformats/reg-xtensa.dat in the gdb source */
-#define ESP32_S2_NUM_REGS_G_COMMAND 72
-
-enum esp32s2_reg_id {
- /* chip specific registers that extend ISA go after ISA-defined ones */
- ESP32_S2_REG_IDX_GPIOOUT = XT_USR_REG_START,
- ESP32_S2_NUM_REGS,
-};
-
-#endif /* OPENOCD_TARGET_ESP32S2_H */
diff --git a/src/target/espressif/esp32s3.c b/src/target/espressif/esp32s3.c
new file mode 100644
index 0000000..62b22b1
--- /dev/null
+++ b/src/target/espressif/esp32s3.c
@@ -0,0 +1,422 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * ESP32-S3 target API for OpenOCD *
+ * Copyright (C) 2020 Espressif Systems Ltd. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <helper/time_support.h>
+#include <target/target.h>
+#include <target/target_type.h>
+#include <target/smp.h>
+#include <target/semihosting_common.h>
+#include "assert.h"
+#include "esp_xtensa_smp.h"
+
+/*
+This is a JTAG driver for the ESP32_S3, the are two Tensilica cores inside
+the ESP32_S3 chip. For more information please have a look into ESP32_S3 target
+implementation.
+*/
+
+/* ESP32_S3 memory map */
+#define ESP32_S3_IRAM_LOW 0x40370000
+#define ESP32_S3_IRAM_HIGH 0x403E0000
+#define ESP32_S3_IROM_MASK_LOW 0x40000000
+#define ESP32_S3_IROM_MASK_HIGH 0x40060000
+#define ESP32_S3_DRAM_LOW 0x3FC88000
+#define ESP32_S3_DRAM_HIGH 0x3FD00000
+#define ESP32_S3_RTC_IRAM_LOW 0x600FE000
+#define ESP32_S3_RTC_IRAM_HIGH 0x60100000
+#define ESP32_S3_RTC_DRAM_LOW 0x600FE000
+#define ESP32_S3_RTC_DRAM_HIGH 0x60100000
+#define ESP32_S3_RTC_DATA_LOW 0x50000000
+#define ESP32_S3_RTC_DATA_HIGH 0x50002000
+#define ESP32_S3_EXTRAM_DATA_LOW 0x3D000000
+#define ESP32_S3_EXTRAM_DATA_HIGH 0x3E000000
+#define ESP32_S3_SYS_RAM_LOW 0x60000000UL
+#define ESP32_S3_SYS_RAM_HIGH (ESP32_S3_SYS_RAM_LOW + 0x10000000UL)
+#define ESP32_S3_RTC_SLOW_MEM_BASE ESP32_S3_RTC_DATA_LOW
+
+/* ESP32_S3 WDT */
+#define ESP32_S3_WDT_WKEY_VALUE 0x50D83AA1
+#define ESP32_S3_TIMG0_BASE 0x6001F000
+#define ESP32_S3_TIMG1_BASE 0x60020000
+#define ESP32_S3_TIMGWDT_CFG0_OFF 0x48
+#define ESP32_S3_TIMGWDT_PROTECT_OFF 0x64
+#define ESP32_S3_TIMG0WDT_CFG0 (ESP32_S3_TIMG0_BASE + ESP32_S3_TIMGWDT_CFG0_OFF)
+#define ESP32_S3_TIMG1WDT_CFG0 (ESP32_S3_TIMG1_BASE + ESP32_S3_TIMGWDT_CFG0_OFF)
+#define ESP32_S3_TIMG0WDT_PROTECT (ESP32_S3_TIMG0_BASE + ESP32_S3_TIMGWDT_PROTECT_OFF)
+#define ESP32_S3_TIMG1WDT_PROTECT (ESP32_S3_TIMG1_BASE + ESP32_S3_TIMGWDT_PROTECT_OFF)
+#define ESP32_S3_RTCCNTL_BASE 0x60008000
+#define ESP32_S3_RTCWDT_CFG_OFF 0x98
+#define ESP32_S3_RTCWDT_PROTECT_OFF 0xB0
+#define ESP32_S3_SWD_CONF_OFF 0xB0
+#define ESP32_S3_SWD_WPROTECT_OFF 0xB4
+#define ESP32_S3_RTCWDT_CFG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_CFG_OFF)
+#define ESP32_S3_RTCWDT_PROTECT (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_PROTECT_OFF)
+#define ESP32_S3_SWD_CONF_REG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_CONF_OFF)
+#define ESP32_S3_SWD_WPROTECT_REG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_WPROTECT_OFF)
+#define ESP32_S3_SWD_AUTO_FEED_EN_M BIT(31)
+#define ESP32_S3_SWD_WKEY_VALUE 0x8F1D312AU
+
+#define ESP32_S3_TRACEMEM_BLOCK_SZ 0x4000
+
+/* ESP32_S3 dport regs */
+#define ESP32_S3_DR_REG_SYSTEM_BASE 0x600c0000
+#define ESP32_S3_SYSTEM_CORE_1_CONTROL_0_REG (ESP32_S3_DR_REG_SYSTEM_BASE + 0x014)
+#define ESP32_S3_SYSTEM_CONTROL_CORE_1_CLKGATE_EN BIT(1)
+
+/* ESP32_S3 RTC regs */
+#define ESP32_S3_RTC_CNTL_SW_CPU_STALL_REG (ESP32_S3_RTCCNTL_BASE + 0xBC)
+#define ESP32_S3_RTC_CNTL_SW_CPU_STALL_DEF 0x0
+
+struct esp32s3_common {
+ struct esp_xtensa_smp_common esp_xtensa_smp;
+};
+
+/* Reset ESP32-S3's peripherals.
+ * 1. OpenOCD makes sure the target is halted; if not, tries to halt it.
+ * If that fails, tries to reset it (via OCD) and then halt.
+ * 2. OpenOCD loads the stub code into RTC_SLOW_MEM.
+ * 3. Executes the stub code from address 0x50000004.
+ * 4. The stub code changes the reset vector to 0x50000000, and triggers
+ * a system reset using RTC_CNTL_SW_SYS_RST bit.
+ * 5. Once the PRO CPU is out of reset, it executes the stub code from address 0x50000000.
+ * The stub code disables the watchdog, re-enables JTAG and the APP CPU,
+ * restores the reset vector, and enters an infinite loop.
+ * 6. OpenOCD waits until it can talk to the OCD module again, then halts the target.
+ * 7. OpenOCD restores the contents of RTC_SLOW_MEM.
+ *
+ * End result: all the peripherals except RTC_CNTL are reset, CPU's PC is undefined,
+ * PRO CPU is halted, APP CPU is in reset.
+ */
+
+static const uint8_t esp32s3_reset_stub_code[] = {
+#include "../../../contrib/loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc"
+};
+
+static int esp32s3_soc_reset(struct target *target)
+{
+ int res;
+ struct target_list *head;
+ struct xtensa *xtensa;
+
+ LOG_DEBUG("start");
+ /* In order to write to peripheral registers, target must be halted first */
+ if (target->state != TARGET_HALTED) {
+ LOG_DEBUG("Target not halted before SoC reset, trying to halt it first");
+ xtensa_halt(target);
+ res = target_wait_state(target, TARGET_HALTED, 1000);
+ if (res != ERROR_OK) {
+ LOG_DEBUG("Couldn't halt target before SoC reset, trying to do reset-halt");
+ res = xtensa_assert_reset(target);
+ if (res != ERROR_OK) {
+ LOG_ERROR(
+ "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
+ res);
+ return res;
+ }
+ alive_sleep(10);
+ xtensa_poll(target);
+ bool reset_halt_save = target->reset_halt;
+ target->reset_halt = true;
+ res = xtensa_deassert_reset(target);
+ target->reset_halt = reset_halt_save;
+ if (res != ERROR_OK) {
+ LOG_ERROR(
+ "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
+ res);
+ return res;
+ }
+ alive_sleep(10);
+ xtensa_poll(target);
+ xtensa_halt(target);
+ res = target_wait_state(target, TARGET_HALTED, 1000);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Couldn't halt target before SoC reset");
+ return res;
+ }
+ }
+ }
+
+ if (target->smp) {
+ foreach_smp_target(head, target->smp_targets) {
+ xtensa = target_to_xtensa(head->target);
+ /* if any of the cores is stalled unstall them */
+ if (xtensa_dm_core_is_stalled(&xtensa->dbg_mod)) {
+ LOG_TARGET_DEBUG(head->target, "Unstall CPUs before SW reset!");
+ res = target_write_u32(target,
+ ESP32_S3_RTC_CNTL_SW_CPU_STALL_REG,
+ ESP32_S3_RTC_CNTL_SW_CPU_STALL_DEF);
+ if (res != ERROR_OK) {
+ LOG_TARGET_ERROR(head->target, "Failed to unstall CPUs before SW reset!");
+ return res;
+ }
+ break; /* both cores are unstalled now, so exit the loop */
+ }
+ }
+ }
+
+ LOG_DEBUG("Loading stub code into RTC RAM");
+ uint8_t slow_mem_save[sizeof(esp32s3_reset_stub_code)];
+
+ /* Save contents of RTC_SLOW_MEM which we are about to overwrite */
+ res = target_read_buffer(target, ESP32_S3_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to save contents of RTC_SLOW_MEM (%d)!", res);
+ return res;
+ }
+
+ /* Write stub code into RTC_SLOW_MEM */
+ res = target_write_buffer(target,
+ ESP32_S3_RTC_SLOW_MEM_BASE,
+ sizeof(esp32s3_reset_stub_code),
+ esp32s3_reset_stub_code);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write stub (%d)!", res);
+ return res;
+ }
+
+ LOG_DEBUG("Resuming the target");
+ xtensa = target_to_xtensa(target);
+ xtensa->suppress_dsr_errors = true;
+ res = xtensa_resume(target, 0, ESP32_S3_RTC_SLOW_MEM_BASE + 4, 0, 0);
+ xtensa->suppress_dsr_errors = false;
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to run stub (%d)!", res);
+ return res;
+ }
+ LOG_DEBUG("resume done, waiting for the target to come alive");
+
+ /* Wait for SoC to reset */
+ alive_sleep(100);
+ int64_t timeout = timeval_ms() + 100;
+ bool get_timeout = false;
+ while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
+ alive_sleep(10);
+ xtensa_poll(target);
+ if (timeval_ms() >= timeout) {
+ LOG_TARGET_ERROR(target,
+ "Timed out waiting for CPU to be reset, target state=%d",
+ target->state);
+ get_timeout = true;
+ break;
+ }
+ }
+
+ /* Halt the CPU again */
+ LOG_DEBUG("halting the target");
+ xtensa_halt(target);
+ res = target_wait_state(target, TARGET_HALTED, 1000);
+ if (res == ERROR_OK) {
+ LOG_DEBUG("restoring RTC_SLOW_MEM");
+ res = target_write_buffer(target, ESP32_S3_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);
+ if (res != ERROR_OK)
+ LOG_TARGET_ERROR(target, "Failed to restore contents of RTC_SLOW_MEM (%d)!", res);
+ } else {
+ LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be halted after SoC reset");
+ }
+
+ return get_timeout ? ERROR_TARGET_TIMEOUT : res;
+}
+
+static int esp32s3_disable_wdts(struct target *target)
+{
+ /* TIMG1 WDT */
+ int res = target_write_u32(target, ESP32_S3_TIMG0WDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_S3_TIMG0WDT_PROTECT (%d)!", res);
+ return res;
+ }
+ res = target_write_u32(target, ESP32_S3_TIMG0WDT_CFG0, 0);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_S3_TIMG0WDT_CFG0 (%d)!", res);
+ return res;
+ }
+ /* TIMG2 WDT */
+ res = target_write_u32(target, ESP32_S3_TIMG1WDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_S3_TIMG1WDT_PROTECT (%d)!", res);
+ return res;
+ }
+ res = target_write_u32(target, ESP32_S3_TIMG1WDT_CFG0, 0);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_S3_TIMG1WDT_CFG0 (%d)!", res);
+ return res;
+ }
+ /* RTC WDT */
+ res = target_write_u32(target, ESP32_S3_RTCWDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_S3_RTCWDT_PROTECT (%d)!", res);
+ return res;
+ }
+ res = target_write_u32(target, ESP32_S3_RTCWDT_CFG, 0);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_S3_RTCWDT_CFG (%d)!", res);
+ return res;
+ }
+ /* Enable SWD auto-feed */
+ res = target_write_u32(target, ESP32_S3_SWD_WPROTECT_REG, ESP32_S3_SWD_WKEY_VALUE);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_S3_SWD_WPROTECT_REG (%d)!", res);
+ return res;
+ }
+ uint32_t swd_conf_reg = 0;
+ res = target_read_u32(target, ESP32_S3_SWD_CONF_REG, &swd_conf_reg);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to read ESP32_S3_SWD_CONF_REG (%d)!", res);
+ return res;
+ }
+ swd_conf_reg |= ESP32_S3_SWD_AUTO_FEED_EN_M;
+ res = target_write_u32(target, ESP32_S3_SWD_CONF_REG, swd_conf_reg);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to write ESP32_S3_SWD_CONF_REG (%d)!", res);
+ return res;
+ }
+ return ERROR_OK;
+}
+
+static int esp32s3_on_halt(struct target *target)
+{
+ return esp32s3_disable_wdts(target);
+}
+
+static int esp32s3_arch_state(struct target *target)
+{
+ return ERROR_OK;
+}
+
+static int esp32s3_virt2phys(struct target *target,
+ target_addr_t virtual, target_addr_t *physical)
+{
+ if (physical) {
+ *physical = virtual;
+ return ERROR_OK;
+ }
+ return ERROR_FAIL;
+}
+
+static int esp32s3_target_init(struct command_context *cmd_ctx, struct target *target)
+{
+ return esp_xtensa_smp_target_init(cmd_ctx, target);
+}
+
+static const struct xtensa_debug_ops esp32s3_dbg_ops = {
+ .queue_enable = xtensa_dm_queue_enable,
+ .queue_reg_read = xtensa_dm_queue_reg_read,
+ .queue_reg_write = xtensa_dm_queue_reg_write
+};
+
+static const struct xtensa_power_ops esp32s3_pwr_ops = {
+ .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
+ .queue_reg_write = xtensa_dm_queue_pwr_reg_write
+};
+
+static const struct esp_xtensa_smp_chip_ops esp32s3_chip_ops = {
+ .reset = esp32s3_soc_reset,
+ .on_halt = esp32s3_on_halt
+};
+
+static const struct esp_semihost_ops esp32s3_semihost_ops = {
+ .prepare = esp32s3_disable_wdts
+};
+
+static int esp32s3_target_create(struct target *target, Jim_Interp *interp)
+{
+ struct xtensa_debug_module_config esp32s3_dm_cfg = {
+ .dbg_ops = &esp32s3_dbg_ops,
+ .pwr_ops = &esp32s3_pwr_ops,
+ .tap = target->tap,
+ .queue_tdi_idle = NULL,
+ .queue_tdi_idle_arg = NULL
+ };
+
+ struct esp32s3_common *esp32s3 = calloc(1, sizeof(struct esp32s3_common));
+ if (!esp32s3) {
+ LOG_ERROR("Failed to alloc memory for arch info!");
+ return ERROR_FAIL;
+ }
+
+ int ret = esp_xtensa_smp_init_arch_info(target,
+ &esp32s3->esp_xtensa_smp,
+ &esp32s3_dm_cfg,
+ &esp32s3_chip_ops,
+ &esp32s3_semihost_ops);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Failed to init arch info!");
+ free(esp32s3);
+ return ret;
+ }
+
+ /* Assume running target. If different, the first poll will fix this. */
+ target->state = TARGET_RUNNING;
+ target->debug_reason = DBG_REASON_NOTHALTED;
+ return ERROR_OK;
+}
+
+static const struct command_registration esp32s3_command_handlers[] = {
+ {
+ .usage = "",
+ .chain = esp_xtensa_smp_command_handlers,
+ },
+ {
+ .name = "esp32",
+ .usage = "",
+ .chain = smp_command_handlers,
+ },
+ {
+ .name = "arm",
+ .mode = COMMAND_ANY,
+ .help = "ARM Command Group",
+ .usage = "",
+ .chain = semihosting_common_handlers
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+/** Holds methods for Xtensa targets. */
+struct target_type esp32s3_target = {
+ .name = "esp32s3",
+
+ .poll = esp_xtensa_smp_poll,
+ .arch_state = esp32s3_arch_state,
+
+ .halt = xtensa_halt,
+ .resume = esp_xtensa_smp_resume,
+ .step = esp_xtensa_smp_step,
+
+ .assert_reset = esp_xtensa_smp_assert_reset,
+ .deassert_reset = esp_xtensa_smp_deassert_reset,
+ .soft_reset_halt = esp_xtensa_smp_soft_reset_halt,
+
+ .virt2phys = esp32s3_virt2phys,
+ .mmu = xtensa_mmu_is_enabled,
+ .read_memory = xtensa_read_memory,
+ .write_memory = xtensa_write_memory,
+
+ .read_buffer = xtensa_read_buffer,
+ .write_buffer = xtensa_write_buffer,
+
+ .checksum_memory = xtensa_checksum_memory,
+
+ .get_gdb_arch = xtensa_get_gdb_arch,
+ .get_gdb_reg_list = xtensa_get_gdb_reg_list,
+
+ .add_breakpoint = esp_xtensa_breakpoint_add,
+ .remove_breakpoint = esp_xtensa_breakpoint_remove,
+
+ .add_watchpoint = esp_xtensa_smp_watchpoint_add,
+ .remove_watchpoint = esp_xtensa_smp_watchpoint_remove,
+
+ .target_create = esp32s3_target_create,
+ .init_target = esp32s3_target_init,
+ .examine = xtensa_examine,
+ .deinit_target = esp_xtensa_target_deinit,
+
+ .commands = esp32s3_command_handlers,
+};
diff --git a/src/target/espressif/esp_semihosting.c b/src/target/espressif/esp_semihosting.c
new file mode 100644
index 0000000..5e9cb94
--- /dev/null
+++ b/src/target/espressif/esp_semihosting.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * Semihosting API for Espressif chips *
+ * Copyright (C) 2022 Espressif Systems Ltd. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <helper/log.h>
+#include <target/target.h>
+#include <target/semihosting_common.h>
+#include "esp_semihosting.h"
+#include "esp_xtensa.h"
+
+static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target)
+{
+ const char *arch = target_get_gdb_arch(target);
+ if (arch) {
+ if (strncmp(arch, "xtensa", 6) == 0)
+ return &target_to_esp_xtensa(target)->semihost;
+ /* TODO: add riscv */
+ }
+ LOG_ERROR("Unknown target arch!");
+ return NULL;
+}
+
+static int esp_semihosting_sys_seek(struct target *target, uint64_t fd, uint32_t pos, size_t whence)
+{
+ struct semihosting *semihosting = target->semihosting;
+
+ semihosting->result = lseek(fd, pos, whence);
+ semihosting->sys_errno = errno;
+ LOG_TARGET_DEBUG(target, "lseek(%" PRIx64 ", %" PRIu32 " %" PRId64 ")=%d", fd, pos, semihosting->result, errno);
+ return ERROR_OK;
+}
+
+int esp_semihosting_common(struct target *target)
+{
+ struct semihosting *semihosting = target->semihosting;
+ if (!semihosting)
+ /* Silently ignore if the semihosting field was not set. */
+ return ERROR_OK;
+
+ int retval = ERROR_NOT_IMPLEMENTED;
+
+ /* Enough space to hold 4 long words. */
+ uint8_t fields[4 * 8];
+
+ /*
+ * By default return an error.
+ * The actual result must be set by each function
+ */
+ semihosting->result = -1;
+ semihosting->sys_errno = EIO;
+
+ LOG_TARGET_DEBUG(target, "op=0x%x, param=0x%" PRIx64, semihosting->op, semihosting->param);
+
+ switch (semihosting->op) {
+ case ESP_SEMIHOSTING_SYS_DRV_INFO:
+ /* Return success to make esp-idf application happy */
+ retval = ERROR_OK;
+ semihosting->result = 0;
+ semihosting->sys_errno = 0;
+ break;
+
+ case ESP_SEMIHOSTING_SYS_SEEK:
+ retval = semihosting_read_fields(target, 3, fields);
+ if (retval == ERROR_OK) {
+ uint64_t fd = semihosting_get_field(target, 0, fields);
+ uint32_t pos = semihosting_get_field(target, 1, fields);
+ size_t whence = semihosting_get_field(target, 2, fields);
+ retval = esp_semihosting_sys_seek(target, fd, pos, whence);
+ }
+ break;
+
+ case ESP_SEMIHOSTING_SYS_APPTRACE_INIT:
+ case ESP_SEMIHOSTING_SYS_DEBUG_STUBS_INIT:
+ case ESP_SEMIHOSTING_SYS_BREAKPOINT_SET:
+ case ESP_SEMIHOSTING_SYS_WATCHPOINT_SET:
+ /* For the time being only riscv chips support these commands
+ * TODO: invoke riscv custom command handler */
+ break;
+ }
+
+ return retval;
+}
+
+int esp_semihosting_basedir_command(struct command_invocation *cmd)
+{
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (!target) {
+ LOG_ERROR("No target selected");
+ return ERROR_FAIL;
+ }
+
+ struct semihosting *semihosting = target->semihosting;
+ if (!semihosting) {
+ command_print(CMD, "semihosting not supported for current target");
+ return ERROR_FAIL;
+ }
+
+ if (!semihosting->is_active) {
+ if (semihosting->setup(target, true) != ERROR_OK) {
+ LOG_ERROR("Failed to Configure semihosting");
+ return ERROR_FAIL;
+ }
+ semihosting->is_active = true;
+ }
+
+ if (CMD_ARGC > 0) {
+ free(semihosting->basedir);
+ semihosting->basedir = strdup(CMD_ARGV[0]);
+ if (!semihosting->basedir) {
+ command_print(CMD, "semihosting failed to allocate memory for basedir!");
+ return ERROR_FAIL;
+ }
+ }
+
+ command_print(CMD, "DEPRECATED! semihosting base dir: %s",
+ semihosting->basedir ? semihosting->basedir : "");
+
+ return ERROR_OK;
+}
diff --git a/src/target/espressif/esp_semihosting.h b/src/target/espressif/esp_semihosting.h
new file mode 100644
index 0000000..bd2c079
--- /dev/null
+++ b/src/target/espressif/esp_semihosting.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/***************************************************************************
+ * Semihosting API for Espressif chips *
+ * Copyright (C) 2022 Espressif Systems Ltd. *
+ ***************************************************************************/
+
+#ifndef OPENOCD_TARGET_ESP_SEMIHOSTING_H
+#define OPENOCD_TARGET_ESP_SEMIHOSTING_H
+
+/* Legacy syscalls */
+#define ESP_SYS_DRV_INFO_LEGACY 0xE0
+
+/* syscalls compatible to ARM standard */
+#define ESP_SEMIHOSTING_SYS_DRV_INFO 0x100
+#define ESP_SEMIHOSTING_SYS_APPTRACE_INIT 0x101
+#define ESP_SEMIHOSTING_SYS_DEBUG_STUBS_INIT 0x102
+#define ESP_SEMIHOSTING_SYS_BREAKPOINT_SET 0x103
+#define ESP_SEMIHOSTING_SYS_WATCHPOINT_SET 0x104
+#define ESP_SEMIHOSTING_SYS_SEEK 0x105 /* custom lseek with whence */
+/* not implemented yet */
+#define ESP_SEMIHOSTING_SYS_MKDIR 0x106
+#define ESP_SEMIHOSTING_SYS_OPENDIR 0x107
+#define ESP_SEMIHOSTING_SYS_READDIR 0x108
+#define ESP_SEMIHOSTING_SYS_READDIR_R 0x109
+#define ESP_SEMIHOSTING_SYS_SEEKDIR 0x10A
+#define ESP_SEMIHOSTING_SYS_TELLDIR 0x10B
+#define ESP_SEMIHOSTING_SYS_CLOSEDIR 0x10C
+#define ESP_SEMIHOSTING_SYS_RMDIR 0x10D
+#define ESP_SEMIHOSTING_SYS_ACCESS 0x10E
+#define ESP_SEMIHOSTING_SYS_TRUNCATE 0x10F
+#define ESP_SEMIHOSTING_SYS_UTIME 0x110
+#define ESP_SEMIHOSTING_SYS_FSTAT 0x111
+#define ESP_SEMIHOSTING_SYS_STAT 0x112
+#define ESP_SEMIHOSTING_SYS_FSYNC 0x113
+#define ESP_SEMIHOSTING_SYS_LINK 0x114
+#define ESP_SEMIHOSTING_SYS_UNLINK 0x115
+
+/**
+ * Semihost calls handling operations.
+ */
+struct esp_semihost_ops {
+ /** Callback called before handling semihost call */
+ int (*prepare)(struct target *target);
+};
+
+struct esp_semihost_data {
+ bool need_resume;
+ struct esp_semihost_ops *ops;
+};
+
+int esp_semihosting_common(struct target *target);
+int esp_semihosting_basedir_command(struct command_invocation *cmd);
+
+#endif /* OPENOCD_TARGET_ESP_SEMIHOSTING_H */
diff --git a/src/target/espressif/esp_xtensa.c b/src/target/espressif/esp_xtensa.c
index 89393f4..fcc340c 100644
--- a/src/target/espressif/esp_xtensa.c
+++ b/src/target/espressif/esp_xtensa.c
@@ -1,20 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Espressif Xtensa target API for OpenOCD *
* Copyright (C) 2019 Espressif Systems Ltd. *
- * Author: Alexey Gerenkov <alexey@espressif.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -24,15 +12,20 @@
#include <stdbool.h>
#include <stdint.h>
#include <target/smp.h>
-#include "esp_xtensa.h"
#include <target/register.h>
+#include "esp_xtensa.h"
+#include "esp_semihosting.h"
int esp_xtensa_init_arch_info(struct target *target,
struct esp_xtensa_common *esp_xtensa,
- const struct xtensa_config *xtensa_cfg,
- struct xtensa_debug_module_config *dm_cfg)
+ struct xtensa_debug_module_config *dm_cfg,
+ const struct esp_semihost_ops *semihost_ops)
{
- return xtensa_init_arch_info(target, &esp_xtensa->xtensa, xtensa_cfg, dm_cfg);
+ int ret = xtensa_init_arch_info(target, &esp_xtensa->xtensa, dm_cfg);
+ if (ret != ERROR_OK)
+ return ret;
+ esp_xtensa->semihost.ops = (struct esp_semihost_ops *)semihost_ops;
+ return ERROR_OK;
}
int esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
diff --git a/src/target/espressif/esp_xtensa.h b/src/target/espressif/esp_xtensa.h
index 6badb1b..1ad6c37 100644
--- a/src/target/espressif/esp_xtensa.h
+++ b/src/target/espressif/esp_xtensa.h
@@ -1,31 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Generic ESP xtensa target implementation for OpenOCD *
* Copyright (C) 2019 Espressif Systems Ltd. *
- * Author: Alexey Gerenkov <alexey@espressif.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ESP_XTENSA_H
#define OPENOCD_TARGET_ESP_XTENSA_H
-#include <helper/command.h>
#include <target/target.h>
#include <target/xtensa/xtensa.h>
+#include "esp_xtensa.h"
+#include "esp_semihosting.h"
struct esp_xtensa_common {
struct xtensa xtensa; /* must be the first element */
+ struct esp_semihost_data semihost;
};
static inline struct esp_xtensa_common *target_to_esp_xtensa(struct target *target)
@@ -35,8 +25,8 @@ static inline struct esp_xtensa_common *target_to_esp_xtensa(struct target *targ
int esp_xtensa_init_arch_info(struct target *target,
struct esp_xtensa_common *esp_xtensa,
- const struct xtensa_config *xtensa_cfg,
- struct xtensa_debug_module_config *dm_cfg);
+ struct xtensa_debug_module_config *dm_cfg,
+ const struct esp_semihost_ops *semihost_ops);
int esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *target);
void esp_xtensa_target_deinit(struct target *target);
int esp_xtensa_arch_state(struct target *target);
diff --git a/src/target/espressif/esp_xtensa_semihosting.c b/src/target/espressif/esp_xtensa_semihosting.c
new file mode 100644
index 0000000..54e9c4b
--- /dev/null
+++ b/src/target/espressif/esp_xtensa_semihosting.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * Copyright (c) 2020 Espressif Systems (Shanghai) Co. Ltd. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <target/semihosting_common.h>
+#include <target/xtensa/xtensa_regs.h>
+#include <target/xtensa/xtensa.h>
+#include "esp_xtensa.h"
+#include "esp_xtensa_semihosting.h"
+
+#define ESP_XTENSA_SYSCALL 0x41E0 /* XT_INS_BREAK(1, 14) */
+#define ESP_XTENSA_SYSCALL_SZ 3
+
+#define XTENSA_SYSCALL_OP_REG XT_REG_IDX_A2
+#define XTENSA_SYSCALL_RETVAL_REG XT_REG_IDX_A2
+#define XTENSA_SYSCALL_ERRNO_REG XT_REG_IDX_A3
+
+static int esp_xtensa_semihosting_setup(struct target *target, int enable)
+{
+ LOG_TARGET_DEBUG(target, "semihosting enable=%d", enable);
+
+ return ERROR_OK;
+}
+
+static int esp_xtensa_semihosting_post_result(struct target *target)
+{
+ /* Even with the v2 and later, errno will not retrieved from A3 reg, it is safe to set */
+ xtensa_reg_set(target, XTENSA_SYSCALL_RETVAL_REG, target->semihosting->result);
+ xtensa_reg_set(target, XTENSA_SYSCALL_ERRNO_REG, target->semihosting->sys_errno);
+ return ERROR_OK;
+}
+
+/**
+ * Checks and processes an ESP Xtensa semihosting request. This is meant
+ * to be called when the target is stopped due to a debug mode entry.
+ * If the value 0 is returned then there was nothing to process. A non-zero
+ * return value signifies that a request was processed and the target resumed,
+ * or an error was encountered, in which case the caller must return immediately.
+ *
+ * @param target Pointer to the ESP Xtensa target to process.
+ * @param retval Pointer to a location where the return code will be stored
+ * @return SEMIHOSTING_HANDLED if a request was processed or SEMIHOSTING_NONE with the proper retval
+ */
+int esp_xtensa_semihosting(struct target *target, int *retval)
+{
+ struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);
+
+ xtensa_reg_val_t dbg_cause = xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE);
+ if ((dbg_cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)) == 0)
+ return SEMIHOSTING_NONE;
+
+ uint8_t brk_insn_buf[sizeof(uint32_t)] = { 0 };
+ xtensa_reg_val_t pc = xtensa_reg_get(target, XT_REG_IDX_PC);
+ *retval = target_read_memory(target, pc, ESP_XTENSA_SYSCALL_SZ, 1, brk_insn_buf);
+ if (*retval != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "Failed to read break instruction!");
+ return SEMIHOSTING_NONE;
+ }
+
+ uint32_t syscall_ins = buf_get_u32(brk_insn_buf, 0, 32);
+ if (syscall_ins != ESP_XTENSA_SYSCALL) {
+ *retval = ERROR_OK;
+ return SEMIHOSTING_NONE;
+ }
+
+ if (esp_xtensa->semihost.ops && esp_xtensa->semihost.ops->prepare)
+ esp_xtensa->semihost.ops->prepare(target);
+
+ xtensa_reg_val_t a2 = xtensa_reg_get(target, XT_REG_IDX_A2);
+ xtensa_reg_val_t a3 = xtensa_reg_get(target, XT_REG_IDX_A3);
+ LOG_TARGET_DEBUG(target, "Semihosting call 0x%" PRIx32 " 0x%" PRIx32 " Base dir '%s'",
+ a2,
+ a3,
+ target->semihosting->basedir ? target->semihosting->basedir : "");
+
+ target->semihosting->op = a2;
+ target->semihosting->param = a3;
+
+ *retval = semihosting_common(target);
+
+ /* Most operations are resumable, except the two exit calls. */
+ if (*retval != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "Semihosting operation (op: 0x%x) error! Code: %d",
+ target->semihosting->op,
+ *retval);
+ }
+
+ /* Resume if target it is resumable and we are not waiting on a fileio operation to complete. */
+ if (target->semihosting->is_resumable && !target->semihosting->hit_fileio)
+ target_to_esp_xtensa(target)->semihost.need_resume = true;
+
+ return SEMIHOSTING_HANDLED;
+}
+
+static int xtensa_semihosting_init(struct target *target)
+{
+ return semihosting_common_init(target, esp_xtensa_semihosting_setup, esp_xtensa_semihosting_post_result);
+}
+
+int esp_xtensa_semihosting_init(struct target *target)
+{
+ int retval = xtensa_semihosting_init(target);
+ if (retval != ERROR_OK)
+ return retval;
+ target->semihosting->word_size_bytes = 4; /* 32 bits */
+ target->semihosting->user_command_extension = esp_semihosting_common;
+ return ERROR_OK;
+}
diff --git a/src/target/espressif/esp_xtensa_semihosting.h b/src/target/espressif/esp_xtensa_semihosting.h
new file mode 100644
index 0000000..1da3115
--- /dev/null
+++ b/src/target/espressif/esp_xtensa_semihosting.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/***************************************************************************
+ * Copyright (c) 2020 Espressif Systems (Shanghai) Co. Ltd. *
+ ***************************************************************************/
+
+#ifndef OPENOCD_TARGET_ESP_XTENSA_SEMIHOSTING_H
+#define OPENOCD_TARGET_ESP_XTENSA_SEMIHOSTING_H
+
+#include <target/target.h>
+
+int esp_xtensa_semihosting_init(struct target *target);
+int esp_xtensa_semihosting(struct target *target, int *retval);
+
+#endif /* OPENOCD_TARGET_ESP_XTENSA_SEMIHOSTING_H */
diff --git a/src/target/espressif/esp_xtensa_smp.c b/src/target/espressif/esp_xtensa_smp.c
new file mode 100644
index 0000000..1d03774
--- /dev/null
+++ b/src/target/espressif/esp_xtensa_smp.c
@@ -0,0 +1,931 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * ESP Xtensa SMP target API for OpenOCD *
+ * Copyright (C) 2020 Espressif Systems Ltd. Co *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "assert.h"
+#include <target/target.h>
+#include <target/target_type.h>
+#include <target/smp.h>
+#include <target/semihosting_common.h>
+#include "esp_xtensa_smp.h"
+#include "esp_xtensa_semihosting.h"
+
+/*
+Multiprocessor stuff common:
+
+The ESP Xtensa chip can have several cores in it, which can run in SMP-mode if an
+SMP-capable OS is running. The hardware has a few features which makes
+SMP debugging much easier.
+
+First of all, there's something called a 'break network', consisting of a
+BreakIn input and a BreakOut output on each CPU. The idea is that as soon
+as a CPU goes into debug mode for whatever reason, it'll signal that using
+its DebugOut pin. This signal is connected to the other CPU's DebugIn
+input, causing this CPU also to go into debugging mode. To resume execution
+when using only this break network, we will need to manually resume both
+CPUs.
+
+An alternative to this is the XOCDMode output and the RunStall (or DebugStall)
+input. When these are cross-connected, a CPU that goes into debug mode will
+halt execution entirely on the other CPU. Execution on the other CPU can be
+resumed by either the first CPU going out of debug mode, or the second CPU
+going into debug mode: the stall is temporarily lifted as long as the stalled
+CPU is in debug mode.
+
+A third, separate, signal is CrossTrigger. This is connected in the same way
+as the breakIn/breakOut network, but is for the TRAX (trace memory) feature;
+it does not affect OCD in any way.
+*/
+
+/*
+Multiprocessor stuff:
+
+The ESP Xtensa chip has several Xtensa cores inside, but represent themself to the OCD
+as one chip that works in multithreading mode under FreeRTOS OS.
+The core that initiate the stop condition will be defined as an active cpu.
+When one core stops, then other core will be stopped automatically by smpbreak.
+The core that initiates stop condition will be defined as an active core, and
+registers of this core will be transferred.
+*/
+
+#define ESP_XTENSA_SMP_EXAMINE_OTHER_CORES 5
+
+static int esp_xtensa_smp_update_halt_gdb(struct target *target, bool *need_resume);
+
+static inline struct esp_xtensa_smp_common *target_to_esp_xtensa_smp(struct target *target)
+{
+ return container_of(target->arch_info, struct esp_xtensa_smp_common, esp_xtensa);
+}
+
+int esp_xtensa_smp_assert_reset(struct target *target)
+{
+ return ERROR_OK;
+}
+
+int esp_xtensa_smp_deassert_reset(struct target *target)
+{
+ LOG_TARGET_DEBUG(target, "begin");
+
+ int ret = xtensa_deassert_reset(target);
+ if (ret != ERROR_OK)
+ return ret;
+ /* in SMP mode when chip was running single-core app the other core can be left un-examined,
+ because examination is done before SOC reset. But after SOC reset it is functional and should be handled.
+ So try to examine un-examined core just after SOC reset */
+ if (target->smp && !target_was_examined(target))
+ ret = xtensa_examine(target);
+ return ret;
+}
+
+int esp_xtensa_smp_soft_reset_halt(struct target *target)
+{
+ int res;
+ struct target_list *head;
+ struct esp_xtensa_smp_common *esp_xtensa_smp = target_to_esp_xtensa_smp(target);
+
+ LOG_TARGET_DEBUG(target, "begin");
+ /* in SMP mode we need to ensure that at first we reset SOC on PRO-CPU
+ and then call xtensa_assert_reset() for all cores */
+ if (target->smp && target->coreid != 0)
+ return ERROR_OK;
+ /* Reset the SoC first */
+ if (esp_xtensa_smp->chip_ops->reset) {
+ res = esp_xtensa_smp->chip_ops->reset(target);
+ if (res != ERROR_OK)
+ return res;
+ }
+ if (!target->smp)
+ return xtensa_assert_reset(target);
+
+ foreach_smp_target(head, target->smp_targets) {
+ res = xtensa_assert_reset(head->target);
+ if (res != ERROR_OK)
+ return res;
+ }
+ return ERROR_OK;
+}
+
+static struct target *get_halted_esp_xtensa_smp(struct target *target, int32_t coreid)
+{
+ struct target_list *head;
+ struct target *curr;
+
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ if ((curr->coreid == coreid) && (curr->state == TARGET_HALTED))
+ return curr;
+ }
+
+ return target;
+}
+
+int esp_xtensa_smp_poll(struct target *target)
+{
+ enum target_state old_state = target->state;
+ struct esp_xtensa_smp_common *esp_xtensa_smp = target_to_esp_xtensa_smp(target);
+ struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);
+ struct target_list *head;
+ struct target *curr;
+ bool other_core_resume_req = false;
+
+ if (target->state == TARGET_HALTED && target->smp && target->gdb_service && !target->gdb_service->target) {
+ target->gdb_service->target = get_halted_esp_xtensa_smp(target, target->gdb_service->core[1]);
+ LOG_INFO("Switch GDB target to '%s'", target_name(target->gdb_service->target));
+ if (esp_xtensa_smp->chip_ops->on_halt)
+ esp_xtensa_smp->chip_ops->on_halt(target);
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+ return ERROR_OK;
+ }
+
+ int ret = esp_xtensa_poll(target);
+ if (ret != ERROR_OK)
+ return ret;
+
+ if (target->smp) {
+ if (target->state == TARGET_RESET) {
+ esp_xtensa_smp->examine_other_cores = ESP_XTENSA_SMP_EXAMINE_OTHER_CORES;
+ } else if (esp_xtensa_smp->examine_other_cores > 0 &&
+ (target->state == TARGET_RUNNING || target->state == TARGET_HALTED)) {
+ LOG_TARGET_DEBUG(target, "Check for unexamined cores after reset");
+ bool all_examined = true;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ if (curr == target)
+ continue;
+ if (!target_was_examined(curr)) {
+ if (target_examine_one(curr) != ERROR_OK) {
+ LOG_DEBUG("Failed to examine!");
+ all_examined = false;
+ }
+ }
+ }
+ if (all_examined)
+ esp_xtensa_smp->examine_other_cores = 0;
+ else
+ esp_xtensa_smp->examine_other_cores--;
+ }
+ }
+
+ if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
+ if (target->smp) {
+ ret = esp_xtensa_smp_update_halt_gdb(target, &other_core_resume_req);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ /* Call any event callbacks that are applicable */
+ if (old_state == TARGET_DEBUG_RUNNING) {
+ target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
+ } else {
+ if (esp_xtensa_semihosting(target, &ret) == SEMIHOSTING_HANDLED) {
+ if (ret == ERROR_OK && esp_xtensa->semihost.need_resume &&
+ !esp_xtensa_smp->other_core_does_resume) {
+ esp_xtensa->semihost.need_resume = false;
+ /* Resume xtensa_resume will handle BREAK instruction. */
+ ret = target_resume(target, 1, 0, 1, 0);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Failed to resume target");
+ return ret;
+ }
+ }
+ return ret;
+ }
+ /* check whether any core polled by esp_xtensa_smp_update_halt_gdb() requested resume */
+ if (target->smp && other_core_resume_req) {
+ /* Resume xtensa_resume will handle BREAK instruction. */
+ ret = target_resume(target, 1, 0, 1, 0);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Failed to resume target");
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ if (esp_xtensa_smp->chip_ops->on_halt)
+ esp_xtensa_smp->chip_ops->on_halt(target);
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+ }
+ }
+
+ return ERROR_OK;
+}
+
+static int esp_xtensa_smp_update_halt_gdb(struct target *target, bool *need_resume)
+{
+ struct esp_xtensa_smp_common *esp_xtensa_smp;
+ struct target *gdb_target = NULL;
+ struct target_list *head;
+ struct target *curr;
+ int ret = ERROR_OK;
+
+ *need_resume = false;
+
+ if (target->gdb_service && target->gdb_service->target)
+ LOG_DEBUG("GDB target '%s'", target_name(target->gdb_service->target));
+
+ if (target->gdb_service && target->gdb_service->core[0] == -1) {
+ target->gdb_service->target = target;
+ target->gdb_service->core[0] = target->coreid;
+ LOG_INFO("Set GDB target to '%s'", target_name(target));
+ }
+
+ if (target->gdb_service)
+ gdb_target = target->gdb_service->target;
+
+ /* due to smpbreak config other cores can also go to HALTED state */
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ LOG_DEBUG("Check target '%s'", target_name(curr));
+ /* skip calling context */
+ if (curr == target)
+ continue;
+ if (!target_was_examined(curr)) {
+ curr->state = TARGET_HALTED;
+ continue;
+ }
+ /* skip targets that were already halted */
+ if (curr->state == TARGET_HALTED)
+ continue;
+ /* Skip gdb_target; it alerts GDB so has to be polled as last one */
+ if (curr == gdb_target)
+ continue;
+ LOG_DEBUG("Poll target '%s'", target_name(curr));
+
+ esp_xtensa_smp = target_to_esp_xtensa_smp(curr);
+ /* avoid auto-resume after syscall, it will be done later */
+ esp_xtensa_smp->other_core_does_resume = true;
+ /* avoid recursion in esp_xtensa_smp_poll() */
+ curr->smp = 0;
+ if (esp_xtensa_smp->chip_ops->poll)
+ ret = esp_xtensa_smp->chip_ops->poll(curr);
+ else
+ ret = esp_xtensa_smp_poll(curr);
+ curr->smp = 1;
+ if (ret != ERROR_OK)
+ return ret;
+ esp_xtensa_smp->other_core_does_resume = false;
+ struct esp_xtensa_common *curr_esp_xtensa = target_to_esp_xtensa(curr);
+ if (curr_esp_xtensa->semihost.need_resume) {
+ curr_esp_xtensa->semihost.need_resume = false;
+ *need_resume = true;
+ }
+ }
+
+ /* after all targets were updated, poll the gdb serving target */
+ if (gdb_target && gdb_target != target) {
+ esp_xtensa_smp = target_to_esp_xtensa_smp(gdb_target);
+ if (esp_xtensa_smp->chip_ops->poll)
+ ret = esp_xtensa_smp->chip_ops->poll(gdb_target);
+ else
+ ret = esp_xtensa_smp_poll(gdb_target);
+ }
+
+ LOG_DEBUG("exit");
+
+ return ret;
+}
+
+static inline int esp_xtensa_smp_smpbreak_disable(struct target *target, uint32_t *smp_break)
+{
+ int res = xtensa_smpbreak_get(target, smp_break);
+ if (res != ERROR_OK)
+ return res;
+ return xtensa_smpbreak_set(target, 0);
+}
+
+static inline int esp_xtensa_smp_smpbreak_restore(struct target *target, uint32_t smp_break)
+{
+ return xtensa_smpbreak_set(target, smp_break);
+}
+
+static int esp_xtensa_smp_resume_cores(struct target *target,
+ int handle_breakpoints,
+ int debug_execution)
+{
+ struct target_list *head;
+ struct target *curr;
+
+ LOG_TARGET_DEBUG(target, "begin");
+
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ /* in single-core mode disabled core cannot be examined, but need to be resumed too*/
+ if ((curr != target) && (curr->state != TARGET_RUNNING) && target_was_examined(curr)) {
+ /* resume current address, not in SMP mode */
+ curr->smp = 0;
+ int res = esp_xtensa_smp_resume(curr, 1, 0, handle_breakpoints, debug_execution);
+ curr->smp = 1;
+ if (res != ERROR_OK)
+ return res;
+ }
+ }
+ return ERROR_OK;
+}
+
+int esp_xtensa_smp_resume(struct target *target,
+ int current,
+ target_addr_t address,
+ int handle_breakpoints,
+ int debug_execution)
+{
+ int res;
+ uint32_t smp_break;
+
+ xtensa_smpbreak_get(target, &smp_break);
+ LOG_TARGET_DEBUG(target, "smp_break=0x%" PRIx32, smp_break);
+
+ /* dummy resume for smp toggle in order to reduce gdb impact */
+ if ((target->smp) && (target->gdb_service) && (target->gdb_service->core[1] != -1)) {
+ /* simulate a start and halt of target */
+ target->gdb_service->target = NULL;
+ target->gdb_service->core[0] = target->gdb_service->core[1];
+ /* fake resume at next poll we play the target core[1], see poll*/
+ LOG_TARGET_DEBUG(target, "Fake resume");
+ target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
+ return ERROR_OK;
+ }
+
+ /* xtensa_prepare_resume() can step over breakpoint/watchpoint and generate signals on BreakInOut circuit for
+ * other cores. So disconnect this core from BreakInOut circuit and do xtensa_prepare_resume(). */
+ res = esp_xtensa_smp_smpbreak_disable(target, &smp_break);
+ if (res != ERROR_OK)
+ return res;
+ res = xtensa_prepare_resume(target, current, address, handle_breakpoints, debug_execution);
+ /* restore configured BreakInOut signals config */
+ int ret = esp_xtensa_smp_smpbreak_restore(target, smp_break);
+ if (ret != ERROR_OK)
+ return ret;
+ if (res != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "Failed to prepare for resume!");
+ return res;
+ }
+
+ if (target->smp) {
+ if (target->gdb_service)
+ target->gdb_service->core[0] = -1;
+ res = esp_xtensa_smp_resume_cores(target, handle_breakpoints, debug_execution);
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ res = xtensa_do_resume(target);
+ if (res != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "Failed to resume!");
+ return res;
+ }
+
+ target->debug_reason = DBG_REASON_NOTHALTED;
+ if (!debug_execution)
+ target->state = TARGET_RUNNING;
+ else
+ target->state = TARGET_DEBUG_RUNNING;
+
+ target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
+ return ERROR_OK;
+}
+
+int esp_xtensa_smp_step(struct target *target,
+ int current,
+ target_addr_t address,
+ int handle_breakpoints)
+{
+ int res;
+ uint32_t smp_break = 0;
+ struct esp_xtensa_smp_common *esp_xtensa_smp = target_to_esp_xtensa_smp(target);
+
+ if (target->smp) {
+ res = esp_xtensa_smp_smpbreak_disable(target, &smp_break);
+ if (res != ERROR_OK)
+ return res;
+ }
+ res = xtensa_step(target, current, address, handle_breakpoints);
+
+ if (res == ERROR_OK) {
+ if (esp_xtensa_smp->chip_ops->on_halt)
+ esp_xtensa_smp->chip_ops->on_halt(target);
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+ }
+
+ if (target->smp) {
+ int ret = esp_xtensa_smp_smpbreak_restore(target, smp_break);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+
+ return res;
+}
+
+int esp_xtensa_smp_watchpoint_add(struct target *target, struct watchpoint *watchpoint)
+{
+ int res = xtensa_watchpoint_add(target, watchpoint);
+ if (res != ERROR_OK)
+ return res;
+
+ if (!target->smp)
+ return ERROR_OK;
+
+ struct target_list *head;
+ foreach_smp_target(head, target->smp_targets) {
+ struct target *curr = head->target;
+ if (curr == target || !target_was_examined(curr))
+ continue;
+ /* Need to use high level API here because every target for core contains list of watchpoints.
+ * GDB works with active core only, so we need to duplicate every watchpoint on other cores,
+ * otherwise watchpoint_free() on active core can fail if WP has been initially added on another core. */
+ curr->smp = 0;
+ res = watchpoint_add(curr, watchpoint->address, watchpoint->length,
+ watchpoint->rw, watchpoint->value, watchpoint->mask);
+ curr->smp = 1;
+ if (res != ERROR_OK)
+ return res;
+ }
+ return ERROR_OK;
+}
+
+int esp_xtensa_smp_watchpoint_remove(struct target *target, struct watchpoint *watchpoint)
+{
+ int res = xtensa_watchpoint_remove(target, watchpoint);
+ if (res != ERROR_OK)
+ return res;
+
+ if (!target->smp)
+ return ERROR_OK;
+
+ struct target_list *head;
+ foreach_smp_target(head, target->smp_targets) {
+ struct target *curr = head->target;
+ if (curr == target)
+ continue;
+ /* see big comment in esp_xtensa_smp_watchpoint_add() */
+ curr->smp = 0;
+ watchpoint_remove(curr, watchpoint->address);
+ curr->smp = 1;
+ }
+ return ERROR_OK;
+}
+
+int esp_xtensa_smp_init_arch_info(struct target *target,
+ struct esp_xtensa_smp_common *esp_xtensa_smp,
+ struct xtensa_debug_module_config *dm_cfg,
+ const struct esp_xtensa_smp_chip_ops *chip_ops,
+ const struct esp_semihost_ops *semihost_ops)
+{
+ int ret = esp_xtensa_init_arch_info(target, &esp_xtensa_smp->esp_xtensa, dm_cfg, semihost_ops);
+ if (ret != ERROR_OK)
+ return ret;
+ esp_xtensa_smp->chip_ops = chip_ops;
+ esp_xtensa_smp->examine_other_cores = ESP_XTENSA_SMP_EXAMINE_OTHER_CORES;
+ return ERROR_OK;
+}
+
+int esp_xtensa_smp_target_init(struct command_context *cmd_ctx, struct target *target)
+{
+ int ret = esp_xtensa_target_init(cmd_ctx, target);
+ if (ret != ERROR_OK)
+ return ret;
+
+ if (target->smp) {
+ struct target_list *head;
+ foreach_smp_target(head, target->smp_targets) {
+ struct target *curr = head->target;
+ ret = esp_xtensa_semihosting_init(curr);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ } else {
+ ret = esp_xtensa_semihosting_init(target);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_xtdef)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_xtopt)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_xtmem)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_xtmpu)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_xtmmu)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_xtreg)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_xtregfmt)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_permissive_mode)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_permissive_mode_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_permissive_mode_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_smpbreak)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_smpbreak_do, curr);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_smpbreak_do, target);
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_mask_interrupts)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_mask_interrupts_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_mask_interrupts_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_perfmon_enable)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp && CMD_ARGC > 0) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_enable_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_enable_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_perfmon_dump)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ LOG_INFO("CPU%d:", curr->coreid);
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_dump_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_dump_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_tracestart)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_tracestart_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_tracestart_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_tracestop)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp) {
+ struct target_list *head;
+ struct target *curr;
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_tracestop_do,
+ target_to_xtensa(curr));
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_tracestop_do,
+ target_to_xtensa(target));
+}
+
+COMMAND_HANDLER(esp_xtensa_smp_cmd_tracedump)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (target->smp) {
+ struct target_list *head;
+ struct target *curr;
+ int32_t cores_max_id = 0;
+ /* assume that core IDs are assigned to SMP targets sequentially: 0,1,2... */
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ if (cores_max_id < curr->coreid)
+ cores_max_id = curr->coreid;
+ }
+ if (CMD_ARGC < ((uint32_t)cores_max_id + 1)) {
+ command_print(CMD,
+ "Need %d filenames to dump to as output!",
+ cores_max_id + 1);
+ return ERROR_FAIL;
+ }
+ foreach_smp_target(head, target->smp_targets) {
+ curr = head->target;
+ int ret = CALL_COMMAND_HANDLER(xtensa_cmd_tracedump_do,
+ target_to_xtensa(curr), CMD_ARGV[curr->coreid]);
+ if (ret != ERROR_OK)
+ return ret;
+ }
+ return ERROR_OK;
+ }
+ return CALL_COMMAND_HANDLER(xtensa_cmd_tracedump_do,
+ target_to_xtensa(target), CMD_ARGV[0]);
+}
+
+const struct command_registration esp_xtensa_smp_xtensa_command_handlers[] = {
+ {
+ .name = "xtdef",
+ .handler = esp_xtensa_smp_cmd_xtdef,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa core type",
+ .usage = "<type>",
+ },
+ {
+ .name = "xtopt",
+ .handler = esp_xtensa_smp_cmd_xtopt,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa core option",
+ .usage = "<name> <value>",
+ },
+ {
+ .name = "xtmem",
+ .handler = esp_xtensa_smp_cmd_xtmem,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa memory/cache option",
+ .usage = "<type> [parameters]",
+ },
+ {
+ .name = "xtmmu",
+ .handler = esp_xtensa_smp_cmd_xtmmu,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa MMU option",
+ .usage = "<NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56>",
+ },
+ {
+ .name = "xtmpu",
+ .handler = esp_xtensa_smp_cmd_xtmpu,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa MPU option",
+ .usage = "<num FG seg> <min seg size> <lockable> <executeonly>",
+ },
+ {
+ .name = "xtreg",
+ .handler = esp_xtensa_smp_cmd_xtreg,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa register",
+ .usage = "<regname> <regnum>",
+ },
+ {
+ .name = "xtregs",
+ .handler = esp_xtensa_smp_cmd_xtreg,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure number of Xtensa registers",
+ .usage = "<numregs>",
+ },
+ {
+ .name = "xtregfmt",
+ .handler = esp_xtensa_smp_cmd_xtregfmt,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure format of Xtensa register map",
+ .usage = "<numgregs>",
+ },
+ {
+ .name = "set_permissive",
+ .handler = esp_xtensa_smp_cmd_permissive_mode,
+ .mode = COMMAND_ANY,
+ .help = "When set to 1, enable Xtensa permissive mode (less client-side checks)",
+ .usage = "[0|1]",
+ },
+ {
+ .name = "maskisr",
+ .handler = esp_xtensa_smp_cmd_mask_interrupts,
+ .mode = COMMAND_ANY,
+ .help = "mask Xtensa interrupts at step",
+ .usage = "['on'|'off']",
+ },
+ {
+ .name = "smpbreak",
+ .handler = esp_xtensa_smp_cmd_smpbreak,
+ .mode = COMMAND_ANY,
+ .help = "Set the way the CPU chains OCD breaks",
+ .usage =
+ "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]",
+ },
+ {
+ .name = "perfmon_enable",
+ .handler = esp_xtensa_smp_cmd_perfmon_enable,
+ .mode = COMMAND_EXEC,
+ .help = "Enable and start performance counter",
+ .usage = "<counter_id> <select> [mask] [kernelcnt] [tracelevel]",
+ },
+ {
+ .name = "perfmon_dump",
+ .handler = esp_xtensa_smp_cmd_perfmon_dump,
+ .mode = COMMAND_EXEC,
+ .help =
+ "Dump performance counter value. If no argument specified, dumps all counters.",
+ .usage = "[counter_id]",
+ },
+ {
+ .name = "tracestart",
+ .handler = esp_xtensa_smp_cmd_tracestart,
+ .mode = COMMAND_EXEC,
+ .help =
+ "Tracing: Set up and start a trace. Optionally set stop trigger address and amount of data captured after.",
+ .usage = "[pc <pcval>/[maskbitcount]] [after <n> [ins|words]]",
+ },
+ {
+ .name = "tracestop",
+ .handler = esp_xtensa_smp_cmd_tracestop,
+ .mode = COMMAND_EXEC,
+ .help = "Tracing: Stop current trace as started by the tracestart command",
+ .usage = "",
+ },
+ {
+ .name = "tracedump",
+ .handler = esp_xtensa_smp_cmd_tracedump,
+ .mode = COMMAND_EXEC,
+ .help = "Tracing: Dump trace memory to a files. One file per core.",
+ .usage = "<outfile1> <outfile2>",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+const struct command_registration esp_xtensa_smp_command_handlers[] = {
+ {
+ .name = "xtensa",
+ .usage = "",
+ .chain = esp_xtensa_smp_xtensa_command_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+};
diff --git a/src/target/espressif/esp_xtensa_smp.h b/src/target/espressif/esp_xtensa_smp.h
new file mode 100644
index 0000000..aeb1d61
--- /dev/null
+++ b/src/target/espressif/esp_xtensa_smp.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/***************************************************************************
+ * ESP Xtensa SMP target for OpenOCD *
+ * Copyright (C) 2020 Espressif Systems Ltd. Co *
+ ***************************************************************************/
+
+#ifndef OPENOCD_TARGET_XTENSA_ESP_SMP_H
+#define OPENOCD_TARGET_XTENSA_ESP_SMP_H
+
+#include "esp_xtensa.h"
+
+struct esp_xtensa_smp_chip_ops {
+ int (*poll)(struct target *target);
+ int (*reset)(struct target *target);
+ int (*on_halt)(struct target *target);
+};
+
+struct esp_xtensa_smp_common {
+ struct esp_xtensa_common esp_xtensa;
+ const struct esp_xtensa_smp_chip_ops *chip_ops;
+ bool other_core_does_resume;
+ /* number of attempts to examine other SMP cores, attempts are made after reset on target poll */
+ int examine_other_cores;
+};
+
+int esp_xtensa_smp_poll(struct target *target);
+int esp_xtensa_smp_resume(struct target *target,
+ int current,
+ target_addr_t address,
+ int handle_breakpoints,
+ int debug_execution);
+int esp_xtensa_smp_step(struct target *target,
+ int current,
+ target_addr_t address,
+ int handle_breakpoints);
+int esp_xtensa_smp_assert_reset(struct target *target);
+int esp_xtensa_smp_deassert_reset(struct target *target);
+int esp_xtensa_smp_soft_reset_halt(struct target *target);
+int esp_xtensa_smp_watchpoint_add(struct target *target, struct watchpoint *watchpoint);
+int esp_xtensa_smp_watchpoint_remove(struct target *target, struct watchpoint *watchpoint);
+int esp_xtensa_smp_handle_target_event(struct target *target, enum target_event event, void *priv);
+int esp_xtensa_smp_target_init(struct command_context *cmd_ctx, struct target *target);
+int esp_xtensa_smp_init_arch_info(struct target *target,
+ struct esp_xtensa_smp_common *esp_xtensa_smp,
+ struct xtensa_debug_module_config *dm_cfg,
+ const struct esp_xtensa_smp_chip_ops *chip_ops,
+ const struct esp_semihost_ops *semihost_ops);
+
+extern const struct command_registration esp_xtensa_smp_command_handlers[];
+extern const struct command_registration esp_xtensa_smp_xtensa_command_handlers[];
+extern const struct command_registration esp_xtensa_smp_esp_command_handlers[];
+
+#endif /* OPENOCD_TARGET_XTENSA_ESP_SMP_H */
diff --git a/src/target/etb.c b/src/target/etb.c
index ce1bef9..3b9004b 100644
--- a/src/target/etb.c
+++ b/src/target/etb.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/etb.h b/src/target/etb.h
index 680c8a1..fa75600 100644
--- a/src/target/etb.h
+++ b/src/target/etb.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ETB_H
diff --git a/src/target/etm.c b/src/target/etm.c
index 119c0df..57417c3 100644
--- a/src/target/etm.c
+++ b/src/target/etm.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/target/etm.h b/src/target/etm.h
index debe197..be5f2c7 100644
--- a/src/target/etm.h
+++ b/src/target/etm.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007 by Vincent Palatin *
* vincent.palatin_openocd@m4x.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ETM_H
diff --git a/src/target/etm_dummy.c b/src/target/etm_dummy.c
index ba53c7a..8deccf5 100644
--- a/src/target/etm_dummy.c
+++ b/src/target/etm_dummy.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/etm_dummy.h b/src/target/etm_dummy.h
index 5a1955f..8df2000 100644
--- a/src/target/etm_dummy.h
+++ b/src/target/etm_dummy.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_ETM_DUMMY_H
diff --git a/src/target/fa526.c b/src/target/fa526.c
index aa9e450..38b7ab2 100644
--- a/src/target/fa526.c
+++ b/src/target/fa526.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 by Paulius Zaleckas *
* paulius.zaleckas@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/target/feroceon.c b/src/target/feroceon.c
index bbb793a..1e7eb09 100644
--- a/src/target/feroceon.c
+++ b/src/target/feroceon.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008-2009 by Marvell Semiconductors, Inc. *
* Written by Nicolas Pitre <nico@marvell.com> *
* *
* Copyright (C) 2008 by Hongtao Zheng *
* hontor@126.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
diff --git a/src/target/hla_target.c b/src/target/hla_target.c
index 3e359b9..33126d6 100644
--- a/src/target/hla_target.c
+++ b/src/target/hla_target.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
@@ -6,19 +8,6 @@
* spen@spen-soft.co.uk *
* *
* revised: 4/25/13 by brent@mbari.org [DCC target request support] *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -203,7 +192,7 @@ static int adapter_target_create(struct target *target,
{
LOG_DEBUG("%s", __func__);
struct adiv5_private_config *pc = target->private_config;
- if (pc && pc->ap_num > 0) {
+ if (pc && pc->ap_num != DP_APSEL_INVALID && pc->ap_num != 0) {
LOG_ERROR("hla_target: invalid parameter -ap-num (> 0)");
return ERROR_COMMAND_SYNTAX_ERROR;
}
@@ -242,7 +231,7 @@ static int adapter_debug_entry(struct target *target)
struct armv7m_common *armv7m = target_to_armv7m(target);
struct arm *arm = &armv7m->arm;
struct reg *r;
- uint32_t xPSR;
+ uint32_t xpsr;
int retval;
/* preserve the DCRDR across halts */
@@ -260,11 +249,11 @@ static int adapter_debug_entry(struct target *target)
adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
r = arm->cpsr;
- xPSR = buf_get_u32(r->value, 0, 32);
+ xpsr = buf_get_u32(r->value, 0, 32);
/* Are we in an exception handler */
- if (xPSR & 0x1FF) {
- armv7m->exception_number = (xPSR & 0x1FF);
+ if (xpsr & 0x1FF) {
+ armv7m->exception_number = (xpsr & 0x1FF);
arm->core_mode = ARM_MODE_HANDLER;
arm->map = armv7m_msp_reg_map;
diff --git a/src/target/image.c b/src/target/image.c
index 130ea6c..f8de7a2 100644
--- a/src/target/image.c
+++ b/src/target/image.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -13,19 +15,6 @@
* *
* Copyright (C) 2018 by Advantest *
* florian.meister@advantest.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/image.h b/src/target/image.h
index bf06064..03bc068 100644
--- a/src/target/image.h
+++ b/src/target/image.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2018 by Advantest *
* florian.meister@advantest.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_IMAGE_H
diff --git a/src/target/lakemont.c b/src/target/lakemont.c
index 230f53f..5035cdb 100644
--- a/src/target/lakemont.c
+++ b/src/target/lakemont.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright(c) 2013-2016 Intel Corporation.
*
@@ -8,19 +10,6 @@
* Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)
* Jessica Gomez (jessica.gomez.hernandez@intel.com)
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
* Contact Information:
* Intel Corporation
*/
diff --git a/src/target/lakemont.h b/src/target/lakemont.h
index 98efd44..ca6557f 100644
--- a/src/target/lakemont.h
+++ b/src/target/lakemont.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright(c) 2013-2016 Intel Corporation.
*
@@ -7,19 +9,6 @@
* Julien Carreno (julien.carreno@intel.com)
* Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
* Contact Information:
* Intel Corporation
*/
diff --git a/src/target/ls1_sap.c b/src/target/ls1_sap.c
index c167224..9bd00c0 100644
--- a/src/target/ls1_sap.c
+++ b/src/target/ls1_sap.c
@@ -1,17 +1,8 @@
-/***************************************************************************
- * Copyright (C) 2015 by Esben Haabendal *
- * eha@deif.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- ***************************************************************************/
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Copyright (C) 2015 by Esben Haabendal <eha@deif.com>
+ */
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/target/mem_ap.c b/src/target/mem_ap.c
index eef05b4..a662506 100644
--- a/src/target/mem_ap.c
+++ b/src/target/mem_ap.c
@@ -1,16 +1,8 @@
-/*****************************************************************************
- * Copyright (C) 2016 by Matthias Welwarsky <matthias.welwarsky@sysgo.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- ****************************************************************************/
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Copyright (C) 2016 by Matthias Welwarsky <matthias.welwarsky@sysgo.com>
+ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -29,7 +21,7 @@ struct mem_ap {
int common_magic;
struct adiv5_dap *dap;
struct adiv5_ap *ap;
- int ap_num;
+ uint64_t ap_num;
};
static int mem_ap_target_create(struct target *target, Jim_Interp *interp)
@@ -74,8 +66,13 @@ static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *ta
static void mem_ap_deinit_target(struct target *target)
{
+ struct mem_ap *mem_ap = target->arch_info;
+
LOG_DEBUG("%s", __func__);
+ if (mem_ap->ap)
+ dap_put_ap(mem_ap->ap);
+
free(target->private_config);
free(target->arch_info);
return;
@@ -139,7 +136,16 @@ static int mem_ap_examine(struct target *target)
struct mem_ap *mem_ap = target->arch_info;
if (!target_was_examined(target)) {
- mem_ap->ap = dap_ap(mem_ap->dap, mem_ap->ap_num);
+ 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;
+ }
target_set_examined(target);
target->state = TARGET_UNKNOWN;
target->debug_reason = DBG_REASON_UNDEFINED;
@@ -179,7 +185,7 @@ static struct reg_arch_type mem_ap_reg_arch_type = {
.set = mem_ap_reg_set,
};
-const char *mem_ap_get_gdb_arch(struct target *target)
+static const char *mem_ap_get_gdb_arch(struct target *target)
{
return "arm";
}
diff --git a/src/target/mips32.c b/src/target/mips32.c
index c825369..f593b5f 100644
--- a/src/target/mips32.c
+++ b/src/target/mips32.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
@@ -9,19 +11,6 @@
* *
* Copyright (C) 2011 by Drasko DRASKOVIC *
* drasko.draskovic@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/mips32.h b/src/target/mips32.h
index 5ca3b7e..8837da1 100644
--- a/src/target/mips32.h
+++ b/src/target/mips32.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
@@ -6,19 +8,6 @@
* *
* Copyright (C) 2011 by Drasko DRASKOVIC *
* drasko.draskovic@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_MIPS32_H
@@ -27,7 +16,7 @@
#include "target.h"
#include "mips32_pracc.h"
-#define MIPS32_COMMON_MAGIC 0xB320B320
+#define MIPS32_COMMON_MAGIC 0xB320B320U
/**
* Memory segments (32bit kernel mode addresses)
@@ -93,7 +82,8 @@ struct mips32_comparator {
};
struct mips32_common {
- uint32_t common_magic;
+ unsigned int common_magic;
+
void *arch_info;
struct reg_cache *core_cache;
struct mips_ejtag ejtag_info;
@@ -130,7 +120,7 @@ struct mips32_core_reg {
};
struct mips32_algorithm {
- int common_magic;
+ unsigned int common_magic;
enum mips32_isa_mode isa_mode;
};
diff --git a/src/target/mips32_dmaacc.c b/src/target/mips32_dmaacc.c
index 220ea94..beffbf5 100644
--- a/src/target/mips32_dmaacc.c
+++ b/src/target/mips32_dmaacc.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 by John McCarthy *
* jgmcc@magma.ca *
@@ -6,19 +8,6 @@
* spen@spen-soft.co.uk *
* *
* Copyright (C) 2008 by David T.L. Wong *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/mips32_dmaacc.h b/src/target/mips32_dmaacc.h
index 70fe2a7..1725941 100644
--- a/src/target/mips32_dmaacc.h
+++ b/src/target/mips32_dmaacc.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 by John McCarthy *
* jgmcc@magma.ca *
@@ -6,19 +8,6 @@
* spen@spen-soft.co.uk *
* *
* Copyright (C) 2008 by David T.L. Wong *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_MIPS32_DMAACC_H
diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index 9f8762e..c4704b5 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
@@ -8,19 +10,6 @@
* *
* Copyright (C) 2011 by Drasko DRASKOVIC *
* drasko.draskovic@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*
@@ -161,7 +150,7 @@ static int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info)
return ERROR_OK;
}
-int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
+static int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
uint32_t *param_out, bool check_last)
{
int code_count = 0;
@@ -334,7 +323,7 @@ void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)
ctx->store_count++;
}
-void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize)
+static void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize)
{
if (LOWER16(data) == 0 && optimize)
pracc_add(ctx, 0, MIPS32_LUI(ctx->isa, reg_num, UPPER16(data))); /* load only upper value */
diff --git a/src/target/mips32_pracc.h b/src/target/mips32_pracc.h
index 30edaec..1b00768 100644
--- a/src/target/mips32_pracc.h
+++ b/src/target/mips32_pracc.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
@@ -6,19 +8,6 @@
* *
* Copyright (C) 2011 by Drasko DRASKOVIC *
* drasko.draskovic@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_MIPS32_PRACC_H
@@ -64,7 +53,6 @@ struct pracc_queue_info {
void pracc_queue_init(struct pracc_queue_info *ctx);
void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr);
-void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize);
void pracc_queue_free(struct pracc_queue_info *ctx);
int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info,
struct pracc_queue_info *ctx, uint32_t *buf, bool check_last);
@@ -79,9 +67,6 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);
int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);
-int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
- uint32_t *param_out, bool check_last);
-
/**
* \b mips32_cp0_read
*
diff --git a/src/target/mips64.c b/src/target/mips64.c
index 347cdfc..773b92d 100644
--- a/src/target/mips64.c
+++ b/src/target/mips64.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Support for processors implementing MIPS64 instruction set
*
@@ -10,8 +12,6 @@
* Copyright (C) 2008 by Spencer Oliver
* Copyright (C) 2008 by David T.L. Wong
* Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/mips64.h b/src/target/mips64.h
index 3453e4e..9079c80 100644
--- a/src/target/mips64.h
+++ b/src/target/mips64.h
@@ -19,7 +19,7 @@
#include "register.h"
#include "mips64_pracc.h"
-#define MIPS64_COMMON_MAGIC 0xB640B640
+#define MIPS64_COMMON_MAGIC 0xB640B640U
/* MIPS64 CP0 registers */
#define MIPS64_C0_INDEX 0
@@ -81,7 +81,8 @@ struct mips64_comparator {
};
struct mips64_common {
- uint32_t common_magic;
+ unsigned int common_magic;
+
void *arch_info;
struct reg_cache *core_cache;
struct mips_ejtag ejtag_info;
diff --git a/src/target/mips64_pracc.c b/src/target/mips64_pracc.c
index 81a4cfb..b083f5c 100644
--- a/src/target/mips64_pracc.c
+++ b/src/target/mips64_pracc.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Support for processors implementing MIPS64 instruction set
*
@@ -9,8 +11,6 @@
* Copyright (C) 2008 by Spencer Oliver
* Copyright (C) 2008 by David T.L. Wong
* Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c
index b21a1bd..a1a1792 100644
--- a/src/target/mips_ejtag.c
+++ b/src/target/mips_ejtag.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
@@ -5,19 +7,6 @@
* Copyright (C) 2008 by David T.L. Wong *
* *
* Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h
index e50101b..eb80742 100644
--- a/src/target/mips_ejtag.h
+++ b/src/target/mips_ejtag.h
@@ -1,21 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
* Copyright (C) 2008 by David T.L. Wong *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_MIPS_EJTAG_H
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 8601193..e85018c 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
@@ -8,19 +10,6 @@
* *
* Copyright (C) 2011 by Drasko DRASKOVIC *
* drasko.draskovic@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -1368,7 +1357,7 @@ static const struct command_registration mips_m4k_exec_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
-const struct command_registration mips_m4k_command_handlers[] = {
+static const struct command_registration mips_m4k_command_handlers[] = {
{
.chain = mips32_command_handlers,
},
diff --git a/src/target/mips_m4k.h b/src/target/mips_m4k.h
index ea09ae5..f63d72f 100644
--- a/src/target/mips_m4k.h
+++ b/src/target/mips_m4k.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
@@ -6,19 +8,6 @@
* *
* Copyright (C) 2011 by Drasko DRASKOVIC *
* drasko.draskovic@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_MIPS_M4K_H
@@ -26,12 +15,14 @@
struct target;
-#define MIPSM4K_COMMON_MAGIC 0xB321B321
+#define MIPSM4K_COMMON_MAGIC 0xB321B321U
struct mips_m4k_common {
- uint32_t common_magic;
- bool is_pic32mx;
+ unsigned int common_magic;
+
struct mips32_common mips32;
+
+ bool is_pic32mx;
};
static inline struct mips_m4k_common *
@@ -52,6 +43,5 @@ static inline void mips_m4k_isa_filter(enum mips32_isa_imp isa_imp, target_addr_
}
}
}
-extern const struct command_registration mips_m4k_command_handlers[];
#endif /* OPENOCD_TARGET_MIPS_M4K_H */
diff --git a/src/target/mips_mips64.c b/src/target/mips_mips64.c
index 5d821d7..640b4c8 100644
--- a/src/target/mips_mips64.c
+++ b/src/target/mips_mips64.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* MIPS64 generic target support
*
@@ -8,8 +10,6 @@
* Based on the work of:
* Copyright (C) 2008 by Spencer Oliver
* Copyright (C) 2008 by David T.L. Wong
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifdef HAVE_CONFIG_H
@@ -205,12 +205,6 @@ static int mips_mips64_deassert_reset(struct target *target)
return ERROR_OK;
}
-static int mips_mips64_soft_reset_halt(struct target *target)
-{
- /* TODO */
- return ERROR_OK;
-}
-
static int mips_mips64_single_step_core(struct target *target)
{
struct mips64_common *mips64 = target->arch_info;
@@ -1168,7 +1162,7 @@ struct target_type mips_mips64_target = {
.assert_reset = mips_mips64_assert_reset,
.deassert_reset = mips_mips64_deassert_reset,
- .soft_reset_halt = mips_mips64_soft_reset_halt,
+ /* TODO: add .soft_reset_halt */
.get_gdb_reg_list = mips64_get_gdb_reg_list,
diff --git a/src/target/mips_mips64.h b/src/target/mips_mips64.h
index 69fb2a6..9841deb 100644
--- a/src/target/mips_mips64.h
+++ b/src/target/mips_mips64.h
@@ -17,7 +17,8 @@
#include "helper/types.h"
struct mips_mips64_common {
- int common_magic;
+ unsigned int common_magic;
+
struct mips64_common mips64_common;
};
diff --git a/src/target/nds32.c b/src/target/nds32.c
index f0fb74d..bd30976 100644
--- a/src/target/nds32.c
+++ b/src/target/nds32.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/nds32.h b/src/target/nds32.h
index c447673..d0b680a 100644
--- a/src/target/nds32.h
+++ b/src/target/nds32.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_H
@@ -235,7 +224,8 @@ struct nds32_misc_config {
* Represents a generic Andes core.
*/
struct nds32 {
- uint32_t common_magic;
+ unsigned int common_magic;
+
struct reg_cache *core_cache;
/** Handle for the debug module. */
diff --git a/src/target/nds32_aice.c b/src/target/nds32_aice.c
index b01f8c0..8dc4d77 100644
--- a/src/target/nds32_aice.c
+++ b/src/target/nds32_aice.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes technology. *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/target/nds32_aice.h b/src/target/nds32_aice.h
index 5ea3b16..2a6c879 100644
--- a/src/target/nds32_aice.h
+++ b/src/target/nds32_aice.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes technology. *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_AICE_H
diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c
index 69c28ac..37f7648 100644
--- a/src/target/nds32_cmd.c
+++ b/src/target/nds32_cmd.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/nds32_cmd.h b/src/target/nds32_cmd.h
index 543ba54..1593243 100644
--- a/src/target/nds32_cmd.h
+++ b/src/target/nds32_cmd.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_CMD_H
diff --git a/src/target/nds32_disassembler.c b/src/target/nds32_disassembler.c
index 0bf74e1..eebbfe1 100644
--- a/src/target/nds32_disassembler.c
+++ b/src/target/nds32_disassembler.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/nds32_disassembler.h b/src/target/nds32_disassembler.h
index 9117cbb..f2c8e85 100644
--- a/src/target/nds32_disassembler.h
+++ b/src/target/nds32_disassembler.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_DISASSEMBLER_H
diff --git a/src/target/nds32_edm.h b/src/target/nds32_edm.h
index 2b5067a..3213604 100644
--- a/src/target/nds32_edm.h
+++ b/src/target/nds32_edm.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_EDM_H
diff --git a/src/target/nds32_insn.h b/src/target/nds32_insn.h
index 4e0b2d5..25eb9ab 100644
--- a/src/target/nds32_insn.h
+++ b/src/target/nds32_insn.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_INSN_H
diff --git a/src/target/nds32_reg.c b/src/target/nds32_reg.c
index 034a075..1687e69 100644
--- a/src/target/nds32_reg.c
+++ b/src/target/nds32_reg.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/target/nds32_reg.h b/src/target/nds32_reg.h
index 8808cd2..30cd241 100644
--- a/src/target/nds32_reg.h
+++ b/src/target/nds32_reg.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_REG_H
diff --git a/src/target/nds32_tlb.c b/src/target/nds32_tlb.c
index 81734e0..a533e59 100644
--- a/src/target/nds32_tlb.c
+++ b/src/target/nds32_tlb.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/target/nds32_tlb.h b/src/target/nds32_tlb.h
index c22ed73..1edff29 100644
--- a/src/target/nds32_tlb.h
+++ b/src/target/nds32_tlb.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_TLB_H
diff --git a/src/target/nds32_v2.c b/src/target/nds32_v2.c
index 49a5758..2149291 100644
--- a/src/target/nds32_v2.c
+++ b/src/target/nds32_v2.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/nds32_v2.h b/src/target/nds32_v2.h
index dcc08c2..3c30108 100644
--- a/src/target/nds32_v2.h
+++ b/src/target/nds32_v2.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_V2_H
diff --git a/src/target/nds32_v3.c b/src/target/nds32_v3.c
index fde86d6..9d02e5a 100644
--- a/src/target/nds32_v3.c
+++ b/src/target/nds32_v3.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/nds32_v3.h b/src/target/nds32_v3.h
index a5df8fe..389838d 100644
--- a/src/target/nds32_v3.h
+++ b/src/target/nds32_v3.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_V3_H
diff --git a/src/target/nds32_v3_common.c b/src/target/nds32_v3_common.c
index 8ff8e30..f2efab4 100644
--- a/src/target/nds32_v3_common.c
+++ b/src/target/nds32_v3_common.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/nds32_v3_common.h b/src/target/nds32_v3_common.h
index 23393e5..a98988e 100644
--- a/src/target/nds32_v3_common.h
+++ b/src/target/nds32_v3_common.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_V3_COMMON_H
diff --git a/src/target/nds32_v3m.c b/src/target/nds32_v3m.c
index ffd646f..6bc549f 100644
--- a/src/target/nds32_v3m.c
+++ b/src/target/nds32_v3m.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/nds32_v3m.h b/src/target/nds32_v3m.h
index 1e7427c..f21dd62 100644
--- a/src/target/nds32_v3m.h
+++ b/src/target/nds32_v3m.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_V3M_H
diff --git a/src/target/openrisc/Makefile.am b/src/target/openrisc/Makefile.am
index 5a2549a..b9c0f83 100644
--- a/src/target/openrisc/Makefile.am
+++ b/src/target/openrisc/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libopenrisc.la
%C%_libopenrisc_la_SOURCES = \
%D%/or1k.c \
diff --git a/src/target/openrisc/jsp_server.c b/src/target/openrisc/jsp_server.c
index 54c9694..185a506 100644
--- a/src/target/openrisc/jsp_server.c
+++ b/src/target/openrisc/jsp_server.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2014 by Franck Jullien *
* franck.jullien@gmail.com *
* *
* Based on ./src/server/telnet_server.c *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/openrisc/jsp_server.h b/src/target/openrisc/jsp_server.h
index e5cfaa8..a522fa8 100644
--- a/src/target/openrisc/jsp_server.h
+++ b/src/target/openrisc/jsp_server.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
#ifndef OPENOCD_TARGET_OPENRISC_JSP_SERVER_H
#define OPENOCD_TARGET_OPENRISC_JSP_SERVER_H
diff --git a/src/target/openrisc/or1k.c b/src/target/openrisc/or1k.c
index 77fa15d..d73bca2 100644
--- a/src/target/openrisc/or1k.c
+++ b/src/target/openrisc/or1k.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2011 by Julius Baxter *
* julius@opencores.org *
@@ -8,19 +10,6 @@
* Copyright (C) 2013 by Franck Jullien *
* elec4fun@gmail.com *
* *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/openrisc/or1k.h b/src/target/openrisc/or1k.h
index c456ccb..8f76a06 100644
--- a/src/target/openrisc/or1k.h
+++ b/src/target/openrisc/or1k.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2011 by Julius Baxter *
* julius@opencores.org *
@@ -8,19 +10,6 @@
* Copyright (C) 2013 by Franck Jullien *
* elec4fun@gmail.com *
* *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_OPENRISC_OR1K_H
diff --git a/src/target/openrisc/or1k_du.h b/src/target/openrisc/or1k_du.h
index 9828b0d..ae95376 100644
--- a/src/target/openrisc/or1k_du.h
+++ b/src/target/openrisc/or1k_du.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2013 Franck Jullien *
* elec4fun@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_OPENRISC_OR1K_DU_H
diff --git a/src/target/openrisc/or1k_du_adv.c b/src/target/openrisc/or1k_du_adv.c
index 885fcb9..cfb7d0e 100644
--- a/src/target/openrisc/or1k_du_adv.c
+++ b/src/target/openrisc/or1k_du_adv.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013-2014 by Franck Jullien *
* elec4fun@gmail.com *
@@ -9,19 +11,6 @@
* And the Mohor interface version of this file which is: *
* Copyright (C) 2011 by Julius Baxter *
* julius@opencores.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/openrisc/or1k_tap.h b/src/target/openrisc/or1k_tap.h
index 2cf7da8..e06a5e0 100644
--- a/src/target/openrisc/or1k_tap.h
+++ b/src/target/openrisc/or1k_tap.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2012 by Franck Jullien *
* elec4fun@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_OPENRISC_OR1K_TAP_H
diff --git a/src/target/openrisc/or1k_tap_mohor.c b/src/target/openrisc/or1k_tap_mohor.c
index 1415e32..0dedb3e 100644
--- a/src/target/openrisc/or1k_tap_mohor.c
+++ b/src/target/openrisc/or1k_tap_mohor.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Franck Jullien *
* elec4fun@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/openrisc/or1k_tap_vjtag.c b/src/target/openrisc/or1k_tap_vjtag.c
index 28366cf..783b4db 100644
--- a/src/target/openrisc/or1k_tap_vjtag.c
+++ b/src/target/openrisc/or1k_tap_vjtag.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Franck Jullien *
* elec4fun@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/openrisc/or1k_tap_xilinx_bscan.c b/src/target/openrisc/or1k_tap_xilinx_bscan.c
index a77c65e..6b3df0e 100644
--- a/src/target/openrisc/or1k_tap_xilinx_bscan.c
+++ b/src/target/openrisc/or1k_tap_xilinx_bscan.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2013 by Sergio Chico *
* sergio.chico@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/quark_d20xx.c b/src/target/quark_d20xx.c
index 211245d..d63a42a 100644
--- a/src/target/quark_d20xx.c
+++ b/src/target/quark_d20xx.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright(c) 2015-2016 Intel Corporation.
*
* Jessica Gomez (jessica.gomez.hernandez@intel.com)
* Ivan De Cesaris (ivan.de.cesaris@intel.com)
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
* Contact Information:
* Intel Corporation
*/
diff --git a/src/target/quark_x10xx.c b/src/target/quark_x10xx.c
index 525d39a..0daa642 100644
--- a/src/target/quark_x10xx.c
+++ b/src/target/quark_x10xx.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright(c) 2013-2016 Intel Corporation.
*
@@ -7,19 +9,6 @@
* Julien Carreno (julien.carreno@intel.com)
* Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
* Contact Information:
* Intel Corporation
*/
diff --git a/src/target/register.c b/src/target/register.c
index 6387475..2287125 100644
--- a/src/target/register.c
+++ b/src/target/register.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/register.h b/src/target/register.h
index a7705f7..1e4f2e0 100644
--- a/src/target/register.h
+++ b/src/target/register.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_REGISTER_H
diff --git a/src/target/riscv/Makefile.am b/src/target/riscv/Makefile.am
index 83f1a8c..4b6a74f 100644
--- a/src/target/riscv/Makefile.am
+++ b/src/target/riscv/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libriscv.la
%C%_libriscv_la_SOURCES = \
%D%/asm.h \
diff --git a/src/target/riscv/batch.c b/src/target/riscv/batch.c
index 4c1667d..217c36d 100644
--- a/src/target/riscv/batch.c
+++ b/src/target/riscv/batch.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/target/riscv/program.c b/src/target/riscv/program.c
index 16baa4b..ce28026 100644
--- a/src/target/riscv/program.c
+++ b/src/target/riscv/program.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c
index e38d854..c6f4f84 100644
--- a/src/target/riscv/riscv-011.c
+++ b/src/target/riscv/riscv-011.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Support for RISC-V, debug version 0.11. This was never an officially adopted
@@ -229,10 +229,10 @@ static int get_register(struct target *target, riscv_reg_t *value, int regid);
static riscv011_info_t *get_info(const struct target *target)
{
- riscv_info_t *info = (riscv_info_t *) target->arch_info;
+ struct riscv_info *info = target->arch_info;
assert(info);
assert(info->version_specific);
- return (riscv011_info_t *) info->version_specific;
+ return info->version_specific;
}
static unsigned int slot_offset(const struct target *target, slot_t slot)
@@ -1403,7 +1403,10 @@ static int halt(struct target *target)
static void deinit_target(struct target *target)
{
LOG_DEBUG("riscv_deinit_target()");
- riscv_info_t *info = (riscv_info_t *) target->arch_info;
+ struct riscv_info *info = target->arch_info;
+ if (!info)
+ return;
+
free(info->version_specific);
info->version_specific = NULL;
}
@@ -1544,7 +1547,7 @@ static int examine(struct target *target)
uint32_t word0 = cache_get32(target, 0);
uint32_t word1 = cache_get32(target, 1);
- riscv_info_t *generic_info = (riscv_info_t *) target->arch_info;
+ struct riscv_info *generic_info = riscv_info(target);
if (word0 == 1 && word1 == 0) {
generic_info->xlen = 32;
} else if (word0 == 0xffffffff && word1 == 3) {
@@ -2288,7 +2291,7 @@ static int arch_state(struct target *target)
return ERROR_OK;
}
-COMMAND_HELPER(riscv011_print_info, struct target *target)
+static COMMAND_HELPER(riscv011_print_info, struct target *target)
{
/* Abstract description. */
riscv_print_info_line(CMD, "target", "memory.read_while_running8", 0);
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 3043b06..1842667 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Support for RISC-V, debug version 0.13, which is currently (2/4/17) the
@@ -34,7 +34,7 @@ static int riscv013_step_or_resume_current_hart(struct target *target,
bool step);
static void riscv013_clear_abstract_error(struct target *target);
-/* Implementations of the functions in riscv_info_t. */
+/* Implementations of the functions in struct riscv_info. */
static int riscv013_get_register(struct target *target,
riscv_reg_t *value, int rid);
static int riscv013_set_register(struct target *target, int regid, uint64_t value);
@@ -209,14 +209,14 @@ typedef struct {
bool selected;
} riscv013_info_t;
-LIST_HEAD(dm_list);
+static LIST_HEAD(dm_list);
static riscv013_info_t *get_info(const struct target *target)
{
- riscv_info_t *info = (riscv_info_t *) target->arch_info;
+ struct riscv_info *info = target->arch_info;
assert(info);
assert(info->version_specific);
- return (riscv013_info_t *) info->version_specific;
+ return info->version_specific;
}
/**
@@ -224,7 +224,7 @@ static riscv013_info_t *get_info(const struct target *target)
* global list of DMs. If it's not in there, then create one and initialize it
* to 0.
*/
-dm013_info_t *get_dm(struct target *target)
+static dm013_info_t *get_dm(struct target *target)
{
RISCV013_INFO(info);
if (info->dm)
@@ -677,7 +677,7 @@ static int dmi_write_exec(struct target *target, uint32_t address,
return dmi_op(target, NULL, NULL, DMI_OP_WRITE, address, value, true, ensure_success);
}
-int dmstatus_read_timeout(struct target *target, uint32_t *dmstatus,
+static int dmstatus_read_timeout(struct target *target, uint32_t *dmstatus,
bool authenticated, unsigned timeout_sec)
{
int result = dmi_op_timeout(target, dmstatus, NULL, DMI_OP_READ,
@@ -699,7 +699,7 @@ int dmstatus_read_timeout(struct target *target, uint32_t *dmstatus,
return ERROR_OK;
}
-int dmstatus_read(struct target *target, uint32_t *dmstatus,
+static int dmstatus_read(struct target *target, uint32_t *dmstatus,
bool authenticated)
{
int result = dmstatus_read_timeout(target, dmstatus, authenticated,
@@ -721,7 +721,7 @@ static void increase_ac_busy_delay(struct target *target)
info->ac_busy_delay);
}
-uint32_t abstract_register_size(unsigned width)
+static uint32_t __attribute__((unused)) abstract_register_size(unsigned width)
{
switch (width) {
case 32:
@@ -1502,7 +1502,10 @@ static int wait_for_authbusy(struct target *target, uint32_t *dmstatus)
static void deinit_target(struct target *target)
{
LOG_DEBUG("riscv_deinit_target()");
- riscv_info_t *info = (riscv_info_t *) target->arch_info;
+ struct riscv_info *info = target->arch_info;
+ if (!info)
+ return;
+
free(info->version_specific);
/* TODO: free register arch_info */
info->version_specific = NULL;
@@ -1870,7 +1873,7 @@ static unsigned riscv013_data_bits(struct target *target)
return 32;
}
-COMMAND_HELPER(riscv013_print_info, struct target *target)
+static COMMAND_HELPER(riscv013_print_info, struct target *target)
{
RISCV013_INFO(info);
@@ -2427,9 +2430,7 @@ static int assert_reset(struct target *target)
/* TODO: Try to use hasel in dmcontrol */
/* Set haltreq for each hart. */
- uint32_t control = control_base;
-
- control = set_dmcontrol_hartsel(control_base, info->index);
+ uint32_t control = set_dmcontrol_hartsel(control_base, info->index);
control = set_field(control, DM_DMCONTROL_HALTREQ,
target->reset_halt ? 1 : 0);
dmi_write(target, DM_DMCONTROL, control);
@@ -4235,7 +4236,7 @@ static int select_prepped_harts(struct target *target)
unsigned int selected_index = 0;
list_for_each_entry(entry, &dm->target_list, list) {
struct target *t = entry->target;
- riscv_info_t *info = riscv_info(t);
+ struct riscv_info *info = riscv_info(t);
riscv013_info_t *info_013 = get_info(t);
unsigned index = info_013->index;
LOG_DEBUG("index=%d, coreid=%d, prepped=%d", index, t->coreid, info->prepped);
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index f5f2332..c64a98c 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
#include <assert.h>
#include <stdlib.h>
@@ -37,38 +37,38 @@
#define DBUS 0x11
-uint8_t ir_dtmcontrol[4] = {DTMCONTROL};
+static uint8_t ir_dtmcontrol[4] = {DTMCONTROL};
struct scan_field select_dtmcontrol = {
.in_value = NULL,
.out_value = ir_dtmcontrol
};
-uint8_t ir_dbus[4] = {DBUS};
+static uint8_t ir_dbus[4] = {DBUS};
struct scan_field select_dbus = {
.in_value = NULL,
.out_value = ir_dbus
};
-uint8_t ir_idcode[4] = {0x1};
+static uint8_t ir_idcode[4] = {0x1};
struct scan_field select_idcode = {
.in_value = NULL,
.out_value = ir_idcode
};
-bscan_tunnel_type_t bscan_tunnel_type;
+static bscan_tunnel_type_t bscan_tunnel_type;
int bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */
static int bscan_tunnel_ir_id; /* IR ID of the JTAG TAP to access the tunnel. Valid when not 0 */
static const uint8_t bscan_zero[4] = {0};
static const uint8_t bscan_one[4] = {1};
-uint8_t ir_user4[4];
-struct scan_field select_user4 = {
+static uint8_t ir_user4[4];
+static struct scan_field select_user4 = {
.in_value = NULL,
.out_value = ir_user4
};
-uint8_t bscan_tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */
-struct scan_field _bscan_tunnel_data_register_select_dmi[] = {
+static uint8_t bscan_tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */
+static struct scan_field _bscan_tunnel_data_register_select_dmi[] = {
{
.num_bits = 3,
.out_value = bscan_zero,
@@ -91,7 +91,7 @@ struct scan_field _bscan_tunnel_data_register_select_dmi[] = {
}
};
-struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = {
+static struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = {
{
.num_bits = 1,
.out_value = bscan_zero,
@@ -113,11 +113,11 @@ struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = {
.in_value = NULL,
}
};
-struct scan_field *bscan_tunnel_nested_tap_select_dmi = _bscan_tunnel_nested_tap_select_dmi;
-uint32_t bscan_tunnel_nested_tap_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_nested_tap_select_dmi);
+static struct scan_field *bscan_tunnel_nested_tap_select_dmi = _bscan_tunnel_nested_tap_select_dmi;
+static uint32_t bscan_tunnel_nested_tap_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_nested_tap_select_dmi);
-struct scan_field *bscan_tunnel_data_register_select_dmi = _bscan_tunnel_data_register_select_dmi;
-uint32_t bscan_tunnel_data_register_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_data_register_select_dmi);
+static struct scan_field *bscan_tunnel_data_register_select_dmi = _bscan_tunnel_data_register_select_dmi;
+static uint32_t bscan_tunnel_data_register_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_data_register_select_dmi);
struct trigger {
uint64_t address;
@@ -134,7 +134,7 @@ int riscv_command_timeout_sec = DEFAULT_COMMAND_TIMEOUT_SEC;
/* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/
int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC;
-bool riscv_enable_virt2phys = true;
+static bool riscv_enable_virt2phys = true;
bool riscv_ebreakm = true;
bool riscv_ebreaks = true;
bool riscv_ebreaku = true;
@@ -146,7 +146,7 @@ static enum {
RO_REVERSED
} resume_order;
-const virt2phys_info_t sv32 = {
+static const virt2phys_info_t sv32 = {
.name = "Sv32",
.va_bits = 32,
.level = 2,
@@ -159,7 +159,7 @@ const virt2phys_info_t sv32 = {
.pa_ppn_mask = {0x3ff, 0xfff},
};
-const virt2phys_info_t sv39 = {
+static const virt2phys_info_t sv39 = {
.name = "Sv39",
.va_bits = 39,
.level = 3,
@@ -172,7 +172,7 @@ const virt2phys_info_t sv39 = {
.pa_ppn_mask = {0x1ff, 0x1ff, 0x3ffffff},
};
-const virt2phys_info_t sv48 = {
+static const virt2phys_info_t sv48 = {
.name = "Sv48",
.va_bits = 48,
.level = 4,
@@ -185,7 +185,12 @@ const virt2phys_info_t sv48 = {
.pa_ppn_mask = {0x1ff, 0x1ff, 0x1ff, 0x1ffff},
};
-void riscv_sample_buf_maybe_add_timestamp(struct target *target, bool before)
+static enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid);
+static void riscv_info_init(struct target *target, struct riscv_info *r);
+static void riscv_invalidate_register_cache(struct target *target);
+static int riscv_step_rtos_hart(struct target *target);
+
+static void riscv_sample_buf_maybe_add_timestamp(struct target *target, bool before)
{
RISCV_INFO(r);
uint32_t now = timeval_ms() & 0xffffffff;
@@ -334,13 +339,12 @@ static uint32_t dtmcontrol_scan(struct target *target, uint32_t out)
static struct target_type *get_target_type(struct target *target)
{
- riscv_info_t *info = (riscv_info_t *) target->arch_info;
-
- if (!info) {
+ if (!target->arch_info) {
LOG_ERROR("Target has not been initialized");
return NULL;
}
+ RISCV_INFO(info);
switch (info->dtm_version) {
case 0:
return &riscv011_target;
@@ -356,7 +360,7 @@ static struct target_type *get_target_type(struct target *target)
static int riscv_create_target(struct target *target, Jim_Interp *interp)
{
LOG_DEBUG("riscv_create_target()");
- target->arch_info = calloc(1, sizeof(riscv_info_t));
+ target->arch_info = calloc(1, sizeof(struct riscv_info));
if (!target->arch_info) {
LOG_ERROR("Failed to allocate RISC-V target structure.");
return ERROR_FAIL;
@@ -383,10 +387,7 @@ static int riscv_init_target(struct command_context *cmd_ctx,
assert(target->tap->ir_length >= 6);
ir_user4_raw = 0x23 << (target->tap->ir_length - 6);
}
- ir_user4[0] = (uint8_t)ir_user4_raw;
- ir_user4[1] = (uint8_t)(ir_user4_raw >>= 8);
- ir_user4[2] = (uint8_t)(ir_user4_raw >>= 8);
- ir_user4[3] = (uint8_t)(ir_user4_raw >>= 8);
+ h_u32_to_le(ir_user4, ir_user4_raw);
select_user4.num_bits = target->tap->ir_length;
bscan_tunneled_ir_width[0] = bscan_tunnel_ir_width;
if (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)
@@ -423,17 +424,20 @@ static void riscv_deinit_target(struct target *target)
{
LOG_DEBUG("riscv_deinit_target()");
- riscv_info_t *info = target->arch_info;
+ struct riscv_info *info = target->arch_info;
struct target_type *tt = get_target_type(target);
if (riscv_flush_registers(target) != ERROR_OK)
LOG_ERROR("[%s] Failed to flush registers. Ignoring this error.", target_name(target));
- if (tt && info->version_specific)
+ if (tt && info && info->version_specific)
tt->deinit_target(target);
riscv_free_registers(target);
+ if (!info)
+ return;
+
range_list_t *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &info->hide_csr, list) {
free(entry->name);
@@ -1076,7 +1080,7 @@ int riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_
return ERROR_FAIL;
}
-int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
+static int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
{
LOG_TARGET_DEBUG(target, "@0x%" TARGET_PRIxADDR, breakpoint->address);
assert(breakpoint);
@@ -1158,7 +1162,7 @@ static int remove_trigger(struct target *target, int unique_id)
return ERROR_OK;
}
-int riscv_remove_breakpoint(struct target *target,
+static int riscv_remove_breakpoint(struct target *target,
struct breakpoint *breakpoint)
{
if (breakpoint->type == BKPT_SOFT) {
@@ -1306,7 +1310,7 @@ static int riscv_hit_trigger_hit_bit(struct target *target, uint32_t *unique_id)
* The GDB server uses this information to tell GDB what data address has
* been hit, which enables GDB to print the hit variable along with its old
* and new value. */
-int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
+static int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
{
RISCV_INFO(r);
@@ -1474,7 +1478,7 @@ int riscv_flush_registers(struct target *target)
}
/* Convert: RISC-V hart's halt reason --> OpenOCD's generic debug reason */
-int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason)
+static int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason)
{
RISCV_INFO(r);
r->trigger_hit = -1;
@@ -1510,7 +1514,7 @@ int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason)
return ERROR_OK;
}
-int halt_prep(struct target *target)
+static int halt_prep(struct target *target)
{
RISCV_INFO(r);
@@ -1530,7 +1534,7 @@ int halt_prep(struct target *target)
return ERROR_OK;
}
-int riscv_halt_go_all_harts(struct target *target)
+static int riscv_halt_go_all_harts(struct target *target)
{
RISCV_INFO(r);
@@ -1549,9 +1553,9 @@ int riscv_halt_go_all_harts(struct target *target)
return ERROR_OK;
}
-int halt_go(struct target *target)
+static int halt_go(struct target *target)
{
- riscv_info_t *r = riscv_info(target);
+ RISCV_INFO(r);
int result;
if (!r->get_hart_state) {
struct target_type *tt = get_target_type(target);
@@ -1592,7 +1596,7 @@ int riscv_halt(struct target *target)
foreach_smp_target(tlist, target->smp_targets) {
struct target *t = tlist->target;
- riscv_info_t *i = riscv_info(t);
+ struct riscv_info *i = riscv_info(t);
if (i->prepped) {
if (halt_go(t) != ERROR_OK)
result = ERROR_FAIL;
@@ -1763,7 +1767,7 @@ static int resume_prep(struct target *target, int current,
static int resume_go(struct target *target, int current,
target_addr_t address, int handle_breakpoints, int debug_execution)
{
- riscv_info_t *r = riscv_info(target);
+ RISCV_INFO(r);
int result;
if (!r->get_hart_state) {
struct target_type *tt = get_target_type(target);
@@ -1790,7 +1794,7 @@ static int resume_finish(struct target *target, int debug_execution)
* @par single_hart When true, only resume a single hart even if SMP is
* configured. This is used to run algorithms on just one hart.
*/
-int riscv_resume(
+static int riscv_resume(
struct target *target,
int current,
target_addr_t address,
@@ -1830,7 +1834,7 @@ int riscv_resume(
foreach_smp_target_direction(resume_order == RO_NORMAL, tlist, targets) {
struct target *t = tlist->target;
- riscv_info_t *i = riscv_info(t);
+ struct riscv_info *i = riscv_info(t);
if (i->prepped) {
if (resume_go(t, current, address, handle_breakpoints,
debug_execution) != ERROR_OK)
@@ -1941,6 +1945,7 @@ static int riscv_address_translate(struct target *target,
LOG_DEBUG("virtual=0x%" TARGET_PRIxADDR "; mode=%s", virtual, info->name);
/* verify bits xlen-1:va_bits-1 are all equal */
+ assert(xlen >= info->va_bits);
target_addr_t mask = ((target_addr_t)1 << (xlen - (info->va_bits - 1))) - 1;
target_addr_t masked_msbs = (virtual >> (info->va_bits - 1)) & mask;
if (masked_msbs != 0 && masked_msbs != mask) {
@@ -2067,7 +2072,7 @@ static int riscv_write_memory(struct target *target, target_addr_t address,
return tt->write_memory(target, address, size, count, buffer);
}
-const char *riscv_get_gdb_arch(struct target *target)
+static const char *riscv_get_gdb_arch(struct target *target)
{
switch (riscv_xlen(target)) {
case 32:
@@ -2522,7 +2527,7 @@ static int riscv_poll_hart(struct target *target, enum riscv_next_action *next_a
return ERROR_OK;
}
-int sample_memory(struct target *target)
+static int sample_memory(struct target *target)
{
RISCV_INFO(r);
@@ -2873,7 +2878,7 @@ COMMAND_HANDLER(riscv_set_enable_virtual)
return ERROR_OK;
}
-int parse_ranges(struct list_head *ranges, const char *tcl_arg, const char *reg_type, unsigned int max_val)
+static int parse_ranges(struct list_head *ranges, const char *tcl_arg, const char *reg_type, unsigned int max_val)
{
char *args = strdup(tcl_arg);
if (!args)
@@ -3099,27 +3104,25 @@ COMMAND_HANDLER(riscv_authdata_write)
uint32_t value;
unsigned int index = 0;
- if (CMD_ARGC == 0) {
- /* nop */
- } else if (CMD_ARGC == 1) {
+ if (CMD_ARGC == 0 || CMD_ARGC > 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (CMD_ARGC == 1) {
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], value);
- } else if (CMD_ARGC == 2) {
+ } else {
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], index);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
- } else {
- LOG_ERROR("Command takes at most 2 arguments");
- return ERROR_COMMAND_SYNTAX_ERROR;
}
struct target *target = get_current_target(CMD_CTX);
RISCV_INFO(r);
- if (r->authdata_write) {
- return r->authdata_write(target, value, index);
- } else {
+ if (!r->authdata_write) {
LOG_ERROR("authdata_write is not implemented for this target.");
return ERROR_FAIL;
}
+
+ return r->authdata_write(target, value, index);
}
COMMAND_HANDLER(riscv_dmi_read)
@@ -4077,9 +4080,8 @@ static const struct command_registration riscv_exec_command_handlers[] = {
* protocol, then a command like `riscv semihosting enable` will make
* sense, but for now all semihosting commands are prefixed with `arm`.
*/
-extern const struct command_registration semihosting_common_handlers[];
-const struct command_registration riscv_command_handlers[] = {
+static const struct command_registration riscv_command_handlers[] = {
{
.name = "riscv",
.mode = COMMAND_ANY,
@@ -4161,9 +4163,13 @@ struct target_type riscv_target = {
/*** RISC-V Interface ***/
-void riscv_info_init(struct target *target, riscv_info_t *r)
+/* Initializes the shared RISC-V structure. */
+static void riscv_info_init(struct target *target, struct riscv_info *r)
{
memset(r, 0, sizeof(*r));
+
+ r->common_magic = RISCV_COMMON_MAGIC;
+
r->dtm_version = 1;
r->version_specific = NULL;
@@ -4251,7 +4257,7 @@ int riscv_interrupts_restore(struct target *target, uint64_t old_mstatus)
return reg_mstatus->type->set(reg_mstatus, mstatus_bytes);
}
-int riscv_step_rtos_hart(struct target *target)
+static int riscv_step_rtos_hart(struct target *target)
{
RISCV_INFO(r);
LOG_DEBUG("[%s] stepping", target_name(target));
@@ -4290,7 +4296,7 @@ unsigned riscv_xlen(const struct target *target)
return r->xlen;
}
-void riscv_invalidate_register_cache(struct target *target)
+static void riscv_invalidate_register_cache(struct target *target)
{
/* Do not invalidate the register cache if it is not yet set up
* (e.g. when the target failed to get examined). */
@@ -4466,7 +4472,7 @@ int riscv_save_register(struct target *target, enum gdb_regno regid)
return ERROR_OK;
}
-int riscv_get_hart_state(struct target *target, enum riscv_hart_state *state)
+static int riscv_get_hart_state(struct target *target, enum riscv_hart_state *state)
{
RISCV_INFO(r);
assert(r->get_hart_state);
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 6b4d577..591fb3f 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -10,8 +10,11 @@ struct riscv_program;
#include "gdb_regs.h"
#include "jtag/jtag.h"
#include "target/register.h"
+#include "target/semihosting_common.h"
#include <helper/command.h>
+#define RISCV_COMMON_MAGIC 0x52495356U
+
/* The register cache is statically allocated. */
#define RISCV_MAX_HARTS 1024
#define RISCV_MAX_REGISTERS 5000
@@ -106,7 +109,9 @@ typedef struct {
char *name;
} range_list_t;
-typedef struct {
+struct riscv_info {
+ unsigned int common_magic;
+
unsigned dtm_version;
struct command_context *cmd_ctx;
@@ -265,7 +270,7 @@ typedef struct {
int64_t last_activity;
yes_no_maybe_t vsew64_supported;
-} riscv_info_t;
+};
COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,
unsigned int value);
@@ -301,27 +306,27 @@ extern bool riscv_ebreaku;
/* Everything needs the RISC-V specific info structure, so here's a nice macro
* that provides that. */
-static inline riscv_info_t *riscv_info(const struct target *target) __attribute__((unused));
-static inline riscv_info_t *riscv_info(const struct target *target)
+static inline struct riscv_info *riscv_info(const struct target *target) __attribute__((unused));
+static inline struct riscv_info *riscv_info(const struct target *target)
{
assert(target->arch_info);
return target->arch_info;
}
-#define RISCV_INFO(R) riscv_info_t *R = riscv_info(target);
+#define RISCV_INFO(R) struct riscv_info *R = riscv_info(target);
+
+static inline bool is_riscv(const struct riscv_info *riscv_info)
+{
+ return riscv_info->common_magic == RISCV_COMMON_MAGIC;
+}
-extern uint8_t ir_dtmcontrol[4];
extern struct scan_field select_dtmcontrol;
-extern uint8_t ir_dbus[4];
extern struct scan_field select_dbus;
-extern uint8_t ir_idcode[4];
extern struct scan_field select_idcode;
-extern struct scan_field select_user4;
extern struct scan_field *bscan_tunneled_select_dmi;
extern uint32_t bscan_tunneled_select_dmi_num_fields;
typedef enum { BSCAN_TUNNEL_NESTED_TAP, BSCAN_TUNNEL_DATA_REGISTER } bscan_tunnel_type_t;
extern int bscan_tunnel_ir_width;
-extern bscan_tunnel_type_t bscan_tunnel_type;
uint32_t dtmcontrol_scan_via_bscan(struct target *target, uint32_t out);
void select_dmi_via_bscan(struct target *target);
@@ -331,15 +336,6 @@ int riscv_openocd_poll(struct target *target);
int riscv_halt(struct target *target);
-int riscv_resume(
- struct target *target,
- int current,
- target_addr_t address,
- int handle_breakpoints,
- int debug_execution,
- bool single_hart
-);
-
int riscv_openocd_step(
struct target *target,
int current,
@@ -352,13 +348,6 @@ int riscv_openocd_deassert_reset(struct target *target);
/*** RISC-V Interface ***/
-/* Initializes the shared RISC-V structure. */
-void riscv_info_init(struct target *target, riscv_info_t *r);
-
-/* Steps the hart that's currently selected in the RTOS, or if there is no RTOS
- * then the only hart. */
-int riscv_step_rtos_hart(struct target *target);
-
bool riscv_supports_extension(struct target *target, char letter);
/* Returns XLEN for the given (or current) hart. */
@@ -407,29 +396,17 @@ void riscv_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t
void riscv_fill_dmi_read_u64(struct target *target, char *buf, int a);
int riscv_dmi_write_u64_bits(struct target *target);
-/* Invalidates the register cache. */
-void riscv_invalidate_register_cache(struct target *target);
-
int riscv_enumerate_triggers(struct target *target);
-int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint);
-int riscv_remove_breakpoint(struct target *target,
- struct breakpoint *breakpoint);
int riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint);
int riscv_remove_watchpoint(struct target *target,
struct watchpoint *watchpoint);
-int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_wp_address);
int riscv_init_registers(struct target *target);
void riscv_semihosting_init(struct target *target);
-typedef enum {
- SEMI_NONE, /* Not halted for a semihosting call. */
- SEMI_HANDLED, /* Call handled, and target was resumed. */
- SEMI_WAITING, /* Call handled, target is halted waiting until we can resume. */
- SEMI_ERROR /* Something went wrong. */
-} semihosting_result_t;
-semihosting_result_t riscv_semihosting(struct target *target, int *retval);
+
+enum semihosting_result riscv_semihosting(struct target *target, int *retval);
void riscv_add_bscan_tunneled_scan(struct target *target, struct scan_field *field,
riscv_bscan_tunneled_scan_context_t *ctxt);
diff --git a/src/target/riscv/riscv_semihosting.c b/src/target/riscv/riscv_semihosting.c
index 2c53813..5e630c4 100644
--- a/src/target/riscv/riscv_semihosting.c
+++ b/src/target/riscv/riscv_semihosting.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/***************************************************************************
* Copyright (C) 2018 by Liviu Ionescu *
@@ -12,19 +12,6 @@
* *
* Copyright (C) 2016 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
@@ -44,7 +31,6 @@
#include <helper/log.h>
#include "target/target.h"
-#include "target/semihosting_common.h"
#include "riscv.h"
static int riscv_semihosting_setup(struct target *target, int enable);
@@ -67,23 +53,23 @@ void riscv_semihosting_init(struct target *target)
* @param retval Pointer to a location where the return code will be stored
* @return non-zero value if a request was processed or an error encountered
*/
-semihosting_result_t riscv_semihosting(struct target *target, int *retval)
+enum semihosting_result riscv_semihosting(struct target *target, int *retval)
{
struct semihosting *semihosting = target->semihosting;
if (!semihosting) {
LOG_DEBUG(" -> NONE (!semihosting)");
- return SEMI_NONE;
+ return SEMIHOSTING_NONE;
}
if (!semihosting->is_active) {
LOG_DEBUG(" -> NONE (!semihosting->is_active)");
- return SEMI_NONE;
+ return SEMIHOSTING_NONE;
}
riscv_reg_t pc;
int result = riscv_get_register(target, &pc, GDB_REGNO_PC);
if (result != ERROR_OK)
- return SEMI_ERROR;
+ return SEMIHOSTING_ERROR;
uint8_t tmp_buf[12];
@@ -92,7 +78,7 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval)
/* Instruction memories may not support arbitrary read size. Use any size that will work. */
*retval = riscv_read_by_any_size(target, (pc - 4) + 4 * i, 4, tmp_buf + 4 * i);
if (*retval != ERROR_OK)
- return SEMI_ERROR;
+ return SEMIHOSTING_ERROR;
}
/*
@@ -111,7 +97,7 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval)
if (pre != 0x01f01013 || ebreak != 0x00100073 || post != 0x40705013) {
/* Not the magic sequence defining semihosting. */
LOG_DEBUG(" -> NONE (no magic)");
- return SEMI_NONE;
+ return SEMIHOSTING_NONE;
}
/*
@@ -126,13 +112,13 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval)
result = riscv_get_register(target, &r0, GDB_REGNO_A0);
if (result != ERROR_OK) {
LOG_DEBUG(" -> ERROR (couldn't read a0)");
- return SEMI_ERROR;
+ return SEMIHOSTING_ERROR;
}
result = riscv_get_register(target, &r1, GDB_REGNO_A1);
if (result != ERROR_OK) {
LOG_DEBUG(" -> ERROR (couldn't read a1)");
- return SEMI_ERROR;
+ return SEMIHOSTING_ERROR;
}
semihosting->op = r0;
@@ -146,12 +132,12 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval)
*retval = semihosting_common(target);
if (*retval != ERROR_OK) {
LOG_ERROR("Failed semihosting operation (0x%02X)", semihosting->op);
- return SEMI_ERROR;
+ return SEMIHOSTING_ERROR;
}
} else {
/* Unknown operation number, not a semihosting call. */
LOG_DEBUG(" -> NONE (unknown operation number)");
- return SEMI_NONE;
+ return SEMIHOSTING_NONE;
}
}
@@ -166,11 +152,11 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval)
*/
if (semihosting->is_resumable && !semihosting->hit_fileio) {
LOG_DEBUG(" -> HANDLED");
- return SEMI_HANDLED;
+ return SEMIHOSTING_HANDLED;
}
LOG_DEBUG(" -> WAITING");
- return SEMI_WAITING;
+ return SEMIHOSTING_WAITING;
}
/* -------------------------------------------------------------------------
diff --git a/src/target/rtt.c b/src/target/rtt.c
index 4183021..ef2c45d 100644
--- a/src/target/rtt.c
+++ b/src/target/rtt.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/rtt.h b/src/target/rtt.h
index 0122475..f3acda5 100644
--- a/src/target/rtt.h
+++ b/src/target/rtt.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENOCD_TARGET_RTT_H
diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c
index 2df6e38..dc0dae2 100644
--- a/src/target/semihosting_common.c
+++ b/src/target/semihosting_common.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2018 by Liviu Ionescu *
* <ilg@livius.net> *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2016 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
@@ -103,16 +92,6 @@ static int semihosting_common_fileio_info(struct target *target,
static int semihosting_common_fileio_end(struct target *target, int result,
int fileio_errno, bool ctrl_c);
-static int semihosting_read_fields(struct target *target, size_t number,
- uint8_t *fields);
-static int semihosting_write_fields(struct target *target, size_t number,
- uint8_t *fields);
-static uint64_t semihosting_get_field(struct target *target, size_t index,
- uint8_t *fields);
-static void semihosting_set_field(struct target *target, uint64_t value,
- size_t index,
- uint8_t *fields);
-
/* Attempts to include gdb_server.h failed. */
extern int gdb_actual_connections;
@@ -166,6 +145,7 @@ int semihosting_common_init(struct target *target, void *setup,
semihosting->setup = setup;
semihosting->post_result = post_result;
+ semihosting->user_command_extension = NULL;
target->semihosting = semihosting;
@@ -426,7 +406,7 @@ int semihosting_common(struct target *target)
} else {
semihosting->result = close(fd);
semihosting->sys_errno = errno;
- LOG_DEBUG("close(%d)=%d", fd, (int)semihosting->result);
+ LOG_DEBUG("close(%d)=%" PRId64, fd, semihosting->result);
}
}
break;
@@ -651,10 +631,10 @@ int semihosting_common(struct target *target)
semihosting->result = fstat(fd, &buf);
if (semihosting->result == -1) {
semihosting->sys_errno = errno;
- LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
+ LOG_DEBUG("fstat(%d)=%" PRId64, fd, semihosting->result);
break;
}
- LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
+ LOG_DEBUG("fstat(%d)=%" PRId64, fd, semihosting->result);
semihosting->result = buf.st_size;
}
break;
@@ -711,8 +691,7 @@ int semihosting_common(struct target *target)
if (retval != ERROR_OK)
return retval;
}
- LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg,
- (int)semihosting->result);
+ LOG_DEBUG("SYS_GET_CMDLINE=[%s], %" PRId64, arg, semihosting->result);
}
break;
@@ -804,7 +783,7 @@ int semihosting_common(struct target *target)
int fd = semihosting_get_field(target, 0, fields);
semihosting->result = isatty(fd);
semihosting->sys_errno = errno;
- LOG_DEBUG("isatty(%d)=%d", fd, (int)semihosting->result);
+ LOG_DEBUG("isatty(%d)=%" PRId64, fd, semihosting->result);
}
break;
@@ -877,9 +856,11 @@ int semihosting_common(struct target *target)
semihosting->result = -1;
semihosting->sys_errno = ENOMEM;
} else {
- strncpy((char *)fn, semihosting->basedir, basedir_len);
- if (fn[basedir_len - 1] != '/')
- fn[basedir_len++] = '/';
+ if (basedir_len > 0) {
+ strcpy((char *)fn, semihosting->basedir);
+ if (fn[basedir_len - 1] != '/')
+ fn[basedir_len++] = '/';
+ }
retval = target_read_memory(target, addr, 1, len, fn + basedir_len);
if (retval != ERROR_OK) {
free(fn);
@@ -920,22 +901,19 @@ int semihosting_common(struct target *target)
semihosting->result = fd;
semihosting->stdin_fd = fd;
semihosting->sys_errno = errno;
- LOG_DEBUG("dup(STDIN)=%d",
- (int)semihosting->result);
+ LOG_DEBUG("dup(STDIN)=%" PRId64, semihosting->result);
} else if (mode < 8) {
int fd = dup(STDOUT_FILENO);
semihosting->result = fd;
semihosting->stdout_fd = fd;
semihosting->sys_errno = errno;
- LOG_DEBUG("dup(STDOUT)=%d",
- (int)semihosting->result);
+ LOG_DEBUG("dup(STDOUT)=%" PRId64, semihosting->result);
} else {
int fd = dup(STDERR_FILENO);
semihosting->result = fd;
semihosting->stderr_fd = fd;
semihosting->sys_errno = errno;
- LOG_DEBUG("dup(STDERR)=%d",
- (int)semihosting->result);
+ LOG_DEBUG("dup(STDERR)=%" PRId64, semihosting->result);
}
} else {
/* cygwin requires the permission setting
@@ -945,8 +923,7 @@ int semihosting_common(struct target *target)
open_host_modeflags[mode],
0644);
semihosting->sys_errno = errno;
- LOG_DEBUG("open('%s')=%d", fn,
- (int)semihosting->result);
+ LOG_DEBUG("open('%s')=%" PRId64, fn, semihosting->result);
}
}
free(fn);
@@ -1009,11 +986,11 @@ int semihosting_common(struct target *target)
semihosting->sys_errno = ENOMEM;
} else {
semihosting->result = semihosting_read(semihosting, fd, buf, len);
- LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%d",
+ LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%" PRId64,
fd,
addr,
len,
- (int)semihosting->result);
+ semihosting->result);
if (semihosting->result >= 0) {
retval = target_write_buffer(target, addr,
semihosting->result,
@@ -1049,7 +1026,7 @@ int semihosting_common(struct target *target)
return ERROR_FAIL;
}
semihosting->result = semihosting_getchar(semihosting, semihosting->stdin_fd);
- LOG_DEBUG("getchar()=%d", (int)semihosting->result);
+ LOG_DEBUG("getchar()=%" PRId64, semihosting->result);
break;
case SEMIHOSTING_SYS_REMOVE: /* 0x0E */
@@ -1095,8 +1072,7 @@ int semihosting_common(struct target *target)
fn[len] = 0;
semihosting->result = remove((char *)fn);
semihosting->sys_errno = errno;
- LOG_DEBUG("remove('%s')=%d", fn,
- (int)semihosting->result);
+ LOG_DEBUG("remove('%s')=%" PRId64, fn, semihosting->result);
free(fn);
}
@@ -1165,9 +1141,7 @@ int semihosting_common(struct target *target)
semihosting->result = rename((char *)fn1,
(char *)fn2);
semihosting->sys_errno = errno;
- LOG_DEBUG("rename('%s', '%s')=%d", fn1, fn2,
- (int)semihosting->result);
-
+ LOG_DEBUG("rename('%s', '%s')=%" PRId64 " %d", fn1, fn2, semihosting->result, errno);
free(fn1);
free(fn2);
}
@@ -1212,8 +1186,7 @@ int semihosting_common(struct target *target)
} else {
semihosting->result = lseek(fd, pos, SEEK_SET);
semihosting->sys_errno = errno;
- LOG_DEBUG("lseek(%d, %d)=%d", fd, (int)pos,
- (int)semihosting->result);
+ LOG_DEBUG("lseek(%d, %d)=%" PRId64, fd, (int)pos, semihosting->result);
if (semihosting->result == pos)
semihosting->result = 0;
}
@@ -1272,9 +1245,7 @@ int semihosting_common(struct target *target)
cmd[len] = 0;
semihosting->result = system(
(const char *)cmd);
- LOG_DEBUG("system('%s')=%d",
- cmd,
- (int)semihosting->result);
+ LOG_DEBUG("system('%s')=%" PRId64, cmd, semihosting->result);
}
free(cmd);
@@ -1353,11 +1324,11 @@ int semihosting_common(struct target *target)
}
semihosting->result = semihosting_write(semihosting, fd, buf, len);
semihosting->sys_errno = errno;
- LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%d",
+ LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%" PRId64,
fd,
addr,
len,
- (int)semihosting->result);
+ semihosting->result);
if (semihosting->result >= 0) {
/* The number of bytes that are NOT written.
* */
@@ -1446,7 +1417,7 @@ int semihosting_common(struct target *target)
}
break;
- case SEMIHOSTING_USER_CMD_0x100 ... SEMIHOSTING_USER_CMD_0x107:
+ case SEMIHOSTING_USER_CMD_0X100 ... SEMIHOSTING_USER_CMD_0X107:
/**
* This is a user defined operation (while user cmds 0x100-0x1ff
* are possible, only 0x100-0x107 are currently implemented).
@@ -1465,9 +1436,14 @@ int semihosting_common(struct target *target)
* Return
* On exit, the RETURN REGISTER contains the return status.
*/
- {
- assert(!semihosting_user_op_params);
+ if (semihosting->user_command_extension) {
+ retval = semihosting->user_command_extension(target);
+ if (retval != ERROR_NOT_IMPLEMENTED)
+ break;
+ /* If custom user command not handled, we are looking for the TCL handler */
+ }
+ assert(!semihosting_user_op_params);
retval = semihosting_read_fields(target, 2, fields);
if (retval != ERROR_OK) {
LOG_ERROR("Failed to read fields for user defined command"
@@ -1505,11 +1481,8 @@ int semihosting_common(struct target *target)
target_handle_event(target, semihosting->op);
free(semihosting_user_op_params);
semihosting_user_op_params = NULL;
-
semihosting->result = 0;
break;
- }
-
case SEMIHOSTING_SYS_ELAPSED: /* 0x30 */
/*
@@ -1646,17 +1619,11 @@ static int semihosting_common_fileio_end(struct target *target, int result,
*/
switch (semihosting->op) {
case SEMIHOSTING_SYS_WRITE: /* 0x05 */
+ case SEMIHOSTING_SYS_READ: /* 0x06 */
if (result < 0)
- semihosting->result = fileio_info->param_3;
+ semihosting->result = fileio_info->param_3; /* Zero bytes read/written. */
else
- semihosting->result = 0;
- break;
-
- case SEMIHOSTING_SYS_READ: /* 0x06 */
- if (result == (int)fileio_info->param_3)
- semihosting->result = 0;
- if (result <= 0)
- semihosting->result = fileio_info->param_3;
+ semihosting->result = (int64_t)fileio_info->param_3 - result;
break;
case SEMIHOSTING_SYS_SEEK: /* 0x0a */
@@ -1668,10 +1635,13 @@ static int semihosting_common_fileio_end(struct target *target, int result,
return semihosting->post_result(target);
}
+/* -------------------------------------------------------------------------
+ * Utility functions. */
+
/**
* Read all fields of a command from target to buffer.
*/
-static int semihosting_read_fields(struct target *target, size_t number,
+int semihosting_read_fields(struct target *target, size_t number,
uint8_t *fields)
{
struct semihosting *semihosting = target->semihosting;
@@ -1683,7 +1653,7 @@ static int semihosting_read_fields(struct target *target, size_t number,
/**
* Write all fields of a command from buffer to target.
*/
-static int semihosting_write_fields(struct target *target, size_t number,
+int semihosting_write_fields(struct target *target, size_t number,
uint8_t *fields)
{
struct semihosting *semihosting = target->semihosting;
@@ -1695,7 +1665,7 @@ static int semihosting_write_fields(struct target *target, size_t number,
/**
* Extract a field from the buffer, considering register size and endianness.
*/
-static uint64_t semihosting_get_field(struct target *target, size_t index,
+uint64_t semihosting_get_field(struct target *target, size_t index,
uint8_t *fields)
{
struct semihosting *semihosting = target->semihosting;
@@ -1708,7 +1678,7 @@ static uint64_t semihosting_get_field(struct target *target, size_t index,
/**
* Store a field in the buffer, considering register size and endianness.
*/
-static void semihosting_set_field(struct target *target, uint64_t value,
+void semihosting_set_field(struct target *target, uint64_t value,
size_t index,
uint8_t *fields)
{
@@ -1832,7 +1802,7 @@ COMMAND_HANDLER(handle_common_semihosting_redirect_command)
{
struct target *target = get_current_target(CMD_CTX);
- if (target == NULL) {
+ if (!target) {
LOG_ERROR("No target selected");
return ERROR_FAIL;
}
diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h
index 404080f..7c5f748 100644
--- a/src/target/semihosting_common.h
+++ b/src/target/semihosting_common.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2018 by Liviu Ionescu *
* <ilg@livius.net> *
* *
* Copyright (C) 2009 by Marvell Technology Group Ltd. *
* Written by Nicolas Pitre <nico@marvell.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_SEMIHOSTING_COMMON_H
@@ -76,9 +65,9 @@ enum semihosting_operation_numbers {
SEMIHOSTING_SYS_WRITE = 0x05,
SEMIHOSTING_SYS_WRITEC = 0x03,
SEMIHOSTING_SYS_WRITE0 = 0x04,
- SEMIHOSTING_USER_CMD_0x100 = 0x100, /* First user cmd op code */
- SEMIHOSTING_USER_CMD_0x107 = 0x107, /* Last supported user cmd op code */
- SEMIHOSTING_USER_CMD_0x1FF = 0x1FF, /* Last user cmd op code */
+ SEMIHOSTING_USER_CMD_0X100 = 0x100, /* First user cmd op code */
+ SEMIHOSTING_USER_CMD_0X107 = 0x107, /* Last supported user cmd op code */
+ SEMIHOSTING_USER_CMD_0X1FF = 0x1FF, /* Last user cmd op code */
};
/** Maximum allowed Tcl command segment length in bytes*/
@@ -103,6 +92,13 @@ enum semihosting_redirect_config {
SEMIHOSTING_REDIRECT_CFG_ALL,
};
+enum semihosting_result {
+ SEMIHOSTING_NONE, /* Not halted for a semihosting call. */
+ SEMIHOSTING_HANDLED, /* Call handled, and target was resumed. */
+ SEMIHOSTING_WAITING, /* Call handled, target is halted waiting until we can resume. */
+ SEMIHOSTING_ERROR /* Something went wrong. */
+};
+
struct target;
/*
@@ -179,6 +175,13 @@ struct semihosting {
/** Base directory for semihosting I/O operations. */
char *basedir;
+ /**
+ * Target's extension of semihosting user commands.
+ * @returns ERROR_NOT_IMPLEMENTED when user command is not handled, otherwise
+ * sets semihosting->result and semihosting->sys_errno and returns ERROR_OK.
+ */
+ int (*user_command_extension)(struct target *target);
+
int (*setup)(struct target *target, int enable);
int (*post_result)(struct target *target);
};
@@ -187,4 +190,17 @@ int semihosting_common_init(struct target *target, void *setup,
void *post_result);
int semihosting_common(struct target *target);
+/* utility functions which may also be used by semihosting extensions (custom vendor-defined syscalls) */
+int semihosting_read_fields(struct target *target, size_t number,
+ uint8_t *fields);
+int semihosting_write_fields(struct target *target, size_t number,
+ uint8_t *fields);
+uint64_t semihosting_get_field(struct target *target, size_t index,
+ uint8_t *fields);
+void semihosting_set_field(struct target *target, uint64_t value,
+ size_t index,
+ uint8_t *fields);
+
+extern const struct command_registration semihosting_common_handlers[];
+
#endif /* OPENOCD_TARGET_SEMIHOSTING_COMMON_H */
diff --git a/src/target/smp.c b/src/target/smp.c
index 569abd7..effc63f 100644
--- a/src/target/smp.c
+++ b/src/target/smp.c
@@ -1,19 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* *
* Copyright (C) ST-Ericsson SA 2011 *
* Author: Michel Jaouen <michel.jaouen@stericsson.com> for ST-Ericsson. *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/smp.h b/src/target/smp.h
index d373c90..20835a0 100644
--- a/src/target/smp.h
+++ b/src/target/smp.h
@@ -1,19 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* *
* Copyright (C) ST-Ericsson SA 2011 *
* Author: Michel Jaouen <michel.jaouen@stericsson.com> for ST-Ericsson. *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_SMP_H
diff --git a/src/target/startup.tcl b/src/target/startup.tcl
index 0e46992..290e79d 100644
--- a/src/target/startup.tcl
+++ b/src/target/startup.tcl
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
# Defines basic Tcl procs for OpenOCD target module
proc new_target_name { } {
diff --git a/src/target/stm8.c b/src/target/stm8.c
index 4102082..aa934c9 100644
--- a/src/target/stm8.c
+++ b/src/target/stm8.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* OpenOCD STM8 target driver
* Copyright (C) 2017 Ake Rehnman
* ake.rehnman(at)gmail.com
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/stm8.h b/src/target/stm8.h
index b18ff58..55e1071 100644
--- a/src/target/stm8.h
+++ b/src/target/stm8.h
@@ -1,20 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* OpenOCD STM8 target driver
* Copyright (C) 2017 Ake Rehnman
* ake.rehnman(at)gmail.com
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENOCD_TARGET_STM8_H
@@ -22,11 +11,12 @@
struct target;
-#define STM8_COMMON_MAGIC 0x53544D38
+#define STM8_COMMON_MAGIC 0x53544D38U
#define STM8_NUM_CORE_REGS 6
struct stm8_common {
- uint32_t common_magic;
+ unsigned int common_magic;
+
void *arch_info;
struct reg_cache *core_cache;
uint32_t core_regs[STM8_NUM_CORE_REGS];
diff --git a/src/target/target.c b/src/target/target.c
index a373848..f09c9a5 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -22,19 +24,6 @@
* *
* Copyright (C) 2011 Andreas Fritiofson *
* andreas.fritiofson@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -88,6 +77,7 @@ extern struct target_type fa526_target;
extern struct target_type feroceon_target;
extern struct target_type dragonite_target;
extern struct target_type xscale_target;
+extern struct target_type xtensa_chip_target;
extern struct target_type cortexm_target;
extern struct target_type cortexa_target;
extern struct target_type aarch64_target;
@@ -105,7 +95,9 @@ 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;
extern struct target_type or1k_target;
extern struct target_type quark_x10xx_target;
extern struct target_type quark_d20xx_target;
@@ -127,6 +119,7 @@ static struct target_type *target_types[] = {
&feroceon_target,
&dragonite_target,
&xscale_target,
+ &xtensa_chip_target,
&cortexm_target,
&cortexa_target,
&cortexr4_target,
@@ -142,7 +135,9 @@ static struct target_type *target_types[] = {
&nds32_v2_target,
&nds32_v3_target,
&nds32_v3m_target,
+ &esp32_target,
&esp32s2_target,
+ &esp32s3_target,
&or1k_target,
&quark_x10xx_target,
&quark_d20xx_target,
@@ -241,14 +236,14 @@ static const struct jim_nvp nvp_target_event[] = {
{ .value = TARGET_EVENT_TRACE_CONFIG, .name = "trace-config" },
- { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x100, .name = "semihosting-user-cmd-0x100" },
- { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x101, .name = "semihosting-user-cmd-0x101" },
- { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x102, .name = "semihosting-user-cmd-0x102" },
- { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x103, .name = "semihosting-user-cmd-0x103" },
- { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x104, .name = "semihosting-user-cmd-0x104" },
- { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x105, .name = "semihosting-user-cmd-0x105" },
- { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x106, .name = "semihosting-user-cmd-0x106" },
- { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0x107, .name = "semihosting-user-cmd-0x107" },
+ { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X100, .name = "semihosting-user-cmd-0x100" },
+ { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X101, .name = "semihosting-user-cmd-0x101" },
+ { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X102, .name = "semihosting-user-cmd-0x102" },
+ { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X103, .name = "semihosting-user-cmd-0x103" },
+ { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X104, .name = "semihosting-user-cmd-0x104" },
+ { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X105, .name = "semihosting-user-cmd-0x105" },
+ { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X106, .name = "semihosting-user-cmd-0x106" },
+ { .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X107, .name = "semihosting-user-cmd-0x107" },
{ .name = NULL, .value = -1 }
};
@@ -662,10 +657,10 @@ int target_resume(struct target *target, int current, target_addr_t address,
* Disable polling during resume() to guarantee the execution of handlers
* in the correct order.
*/
- bool save_poll = jtag_poll_get_enabled();
- jtag_poll_set_enabled(false);
+ bool save_poll_mask = jtag_poll_mask();
retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution);
- jtag_poll_set_enabled(save_poll);
+ jtag_poll_unmask(save_poll_mask);
+
if (retval != ERROR_OK)
return retval;
@@ -693,14 +688,12 @@ static int target_process_reset(struct command_invocation *cmd, enum target_rese
* more predictable, i.e. dr/irscan & pathmove in events will
* not have JTAG operations injected into the middle of a sequence.
*/
- bool save_poll = jtag_poll_get_enabled();
-
- jtag_poll_set_enabled(false);
+ bool save_poll_mask = jtag_poll_mask();
sprintf(buf, "ocd_process_reset %s", n->name);
retval = Jim_Eval(cmd->ctx->interp, buf);
- jtag_poll_set_enabled(save_poll);
+ jtag_poll_unmask(save_poll_mask);
if (retval != JIM_OK) {
Jim_MakeErrorMessage(cmd->ctx->interp);
@@ -2088,7 +2081,7 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w
struct working_area *new_wa = malloc(sizeof(*new_wa));
if (new_wa) {
new_wa->next = NULL;
- new_wa->size = target->working_area_size & ~3UL; /* 4-byte align */
+ new_wa->size = ALIGN_DOWN(target->working_area_size, 4); /* 4-byte align */
new_wa->address = target->working_area;
new_wa->backup = NULL;
new_wa->user = NULL;
@@ -2099,8 +2092,7 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w
}
/* only allocate multiples of 4 byte */
- if (size % 4)
- size = (size + 3) & (~3UL);
+ size = ALIGN_UP(size, 4);
struct working_area *c = target->working_areas;
@@ -2254,7 +2246,7 @@ uint32_t target_get_working_area_avail(struct target *target)
uint32_t max_size = 0;
if (!c)
- return target->working_area_size;
+ return ALIGN_DOWN(target->working_area_size, 4);
while (c) {
if (c->free && max_size < c->size)
@@ -3337,7 +3329,7 @@ COMMAND_HANDLER(handle_soft_reset_halt_command)
{
struct target *target = get_current_target(CMD_CTX);
- LOG_USER("requesting target halt and executing a soft reset");
+ LOG_TARGET_INFO(target, "requesting target halt and executing a soft reset");
target_soft_reset_halt(target);
@@ -4727,7 +4719,7 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc,
break;
}
- char value_buf[11];
+ char value_buf[19];
snprintf(value_buf, sizeof(value_buf), "0x%" PRIx64, v);
Jim_ListAppendElement(interp, result_list,
diff --git a/src/target/target.h b/src/target/target.h
index e67016c..197890b 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -13,19 +15,6 @@
* *
* Copyright (C) ST-Ericsson SA 2011 *
* michel.jaouen@stericsson.com : smp minimum support *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_TARGET_H
@@ -303,14 +292,14 @@ enum target_event {
TARGET_EVENT_TRACE_CONFIG,
- TARGET_EVENT_SEMIHOSTING_USER_CMD_0x100 = 0x100, /* semihosting allows user cmds from 0x100 to 0x1ff */
- TARGET_EVENT_SEMIHOSTING_USER_CMD_0x101 = 0x101,
- TARGET_EVENT_SEMIHOSTING_USER_CMD_0x102 = 0x102,
- TARGET_EVENT_SEMIHOSTING_USER_CMD_0x103 = 0x103,
- TARGET_EVENT_SEMIHOSTING_USER_CMD_0x104 = 0x104,
- TARGET_EVENT_SEMIHOSTING_USER_CMD_0x105 = 0x105,
- TARGET_EVENT_SEMIHOSTING_USER_CMD_0x106 = 0x106,
- TARGET_EVENT_SEMIHOSTING_USER_CMD_0x107 = 0x107,
+ TARGET_EVENT_SEMIHOSTING_USER_CMD_0X100 = 0x100, /* semihosting allows user cmds from 0x100 to 0x1ff */
+ TARGET_EVENT_SEMIHOSTING_USER_CMD_0X101 = 0x101,
+ TARGET_EVENT_SEMIHOSTING_USER_CMD_0X102 = 0x102,
+ TARGET_EVENT_SEMIHOSTING_USER_CMD_0X103 = 0x103,
+ TARGET_EVENT_SEMIHOSTING_USER_CMD_0X104 = 0x104,
+ TARGET_EVENT_SEMIHOSTING_USER_CMD_0X105 = 0x105,
+ TARGET_EVENT_SEMIHOSTING_USER_CMD_0X106 = 0x106,
+ TARGET_EVENT_SEMIHOSTING_USER_CMD_0X107 = 0x107,
};
struct target_event_action {
diff --git a/src/target/target_request.c b/src/target/target_request.c
index 562b046..72c8421 100644
--- a/src/target/target_request.c
+++ b/src/target/target_request.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/target_request.h b/src/target/target_request.h
index 1b13173..62d5c74 100644
--- a/src/target/target_request.h
+++ b/src/target/target_request.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_TARGET_REQUEST_H
diff --git a/src/target/target_type.h b/src/target/target_type.h
index a26c2e7..9470803 100644
--- a/src/target/target_type.h
+++ b/src/target/target_type.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_TARGET_TYPE_H
@@ -297,6 +286,15 @@ struct target_type {
*/
int (*gdb_fileio_end)(struct target *target, int retcode, int fileio_errno, bool ctrl_c);
+ /* Parse target-specific GDB query commands.
+ * The string pointer "response_p" is always assigned by the called function
+ * to a pointer to a NULL-terminated string, even when the function returns
+ * an error. The string memory is not freed by the caller, so this function
+ * must pay attention for possible memory leaks if the string memory is
+ * dynamically allocated.
+ */
+ int (*gdb_query_custom)(struct target *target, const char *packet, char **response_p);
+
/* do target profiling
*/
int (*profiling)(struct target *target, uint32_t *samples,
diff --git a/src/target/testee.c b/src/target/testee.c
index 236ac9a..6875652 100644
--- a/src/target/testee.c
+++ b/src/target/testee.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/trace.c b/src/target/trace.c
index f2ceb03..333a787 100644
--- a/src/target/trace.c
+++ b/src/target/trace.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/trace.h b/src/target/trace.h
index 45308c0..e3d787e 100644
--- a/src/target/trace.h
+++ b/src/target/trace.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_TRACE_H
diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c
index d119be1..ecaf52b 100644
--- a/src/target/x86_32_common.c
+++ b/src/target/x86_32_common.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright(c) 2013 Intel Corporation.
*
@@ -7,19 +9,6 @@
* Julien Carreno (julien.carreno@intel.com)
* Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
* Contact Information:
* Intel Corporation
*/
diff --git a/src/target/x86_32_common.h b/src/target/x86_32_common.h
index 14e6e35..7392447 100644
--- a/src/target/x86_32_common.h
+++ b/src/target/x86_32_common.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright(c) 2013-2016 Intel Corporation.
*
@@ -7,19 +9,6 @@
* Julien Carreno (julien.carreno@intel.com)
* Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
* Contact Information:
* Intel Corporation
*/
@@ -159,7 +148,7 @@ enum {
PMCR,
};
-#define X86_32_COMMON_MAGIC 0x86328632
+#define X86_32_COMMON_MAGIC 0x86328632U
enum {
/* memory read/write */
@@ -211,7 +200,8 @@ struct swbp_mem_patch {
#define NUM_PM_REGS 18 /* regs used in save/restore */
struct x86_32_common {
- uint32_t common_magic;
+ unsigned int common_magic;
+
void *arch_info;
enum x86_core_type core_type;
struct reg_cache *cache;
diff --git a/src/target/xscale.c b/src/target/xscale.c
index 78bd099..066ff8c 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -7,19 +9,6 @@
* *
* Copyright (C) 2009 Michael Schwingen *
* michael@schwingen.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/xscale.h b/src/target/xscale.h
index a86edb2..36a69bc 100644
--- a/src/target/xscale.h
+++ b/src/target/xscale.h
@@ -1,22 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_XSCALE_H
@@ -26,7 +15,7 @@
#include "armv4_5_mmu.h"
#include "trace.h"
-#define XSCALE_COMMON_MAGIC 0x58534341
+#define XSCALE_COMMON_MAGIC 0x58534341U
/* These four JTAG instructions are architecturally defined.
* Lengths are core-specific; originally 5 bits, later 7.
@@ -82,11 +71,11 @@ struct xscale_trace {
};
struct xscale_common {
+ unsigned int common_magic;
+
/* armv4/5 common stuff */
struct arm arm;
- int common_magic;
-
/* XScale registers (CP15, DBG) */
struct reg_cache *reg_cache;
diff --git a/src/target/xtensa/Makefile.am b/src/target/xtensa/Makefile.am
index f6cee99..94c7c4a 100644
--- a/src/target/xtensa/Makefile.am
+++ b/src/target/xtensa/Makefile.am
@@ -1,7 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libxtensa.la
%C%_libxtensa_la_SOURCES = \
%D%/xtensa.c \
%D%/xtensa.h \
+ %D%/xtensa_chip.c \
+ %D%/xtensa_chip.h \
%D%/xtensa_debug_module.c \
%D%/xtensa_debug_module.h \
%D%/xtensa_regs.h
diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c
index a955960..4dfff6a 100644
--- a/src/target/xtensa/xtensa.c
+++ b/src/target/xtensa/xtensa.c
@@ -1,24 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Generic Xtensa target API for OpenOCD *
+ * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
* Copyright (C) 2016-2019 Espressif Systems Ltd. *
* Derived from esp108.c *
* Author: Angus Gratton gus@projectgus.com *
- * Author: Jeroen Domburg <jeroen@espressif.com> *
- * Author: Alexey Gerenkov <alexey@espressif.com> *
- * Author: Andrey Gramakov <andrei.gramakov@espressif.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -30,325 +17,270 @@
#include <helper/align.h>
#include <target/register.h>
+#include "xtensa_chip.h"
#include "xtensa.h"
-
-#define _XT_INS_FORMAT_RSR(OPCODE, SR, T) ((OPCODE) \
- | (((SR) & 0xFF) << 8) \
+/* Swap 4-bit Xtensa opcodes and fields */
+#define XT_NIBSWAP8(V) \
+ ((((V) & 0x0F) << 4) \
+ | (((V) & 0xF0) >> 4))
+
+#define XT_NIBSWAP16(V) \
+ ((((V) & 0x000F) << 12) \
+ | (((V) & 0x00F0) << 4) \
+ | (((V) & 0x0F00) >> 4) \
+ | (((V) & 0xF000) >> 12))
+
+#define XT_NIBSWAP24(V) \
+ ((((V) & 0x00000F) << 20) \
+ | (((V) & 0x0000F0) << 12) \
+ | (((V) & 0x000F00) << 4) \
+ | (((V) & 0x00F000) >> 4) \
+ | (((V) & 0x0F0000) >> 12) \
+ | (((V) & 0xF00000) >> 20))
+
+/* _XT_INS_FORMAT_*()
+ * Instruction formatting converted from little-endian inputs
+ * and shifted to the MSB-side of DIR for BE systems.
+ */
+#define _XT_INS_FORMAT_RSR(X, OPCODE, SR, T) \
+ (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
+ | (((T) & 0x0F) << 16) \
+ | (((SR) & 0xFF) << 8)) << 8 \
+ : (OPCODE) \
+ | (((SR) & 0xFF) << 8) \
| (((T) & 0x0F) << 4))
-#define _XT_INS_FORMAT_RRR(OPCODE, ST, R) ((OPCODE) \
- | (((ST) & 0xFF) << 4) \
+#define _XT_INS_FORMAT_RRR(X, OPCODE, ST, R) \
+ (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
+ | ((XT_NIBSWAP8((ST) & 0xFF)) << 12) \
+ | (((R) & 0x0F) << 8)) << 8 \
+ : (OPCODE) \
+ | (((ST) & 0xFF) << 4) \
| (((R) & 0x0F) << 12))
-#define _XT_INS_FORMAT_RRRN(OPCODE, S, T, IMM4) ((OPCODE) \
- | (((T) & 0x0F) << 4) \
- | (((S) & 0x0F) << 8) \
+#define _XT_INS_FORMAT_RRRN(X, OPCODE, S, T, IMM4) \
+ (XT_ISBE(X) ? (XT_NIBSWAP16(OPCODE) \
+ | (((T) & 0x0F) << 8) \
+ | (((S) & 0x0F) << 4) \
+ | ((IMM4) & 0x0F)) << 16 \
+ : (OPCODE) \
+ | (((T) & 0x0F) << 4) \
+ | (((S) & 0x0F) << 8) \
| (((IMM4) & 0x0F) << 12))
-#define _XT_INS_FORMAT_RRI8(OPCODE, R, S, T, IMM8) ((OPCODE) \
- | (((IMM8) & 0xFF) << 16) \
- | (((R) & 0x0F) << 12) \
- | (((S) & 0x0F) << 8) \
+#define _XT_INS_FORMAT_RRI8(X, OPCODE, R, S, T, IMM8) \
+ (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
+ | (((T) & 0x0F) << 16) \
+ | (((S) & 0x0F) << 12) \
+ | (((R) & 0x0F) << 8) \
+ | ((IMM8) & 0xFF)) << 8 \
+ : (OPCODE) \
+ | (((IMM8) & 0xFF) << 16) \
+ | (((R) & 0x0F) << 12) \
+ | (((S) & 0x0F) << 8) \
| (((T) & 0x0F) << 4))
-#define _XT_INS_FORMAT_RRI4(OPCODE, IMM4, R, S, T) ((OPCODE) \
- | (((IMM4) & 0x0F) << 20) \
- | (((R) & 0x0F) << 12) \
- | (((S) & 0x0F) << 8) \
+#define _XT_INS_FORMAT_RRI4(X, OPCODE, IMM4, R, S, T) \
+ (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
+ | (((T) & 0x0F) << 16) \
+ | (((S) & 0x0F) << 12) \
+ | (((R) & 0x0F) << 8)) << 8 \
+ | ((IMM4) & 0x0F) \
+ : (OPCODE) \
+ | (((IMM4) & 0x0F) << 20) \
+ | (((R) & 0x0F) << 12) \
+ | (((S) & 0x0F) << 8) \
| (((T) & 0x0F) << 4))
/* Xtensa processor instruction opcodes
- * "Return From Debug Operation" to Normal */
-#define XT_INS_RFDO 0xf1e000
+*/
+/* "Return From Debug Operation" to Normal */
+#define XT_INS_RFDO(X) (XT_ISBE(X) ? 0x000e1f << 8 : 0xf1e000)
/* "Return From Debug and Dispatch" - allow sw debugging stuff to take over */
-#define XT_INS_RFDD 0xf1e010
+#define XT_INS_RFDD(X) (XT_ISBE(X) ? 0x010e1f << 8 : 0xf1e010)
/* Load to DDR register, increase addr register */
-#define XT_INS_LDDR32P(S) (0x0070E0 | ((S) << 8))
+#define XT_INS_LDDR32P(X, S) (XT_ISBE(X) ? (0x0E0700 | ((S) << 12)) << 8 : (0x0070E0 | ((S) << 8)))
/* Store from DDR register, increase addr register */
-#define XT_INS_SDDR32P(S) (0x0070F0 | ((S) << 8))
-
-/* Load 32-bit Indirect from A(S) + 4 * IMM8 to A(T) */
-#define XT_INS_L32I(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x002002, 0, S, T, IMM8)
-/* Load 16-bit Unsigned from A(S) + 2 * IMM8 to A(T) */
-#define XT_INS_L16UI(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x001002, 0, S, T, IMM8)
-/* Load 8-bit Unsigned from A(S) + IMM8 to A(T) */
-#define XT_INS_L8UI(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x000002, 0, S, T, IMM8)
-
-/* Store 32-bit Indirect to A(S) + 4 * IMM8 from A(T) */
-#define XT_INS_S32I(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x006002, 0, S, T, IMM8)
-/* Store 16-bit to A(S) + 2 * IMM8 from A(T) */
-#define XT_INS_S16I(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x005002, 0, S, T, IMM8)
-/* Store 8-bit to A(S) + IMM8 from A(T) */
-#define XT_INS_S8I(S, T, IMM8) _XT_INS_FORMAT_RRI8(0x004002, 0, S, T, IMM8)
+#define XT_INS_SDDR32P(X, S) (XT_ISBE(X) ? (0x0F0700 | ((S) << 12)) << 8 : (0x0070F0 | ((S) << 8)))
+
+/* Load 32-bit Indirect from A(S)+4*IMM8 to A(T) */
+#define XT_INS_L32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x002002, 0, S, T, IMM8)
+/* Load 16-bit Unsigned from A(S)+2*IMM8 to A(T) */
+#define XT_INS_L16UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x001002, 0, S, T, IMM8)
+/* Load 8-bit Unsigned from A(S)+IMM8 to A(T) */
+#define XT_INS_L8UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x000002, 0, S, T, IMM8)
+
+/* Store 32-bit Indirect to A(S)+4*IMM8 from A(T) */
+#define XT_INS_S32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x006002, 0, S, T, IMM8)
+/* Store 16-bit to A(S)+2*IMM8 from A(T) */
+#define XT_INS_S16I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x005002, 0, S, T, IMM8)
+/* Store 8-bit to A(S)+IMM8 from A(T) */
+#define XT_INS_S8I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x004002, 0, S, T, IMM8)
+
+/* Cache Instructions */
+#define XT_INS_IHI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x0070E2, 0, S, 0, IMM8)
+#define XT_INS_DHWBI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007052, 0, S, 0, IMM8)
+#define XT_INS_DHWB(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007042, 0, S, 0, IMM8)
+#define XT_INS_ISYNC(X) (XT_ISBE(X) ? 0x000200 << 8 : 0x002000)
+
+/* Control Instructions */
+#define XT_INS_JX(X, S) (XT_ISBE(X) ? (0x050000 | ((S) << 12)) : (0x0000a0 | ((S) << 8)))
+#define XT_INS_CALL0(X, IMM18) (XT_ISBE(X) ? (0x500000 | ((IMM18) & 0x3ffff)) : (0x000005 | (((IMM18) & 0x3ffff) << 6)))
/* Read Special Register */
-#define XT_INS_RSR(SR, T) _XT_INS_FORMAT_RSR(0x030000, SR, T)
+#define XT_INS_RSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x030000, SR, T)
/* Write Special Register */
-#define XT_INS_WSR(SR, T) _XT_INS_FORMAT_RSR(0x130000, SR, T)
+#define XT_INS_WSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x130000, SR, T)
/* Swap Special Register */
-#define XT_INS_XSR(SR, T) _XT_INS_FORMAT_RSR(0x610000, SR, T)
+#define XT_INS_XSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x610000, SR, T)
/* Rotate Window by (-8..7) */
-#define XT_INS_ROTW(N) ((0x408000) | (((N) & 15) << 4))
+#define XT_INS_ROTW(X, N) (XT_ISBE(X) ? ((0x000804) | (((N) & 15) << 16)) << 8 : ((0x408000) | (((N) & 15) << 4)))
/* Read User Register */
-#define XT_INS_RUR(UR, T) _XT_INS_FORMAT_RRR(0xE30000, UR, T)
+#define XT_INS_RUR(X, UR, T) _XT_INS_FORMAT_RRR(X, 0xE30000, UR, T)
/* Write User Register */
-#define XT_INS_WUR(UR, T) _XT_INS_FORMAT_RSR(0xF30000, UR, T)
+#define XT_INS_WUR(X, UR, T) _XT_INS_FORMAT_RSR(X, 0xF30000, UR, T)
/* Read Floating-Point Register */
-#define XT_INS_RFR(FR, T) _XT_INS_FORMAT_RRR(0xFA0000, (((FR) << 4) | 0x4), T)
+#define XT_INS_RFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((FR << 4) | 0x4), T)
/* Write Floating-Point Register */
-#define XT_INS_WFR(FR, T) _XT_INS_FORMAT_RRR(0xFA0000, (((FR) << 4) | 0x5), T)
-
-/* 32-bit break */
-#define XT_INS_BREAK(IMM1, IMM2) _XT_INS_FORMAT_RRR(0x000000, \
- (((IMM1) & 0x0F) << 4) | ((IMM2) & 0x0F), 0x4)
-/* 16-bit break */
-#define XT_INS_BREAKN(IMM4) _XT_INS_FORMAT_RRRN(0x00000D, IMM4, 0x2, 0xF)
+#define XT_INS_WFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((T << 4) | 0x5), FR)
-#define XT_INS_L32E(R, S, T) _XT_INS_FORMAT_RRI4(0x90000, 0, R, S, T)
-#define XT_INS_S32E(R, S, T) _XT_INS_FORMAT_RRI4(0x490000, 0, R, S, T)
-#define XT_INS_L32E_S32E_MASK 0xFF000F
+#define XT_INS_L32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x090000, 0, R, S, T)
+#define XT_INS_S32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x490000, 0, R, S, T)
+#define XT_INS_L32E_S32E_MASK(X) (XT_ISBE(X) ? 0xF000FF << 8 : 0xFF000F)
-#define XT_INS_RFWO 0x3400
-#define XT_INS_RFWU 0x3500
-#define XT_INS_RFWO_RFWU_MASK 0xFFFFFF
+#define XT_INS_RFWO(X) (XT_ISBE(X) ? 0x004300 << 8 : 0x003400)
+#define XT_INS_RFWU(X) (XT_ISBE(X) ? 0x005300 << 8 : 0x003500)
+#define XT_INS_RFWO_RFWU_MASK(X) (XT_ISBE(X) ? 0xFFFFFF << 8 : 0xFFFFFF)
#define XT_WATCHPOINTS_NUM_MAX 2
-/* Special register number macro for DDR register.
-* this gets used a lot so making a shortcut to it is
-* useful.
-*/
-#define XT_SR_DDR (xtensa_regs[XT_REG_IDX_OCD_DDR].reg_num)
-
-/*Same thing for A3/A4 */
+/* Special register number macro for DDR, PS, WB, A3, A4 registers.
+ * These get used a lot so making a shortcut is useful.
+ */
+#define XT_SR_DDR (xtensa_regs[XT_REG_IDX_DDR].reg_num)
+#define XT_SR_PS (xtensa_regs[XT_REG_IDX_PS].reg_num)
+#define XT_SR_WB (xtensa_regs[XT_REG_IDX_WINDOWBASE].reg_num)
#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_PC_REG_NUM_BASE (176)
-#define XT_SW_BREAKPOINTS_MAX_NUM 32
-
-const struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS] = {
- { "pc", XT_PC_REG_NUM_BASE /*+XT_DEBUGLEVEL*/, XT_REG_SPECIAL, 0 }, /* actually epc[debuglevel] */
- { "ar0", 0x00, XT_REG_GENERAL, 0 },
- { "ar1", 0x01, XT_REG_GENERAL, 0 },
- { "ar2", 0x02, XT_REG_GENERAL, 0 },
- { "ar3", 0x03, XT_REG_GENERAL, 0 },
- { "ar4", 0x04, XT_REG_GENERAL, 0 },
- { "ar5", 0x05, XT_REG_GENERAL, 0 },
- { "ar6", 0x06, XT_REG_GENERAL, 0 },
- { "ar7", 0x07, XT_REG_GENERAL, 0 },
- { "ar8", 0x08, XT_REG_GENERAL, 0 },
- { "ar9", 0x09, XT_REG_GENERAL, 0 },
- { "ar10", 0x0A, XT_REG_GENERAL, 0 },
- { "ar11", 0x0B, XT_REG_GENERAL, 0 },
- { "ar12", 0x0C, XT_REG_GENERAL, 0 },
- { "ar13", 0x0D, XT_REG_GENERAL, 0 },
- { "ar14", 0x0E, XT_REG_GENERAL, 0 },
- { "ar15", 0x0F, XT_REG_GENERAL, 0 },
- { "ar16", 0x10, XT_REG_GENERAL, 0 },
- { "ar17", 0x11, XT_REG_GENERAL, 0 },
- { "ar18", 0x12, XT_REG_GENERAL, 0 },
- { "ar19", 0x13, XT_REG_GENERAL, 0 },
- { "ar20", 0x14, XT_REG_GENERAL, 0 },
- { "ar21", 0x15, XT_REG_GENERAL, 0 },
- { "ar22", 0x16, XT_REG_GENERAL, 0 },
- { "ar23", 0x17, XT_REG_GENERAL, 0 },
- { "ar24", 0x18, XT_REG_GENERAL, 0 },
- { "ar25", 0x19, XT_REG_GENERAL, 0 },
- { "ar26", 0x1A, XT_REG_GENERAL, 0 },
- { "ar27", 0x1B, XT_REG_GENERAL, 0 },
- { "ar28", 0x1C, XT_REG_GENERAL, 0 },
- { "ar29", 0x1D, XT_REG_GENERAL, 0 },
- { "ar30", 0x1E, XT_REG_GENERAL, 0 },
- { "ar31", 0x1F, XT_REG_GENERAL, 0 },
- { "ar32", 0x20, XT_REG_GENERAL, 0 },
- { "ar33", 0x21, XT_REG_GENERAL, 0 },
- { "ar34", 0x22, XT_REG_GENERAL, 0 },
- { "ar35", 0x23, XT_REG_GENERAL, 0 },
- { "ar36", 0x24, XT_REG_GENERAL, 0 },
- { "ar37", 0x25, XT_REG_GENERAL, 0 },
- { "ar38", 0x26, XT_REG_GENERAL, 0 },
- { "ar39", 0x27, XT_REG_GENERAL, 0 },
- { "ar40", 0x28, XT_REG_GENERAL, 0 },
- { "ar41", 0x29, XT_REG_GENERAL, 0 },
- { "ar42", 0x2A, XT_REG_GENERAL, 0 },
- { "ar43", 0x2B, XT_REG_GENERAL, 0 },
- { "ar44", 0x2C, XT_REG_GENERAL, 0 },
- { "ar45", 0x2D, XT_REG_GENERAL, 0 },
- { "ar46", 0x2E, XT_REG_GENERAL, 0 },
- { "ar47", 0x2F, XT_REG_GENERAL, 0 },
- { "ar48", 0x30, XT_REG_GENERAL, 0 },
- { "ar49", 0x31, XT_REG_GENERAL, 0 },
- { "ar50", 0x32, XT_REG_GENERAL, 0 },
- { "ar51", 0x33, XT_REG_GENERAL, 0 },
- { "ar52", 0x34, XT_REG_GENERAL, 0 },
- { "ar53", 0x35, XT_REG_GENERAL, 0 },
- { "ar54", 0x36, XT_REG_GENERAL, 0 },
- { "ar55", 0x37, XT_REG_GENERAL, 0 },
- { "ar56", 0x38, XT_REG_GENERAL, 0 },
- { "ar57", 0x39, XT_REG_GENERAL, 0 },
- { "ar58", 0x3A, XT_REG_GENERAL, 0 },
- { "ar59", 0x3B, XT_REG_GENERAL, 0 },
- { "ar60", 0x3C, XT_REG_GENERAL, 0 },
- { "ar61", 0x3D, XT_REG_GENERAL, 0 },
- { "ar62", 0x3E, XT_REG_GENERAL, 0 },
- { "ar63", 0x3F, XT_REG_GENERAL, 0 },
- { "lbeg", 0x00, XT_REG_SPECIAL, 0 },
- { "lend", 0x01, XT_REG_SPECIAL, 0 },
- { "lcount", 0x02, XT_REG_SPECIAL, 0 },
- { "sar", 0x03, XT_REG_SPECIAL, 0 },
- { "windowbase", 0x48, XT_REG_SPECIAL, 0 },
- { "windowstart", 0x49, XT_REG_SPECIAL, 0 },
- { "configid0", 0xB0, XT_REG_SPECIAL, 0 },
- { "configid1", 0xD0, XT_REG_SPECIAL, 0 },
- { "ps", 0xC6, XT_REG_SPECIAL, 0 }, /* actually EPS[debuglevel] */
- { "threadptr", 0xE7, XT_REG_USER, 0 },
- { "br", 0x04, XT_REG_SPECIAL, 0 },
- { "scompare1", 0x0C, XT_REG_SPECIAL, 0 },
- { "acclo", 0x10, XT_REG_SPECIAL, 0 },
- { "acchi", 0x11, XT_REG_SPECIAL, 0 },
- { "m0", 0x20, XT_REG_SPECIAL, 0 },
- { "m1", 0x21, XT_REG_SPECIAL, 0 },
- { "m2", 0x22, XT_REG_SPECIAL, 0 },
- { "m3", 0x23, XT_REG_SPECIAL, 0 },
- { "f0", 0x00, XT_REG_FR, XT_REGF_COPROC0 },
- { "f1", 0x01, XT_REG_FR, XT_REGF_COPROC0 },
- { "f2", 0x02, XT_REG_FR, XT_REGF_COPROC0 },
- { "f3", 0x03, XT_REG_FR, XT_REGF_COPROC0 },
- { "f4", 0x04, XT_REG_FR, XT_REGF_COPROC0 },
- { "f5", 0x05, XT_REG_FR, XT_REGF_COPROC0 },
- { "f6", 0x06, XT_REG_FR, XT_REGF_COPROC0 },
- { "f7", 0x07, XT_REG_FR, XT_REGF_COPROC0 },
- { "f8", 0x08, XT_REG_FR, XT_REGF_COPROC0 },
- { "f9", 0x09, XT_REG_FR, XT_REGF_COPROC0 },
- { "f10", 0x0A, XT_REG_FR, XT_REGF_COPROC0 },
- { "f11", 0x0B, XT_REG_FR, XT_REGF_COPROC0 },
- { "f12", 0x0C, XT_REG_FR, XT_REGF_COPROC0 },
- { "f13", 0x0D, XT_REG_FR, XT_REGF_COPROC0 },
- { "f14", 0x0E, XT_REG_FR, XT_REGF_COPROC0 },
- { "f15", 0x0F, XT_REG_FR, XT_REGF_COPROC0 },
- { "fcr", 0xE8, XT_REG_USER, XT_REGF_COPROC0 },
- { "fsr", 0xE9, XT_REG_USER, XT_REGF_COPROC0 },
- { "mmid", 0x59, XT_REG_SPECIAL, XT_REGF_NOREAD },
- { "ibreakenable", 0x60, XT_REG_SPECIAL, 0 },
- { "memctl", 0x61, XT_REG_SPECIAL, 0 },
- { "atomctl", 0x63, XT_REG_SPECIAL, 0 },
- { "ibreaka0", 0x80, XT_REG_SPECIAL, 0 },
- { "ibreaka1", 0x81, XT_REG_SPECIAL, 0 },
- { "dbreaka0", 0x90, XT_REG_SPECIAL, 0 },
- { "dbreaka1", 0x91, XT_REG_SPECIAL, 0 },
- { "dbreakc0", 0xA0, XT_REG_SPECIAL, 0 },
- { "dbreakc1", 0xA1, XT_REG_SPECIAL, 0 },
- { "epc1", 0xB1, XT_REG_SPECIAL, 0 },
- { "epc2", 0xB2, XT_REG_SPECIAL, 0 },
- { "epc3", 0xB3, XT_REG_SPECIAL, 0 },
- { "epc4", 0xB4, XT_REG_SPECIAL, 0 },
- { "epc5", 0xB5, XT_REG_SPECIAL, 0 },
- { "epc6", 0xB6, XT_REG_SPECIAL, 0 },
- { "epc7", 0xB7, XT_REG_SPECIAL, 0 },
- { "depc", 0xC0, XT_REG_SPECIAL, 0 },
- { "eps2", 0xC2, XT_REG_SPECIAL, 0 },
- { "eps3", 0xC3, XT_REG_SPECIAL, 0 },
- { "eps4", 0xC4, XT_REG_SPECIAL, 0 },
- { "eps5", 0xC5, XT_REG_SPECIAL, 0 },
- { "eps6", 0xC6, XT_REG_SPECIAL, 0 },
- { "eps7", 0xC7, XT_REG_SPECIAL, 0 },
- { "excsave1", 0xD1, XT_REG_SPECIAL, 0 },
- { "excsave2", 0xD2, XT_REG_SPECIAL, 0 },
- { "excsave3", 0xD3, XT_REG_SPECIAL, 0 },
- { "excsave4", 0xD4, XT_REG_SPECIAL, 0 },
- { "excsave5", 0xD5, XT_REG_SPECIAL, 0 },
- { "excsave6", 0xD6, XT_REG_SPECIAL, 0 },
- { "excsave7", 0xD7, XT_REG_SPECIAL, 0 },
- { "cpenable", 0xE0, XT_REG_SPECIAL, 0 },
- { "interrupt", 0xE2, XT_REG_SPECIAL, 0 },
- { "intset", 0xE2, XT_REG_SPECIAL, XT_REGF_NOREAD },
- { "intclear", 0xE3, XT_REG_SPECIAL, XT_REGF_NOREAD },
- { "intenable", 0xE4, XT_REG_SPECIAL, 0 },
- { "vecbase", 0xE7, XT_REG_SPECIAL, 0 },
- { "exccause", 0xE8, XT_REG_SPECIAL, 0 },
- { "debugcause", 0xE9, XT_REG_SPECIAL, 0 },
- { "ccount", 0xEA, XT_REG_SPECIAL, 0 },
- { "prid", 0xEB, XT_REG_SPECIAL, 0 },
- { "icount", 0xEC, XT_REG_SPECIAL, 0 },
- { "icountlevel", 0xED, XT_REG_SPECIAL, 0 },
- { "excvaddr", 0xEE, XT_REG_SPECIAL, 0 },
- { "ccompare0", 0xF0, XT_REG_SPECIAL, 0 },
- { "ccompare1", 0xF1, XT_REG_SPECIAL, 0 },
- { "ccompare2", 0xF2, XT_REG_SPECIAL, 0 },
- { "misc0", 0xF4, XT_REG_SPECIAL, 0 },
- { "misc1", 0xF5, XT_REG_SPECIAL, 0 },
- { "misc2", 0xF6, XT_REG_SPECIAL, 0 },
- { "misc3", 0xF7, XT_REG_SPECIAL, 0 },
- { "litbase", 0x05, XT_REG_SPECIAL, 0 },
- { "ptevaddr", 0x53, XT_REG_SPECIAL, 0 },
- { "rasid", 0x5A, XT_REG_SPECIAL, 0 },
- { "itlbcfg", 0x5B, XT_REG_SPECIAL, 0 },
- { "dtlbcfg", 0x5C, XT_REG_SPECIAL, 0 },
- { "mepc", 0x6A, XT_REG_SPECIAL, 0 },
- { "meps", 0x6B, XT_REG_SPECIAL, 0 },
- { "mesave", 0x6C, XT_REG_SPECIAL, 0 },
- { "mesr", 0x6D, XT_REG_SPECIAL, 0 },
- { "mecr", 0x6E, XT_REG_SPECIAL, 0 },
- { "mevaddr", 0x6F, XT_REG_SPECIAL, 0 },
- { "a0", XT_REG_IDX_AR0, XT_REG_RELGEN, 0 }, /* WARNING: For these registers, regnum points to the */
- { "a1", XT_REG_IDX_AR1, XT_REG_RELGEN, 0 }, /* index of the corresponding ARxregisters, NOT to */
- { "a2", XT_REG_IDX_AR2, XT_REG_RELGEN, 0 }, /* the processor register number! */
- { "a3", XT_REG_IDX_AR3, XT_REG_RELGEN, 0 },
- { "a4", XT_REG_IDX_AR4, XT_REG_RELGEN, 0 },
- { "a5", XT_REG_IDX_AR5, XT_REG_RELGEN, 0 },
- { "a6", XT_REG_IDX_AR6, XT_REG_RELGEN, 0 },
- { "a7", XT_REG_IDX_AR7, XT_REG_RELGEN, 0 },
- { "a8", XT_REG_IDX_AR8, XT_REG_RELGEN, 0 },
- { "a9", XT_REG_IDX_AR9, XT_REG_RELGEN, 0 },
- { "a10", XT_REG_IDX_AR10, XT_REG_RELGEN, 0 },
- { "a11", XT_REG_IDX_AR11, XT_REG_RELGEN, 0 },
- { "a12", XT_REG_IDX_AR12, XT_REG_RELGEN, 0 },
- { "a13", XT_REG_IDX_AR13, XT_REG_RELGEN, 0 },
- { "a14", XT_REG_IDX_AR14, XT_REG_RELGEN, 0 },
- { "a15", XT_REG_IDX_AR15, XT_REG_RELGEN, 0 },
-
- { "pwrctl", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "pwrstat", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "eristat", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "cs_itctrl", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "cs_claimset", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "cs_claimclr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "cs_lockaccess", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "cs_lockstatus", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "cs_authstatus", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "fault_info", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_id", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_ctrl", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_stat", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_data", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_addr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_pctrigger", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_pcmatch", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_delay", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_memstart", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "trax_memend", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "pmg", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "pmoc", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "pm0", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "pm1", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "pmctrl0", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "pmctrl1", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "pmstat0", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "pmstat1", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "ocd_id", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "ocd_dcrclr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "ocd_dcrset", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "ocd_dsr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
- { "ddr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD },
+#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_PC_REG_NUM_VIRTUAL (0xffU) /* Marker for computing PC (EPC[DBGLEVEL) */
+#define XT_PC_DBREG_NUM_BASE (0x20U) /* External (i.e., GDB) access */
+
+#define XT_SW_BREAKPOINTS_MAX_NUM 32
+#define XT_HW_IBREAK_MAX_NUM 2
+#define XT_HW_DBREAK_MAX_NUM 2
+
+struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS] = {
+ XT_MK_REG_DESC("pc", XT_PC_REG_NUM_VIRTUAL, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("ar0", 0x00, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar1", 0x01, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar2", 0x02, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar3", 0x03, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar4", 0x04, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar5", 0x05, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar6", 0x06, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar7", 0x07, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar8", 0x08, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar9", 0x09, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar10", 0x0A, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar11", 0x0B, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar12", 0x0C, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar13", 0x0D, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar14", 0x0E, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar15", 0x0F, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar16", 0x10, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar17", 0x11, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar18", 0x12, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar19", 0x13, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar20", 0x14, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar21", 0x15, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar22", 0x16, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar23", 0x17, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar24", 0x18, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar25", 0x19, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar26", 0x1A, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar27", 0x1B, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar28", 0x1C, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar29", 0x1D, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar30", 0x1E, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar31", 0x1F, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar32", 0x20, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar33", 0x21, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar34", 0x22, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar35", 0x23, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar36", 0x24, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar37", 0x25, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar38", 0x26, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar39", 0x27, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar40", 0x28, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar41", 0x29, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar42", 0x2A, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar43", 0x2B, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar44", 0x2C, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar45", 0x2D, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar46", 0x2E, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar47", 0x2F, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar48", 0x30, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar49", 0x31, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar50", 0x32, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar51", 0x33, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar52", 0x34, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar53", 0x35, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar54", 0x36, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar55", 0x37, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar56", 0x38, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar57", 0x39, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar58", 0x3A, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar59", 0x3B, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar60", 0x3C, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar61", 0x3D, XT_REG_GENERAL, 0),
+ XT_MK_REG_DESC("ar62", 0x3E, XT_REG_GENERAL, 0),
+ 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("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),
+ XT_MK_REG_DESC("ibreaka1", 0x81, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("dbreaka0", 0x90, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("dbreaka1", 0x91, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("dbreakc0", 0xA0, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("dbreakc1", 0xA1, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("cpenable", 0xE0, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("exccause", 0xE8, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("debugcause", 0xE9, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("icount", 0xEC, XT_REG_SPECIAL, 0),
+ XT_MK_REG_DESC("icountlevel", 0xED, XT_REG_SPECIAL, 0),
+
+ /* WARNING: For these registers, regnum points to the
+ * index of the corresponding ARx registers, NOT to
+ * the processor register number! */
+ XT_MK_REG_DESC("a0", XT_REG_IDX_AR0, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a1", XT_REG_IDX_AR1, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a2", XT_REG_IDX_AR2, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a3", XT_REG_IDX_AR3, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a4", XT_REG_IDX_AR4, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a5", XT_REG_IDX_AR5, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a6", XT_REG_IDX_AR6, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a7", XT_REG_IDX_AR7, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a8", XT_REG_IDX_AR8, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a9", XT_REG_IDX_AR9, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a10", XT_REG_IDX_AR10, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a11", XT_REG_IDX_AR11, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a12", XT_REG_IDX_AR12, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a13", XT_REG_IDX_AR13, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a14", XT_REG_IDX_AR14, XT_REG_RELGEN, 0),
+ XT_MK_REG_DESC("a15", XT_REG_IDX_AR15, XT_REG_RELGEN, 0),
};
-
/**
* Types of memory used at xtensa target
*/
@@ -357,11 +289,27 @@ enum xtensa_mem_region_type {
XTENSA_MEM_REG_IRAM,
XTENSA_MEM_REG_DROM,
XTENSA_MEM_REG_DRAM,
- XTENSA_MEM_REG_URAM,
- XTENSA_MEM_REG_XLMI,
+ XTENSA_MEM_REG_SRAM,
+ XTENSA_MEM_REG_SROM,
XTENSA_MEM_REGS_NUM
};
+/* Register definition as union for list allocation */
+union xtensa_reg_val_u {
+ xtensa_reg_val_t val;
+ uint8_t buf[4];
+};
+
+static const struct xtensa_keyval_info_s xt_qerr[XT_QERR_NUM] = {
+ { .chrval = "E00", .intval = ERROR_FAIL },
+ { .chrval = "E01", .intval = ERROR_FAIL },
+ { .chrval = "E02", .intval = ERROR_COMMAND_ARGUMENT_INVALID },
+ { .chrval = "E03", .intval = ERROR_FAIL },
+};
+
+/* Set to true for extra debug logging */
+static const bool xtensa_extra_debug_log;
+
/**
* Gets a config for the specific mem type
*/
@@ -378,10 +326,10 @@ static inline const struct xtensa_local_mem_config *xtensa_get_mem_config(
return &xtensa->core_config->drom;
case XTENSA_MEM_REG_DRAM:
return &xtensa->core_config->dram;
- case XTENSA_MEM_REG_URAM:
- return &xtensa->core_config->uram;
- case XTENSA_MEM_REG_XLMI:
- return &xtensa->core_config->xlmi;
+ case XTENSA_MEM_REG_SRAM:
+ return &xtensa->core_config->sram;
+ case XTENSA_MEM_REG_SROM:
+ return &xtensa->core_config->srom;
default:
return NULL;
}
@@ -424,14 +372,47 @@ static inline const struct xtensa_local_mem_region_config *xtensa_target_memory_
return NULL;
}
+static inline bool xtensa_is_cacheable(const struct xtensa_cache_config *cache,
+ const struct xtensa_local_mem_config *mem,
+ target_addr_t address)
+{
+ if (!cache->size)
+ return false;
+ return xtensa_memory_region_find(mem, address);
+}
+
+static inline bool xtensa_is_icacheable(struct xtensa *xtensa, target_addr_t address)
+{
+ return xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->iram, address) ||
+ xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->irom, address) ||
+ xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->sram, address) ||
+ xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->srom, address);
+}
+
+static inline bool xtensa_is_dcacheable(struct xtensa *xtensa, target_addr_t address)
+{
+ return xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->dram, address) ||
+ xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->drom, address) ||
+ xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->sram, address) ||
+ xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->srom, address);
+}
+
static int xtensa_core_reg_get(struct reg *reg)
{
- /*We don't need this because we read all registers on halt anyway. */
+ /* We don't need this because we read all registers on halt anyway. */
struct xtensa *xtensa = (struct xtensa *)reg->arch_info;
struct target *target = xtensa->target;
if (target->state != TARGET_HALTED)
return ERROR_TARGET_NOT_HALTED;
+ if (!reg->exist) {
+ if (strncmp(reg->name, "?0x", 3) == 0) {
+ unsigned int regnum = strtoul(reg->name + 1, 0, 0);
+ LOG_WARNING("Read unknown register 0x%04x ignored", regnum);
+ return ERROR_OK;
+ }
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
return ERROR_OK;
}
@@ -444,7 +425,31 @@ static int xtensa_core_reg_set(struct reg *reg, uint8_t *buf)
if (target->state != TARGET_HALTED)
return ERROR_TARGET_NOT_HALTED;
+ if (!reg->exist) {
+ if (strncmp(reg->name, "?0x", 3) == 0) {
+ unsigned int regnum = strtoul(reg->name + 1, 0, 0);
+ LOG_WARNING("Write unknown register 0x%04x ignored", regnum);
+ return ERROR_OK;
+ }
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
buf_cpy(buf, reg->value, reg->size);
+
+ if (xtensa->core_config->windowed) {
+ /* If the user updates a potential scratch register, track for conflicts */
+ for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) {
+ if (strcmp(reg->name, xtensa->scratch_ars[s].chrval) == 0) {
+ LOG_DEBUG("Scratch reg %s [0x%08" PRIx32 "] set from gdb", reg->name,
+ buf_get_u32(reg->value, 0, 32));
+ LOG_DEBUG("scratch_ars mapping: a3/%s, a4/%s",
+ xtensa->scratch_ars[XT_AR_SCRATCH_AR3].chrval,
+ xtensa->scratch_ars[XT_AR_SCRATCH_AR4].chrval);
+ xtensa->scratch_ars[s].intval = true;
+ break;
+ }
+ }
+ }
reg->dirty = true;
reg->valid = true;
@@ -456,26 +461,13 @@ static const struct reg_arch_type xtensa_reg_type = {
.set = xtensa_core_reg_set,
};
-const struct reg_arch_type xtensa_user_reg_u32_type = {
- .get = xtensa_core_reg_get,
- .set = xtensa_core_reg_set,
-};
-
-const struct reg_arch_type xtensa_user_reg_u128_type = {
- .get = xtensa_core_reg_get,
- .set = xtensa_core_reg_set,
-};
-
-static inline size_t xtensa_insn_size_get(uint32_t insn)
-{
- return insn & BIT(3) ? 2 : XT_ISNS_SZ_MAX;
-}
-
/* Convert a register index that's indexed relative to windowbase, to the real address. */
-static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(enum xtensa_reg_id reg_idx, int windowbase)
+static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(struct xtensa *xtensa,
+ enum xtensa_reg_id reg_idx,
+ int windowbase)
{
unsigned int idx;
- if (reg_idx >= XT_REG_IDX_AR0 && reg_idx <= XT_REG_IDX_AR63) {
+ if (reg_idx >= XT_REG_IDX_AR0 && reg_idx <= XT_REG_IDX_ARLAST) {
idx = reg_idx - XT_REG_IDX_AR0;
} else if (reg_idx >= XT_REG_IDX_A0 && reg_idx <= XT_REG_IDX_A15) {
idx = reg_idx - XT_REG_IDX_A0;
@@ -483,12 +475,14 @@ static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(enum xtensa_reg_
LOG_ERROR("Error: can't convert register %d to non-windowbased register!", reg_idx);
return -1;
}
- return ((idx + windowbase * 4) & 63) + XT_REG_IDX_AR0;
+ return ((idx + windowbase * 4) & (xtensa->core_config->aregs_num - 1)) + XT_REG_IDX_AR0;
}
-static enum xtensa_reg_id xtensa_canonical_to_windowbase_offset(enum xtensa_reg_id reg_idx, int windowbase)
+static enum xtensa_reg_id xtensa_canonical_to_windowbase_offset(struct xtensa *xtensa,
+ enum xtensa_reg_id reg_idx,
+ int windowbase)
{
- return xtensa_windowbase_offset_to_canonical(reg_idx, -windowbase);
+ return xtensa_windowbase_offset_to_canonical(xtensa, reg_idx, -windowbase);
}
static void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)
@@ -497,36 +491,78 @@ static void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id
reg_list[reg_idx].dirty = true;
}
-static int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, unsigned int reg, uint8_t *data)
+static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins)
{
- struct xtensa_debug_module *dm = &xtensa->dbg_mod;
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0EXEC, ins);
+}
- if (!xtensa->core_config->trace.enabled &&
- (reg <= NARADR_MEMADDREND || (reg >= NARADR_PMG && reg <= NARADR_PMSTAT7))) {
- LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg);
- return ERROR_FAIL;
+static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint8_t oplen)
+{
+ const int max_oplen = 64; /* 8 DIRx regs: max width 64B */
+ if ((oplen > 0) && (oplen <= max_oplen)) {
+ uint8_t ops_padded[max_oplen];
+ memcpy(ops_padded, ops, oplen);
+ memset(ops_padded + oplen, 0, max_oplen - oplen);
+ unsigned int oplenw = DIV_ROUND_UP(oplen, sizeof(uint32_t));
+ for (int32_t i = oplenw - 1; i > 0; i--)
+ xtensa_queue_dbg_reg_write(xtensa,
+ XDMREG_DIR0 + i,
+ target_buffer_get_u32(xtensa->target, &ops_padded[sizeof(uint32_t)*i]));
+ /* Write DIR0EXEC last */
+ xtensa_queue_dbg_reg_write(xtensa,
+ XDMREG_DIR0EXEC,
+ target_buffer_get_u32(xtensa->target, &ops_padded[0]));
}
- return dm->dbg_ops->queue_reg_read(dm, reg, data);
}
-static int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
+static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
{
struct xtensa_debug_module *dm = &xtensa->dbg_mod;
+ return dm->pwr_ops->queue_reg_write(dm, reg, data);
+}
- if (!xtensa->core_config->trace.enabled &&
- (reg <= NARADR_MEMADDREND || (reg >= NARADR_PMG && reg <= NARADR_PMSTAT7))) {
- LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg);
- return ERROR_FAIL;
+/* NOTE: Assumes A3 has already been saved */
+static int xtensa_window_state_save(struct target *target, uint32_t *woe)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ int woe_dis;
+ uint8_t woe_buf[4];
+
+ if (xtensa->core_config->windowed) {
+ /* Save PS (LX) and disable window overflow exceptions prior to AR save */
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_PS, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, woe_buf);
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to read PS (%d)!", res);
+ return res;
+ }
+ xtensa_core_status_check(target);
+ *woe = buf_get_u32(woe_buf, 0, 32);
+ woe_dis = *woe & ~XT_PS_WOE_MSK;
+ LOG_DEBUG("Clearing PS.WOE (0x%08" PRIx32 " -> 0x%08" PRIx32 ")", *woe, woe_dis);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe_dis);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3));
}
- return dm->dbg_ops->queue_reg_write(dm, reg, data);
+ return ERROR_OK;
}
-static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins)
+/* NOTE: Assumes A3 has already been saved */
+static void xtensa_window_state_restore(struct target *target, uint32_t woe)
{
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DIR0EXEC, ins);
+ struct xtensa *xtensa = target_to_xtensa(target);
+ if (xtensa->core_config->windowed) {
+ /* Restore window overflow exception state */
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3));
+ LOG_DEBUG("Restored PS.WOE (0x%08" PRIx32 ")", woe);
+ }
}
-static bool xtensa_reg_is_readable(enum xtensa_reg_flags flags, xtensa_reg_val_t cpenable)
+static bool xtensa_reg_is_readable(int flags, int cpenable)
{
if (flags & XT_REGF_NOREAD)
return false;
@@ -535,69 +571,17 @@ static bool xtensa_reg_is_readable(enum xtensa_reg_flags flags, xtensa_reg_val_t
return true;
}
-static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
+static bool xtensa_scratch_regs_fixup(struct xtensa *xtensa, struct reg *reg_list, int i, int j, int a_idx, int ar_idx)
{
- struct xtensa_debug_module *dm = &xtensa->dbg_mod;
- return dm->pwr_ops->queue_reg_write(dm, reg, data);
-}
-
-static bool xtensa_special_reg_exists(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)
-{
- /* TODO: array of size XT_NUM_REGS can be used here to map special register ID to
- * corresponding config option 'enabled' flag */
- if (reg_idx >= XT_REG_IDX_LBEG && reg_idx <= XT_REG_IDX_LCOUNT)
- return xtensa->core_config->loop;
- else if (reg_idx == XT_REG_IDX_BR)
- return xtensa->core_config->boolean;
- else if (reg_idx == XT_REG_IDX_LITBASE)
- return xtensa->core_config->ext_l32r;
- else if (reg_idx == XT_REG_IDX_SCOMPARE1 || reg_idx == XT_REG_IDX_ATOMCTL)
- return xtensa->core_config->cond_store;
- else if (reg_idx >= XT_REG_IDX_ACCLO && reg_idx <= XT_REG_IDX_M3)
- return xtensa->core_config->mac16;
- else if (reg_idx == XT_REG_IDX_WINDOWBASE || reg_idx == XT_REG_IDX_WINDOWSTART)
- return xtensa->core_config->windowed;
- else if (reg_idx >= XT_REG_IDX_PTEVADDR && reg_idx <= XT_REG_IDX_DTLBCFG)
- return xtensa->core_config->mmu.enabled;
- else if (reg_idx == XT_REG_IDX_MMID)
- return xtensa->core_config->trace.enabled;
- else if (reg_idx >= XT_REG_IDX_MEPC && reg_idx <= XT_REG_IDX_MEVADDR)
- return xtensa->core_config->mem_err_check;
- else if (reg_idx == XT_REG_IDX_CPENABLE)
- return xtensa->core_config->coproc;
- else if (reg_idx == XT_REG_IDX_VECBASE)
- return xtensa->core_config->reloc_vec;
- else if (reg_idx == XT_REG_IDX_CCOUNT)
- return xtensa->core_config->tim_irq.enabled;
- else if (reg_idx >= XT_REG_IDX_CCOMPARE0 && reg_idx <= XT_REG_IDX_CCOMPARE2)
- return xtensa->core_config->tim_irq.enabled &&
- (reg_idx - XT_REG_IDX_CCOMPARE0 < xtensa->core_config->tim_irq.comp_num);
- else if (reg_idx == XT_REG_IDX_PRID)
- return xtensa->core_config->proc_id;
- else if (reg_idx >= XT_REG_IDX_MISC0 && reg_idx <= XT_REG_IDX_MISC3)
- return reg_idx - XT_REG_IDX_MISC0 < xtensa->core_config->miscregs_num;
- return true;
-}
-
-static bool xtensa_user_reg_exists(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)
-{
- if (reg_idx == XT_REG_IDX_THREADPTR)
- return xtensa->core_config->threadptr;
- if (reg_idx == XT_REG_IDX_FCR || reg_idx == XT_REG_IDX_FSR)
- return xtensa->core_config->fp_coproc;
- return false;
-}
-
-static inline bool xtensa_fp_reg_exists(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)
-{
- return xtensa->core_config->fp_coproc;
-}
-
-static inline bool xtensa_regular_reg_exists(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)
-{
- if (reg_idx >= XT_REG_IDX_AR0 && reg_idx <= XT_REG_IDX_AR63)
- return reg_idx - XT_REG_IDX_AR0 < xtensa->core_config->aregs_num;
- return true;
+ int a_name = (a_idx == XT_AR_SCRATCH_A3) ? 3 : 4;
+ if (xtensa->scratch_ars[a_idx].intval && !xtensa->scratch_ars[ar_idx].intval) {
+ LOG_DEBUG("AR conflict: a%d -> ar%d", a_name, j - XT_REG_IDX_AR0);
+ memcpy(reg_list[j].value, reg_list[i].value, sizeof(xtensa_reg_val_t));
+ } else {
+ LOG_DEBUG("AR conflict: ar%d -> a%d", j - XT_REG_IDX_AR0, a_name);
+ memcpy(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t));
+ }
+ return xtensa->scratch_ars[a_idx].intval && xtensa->scratch_ars[ar_idx].intval;
}
static int xtensa_write_dirty_registers(struct target *target)
@@ -605,45 +589,50 @@ static int xtensa_write_dirty_registers(struct target *target)
struct xtensa *xtensa = target_to_xtensa(target);
int res;
xtensa_reg_val_t regval, windowbase = 0;
- bool scratch_reg_dirty = false;
+ bool scratch_reg_dirty = false, delay_cpenable = false;
struct reg *reg_list = xtensa->core_cache->reg_list;
+ unsigned int reg_list_size = xtensa->core_cache->num_regs;
+ bool preserve_a3 = false;
+ uint8_t a3_buf[4];
+ xtensa_reg_val_t a3 = 0, woe;
LOG_TARGET_DEBUG(target, "start");
- /*We need to write the dirty registers in the cache list back to the processor.
- *Start by writing the SFR/user registers. */
- for (unsigned int i = 0; i < XT_NUM_REGS; i++) {
+ /* We need to write the dirty registers in the cache list back to the processor.
+ * Start by writing the SFR/user registers. */
+ for (unsigned int i = 0; i < reg_list_size; i++) {
+ struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
+ unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
if (reg_list[i].dirty) {
- if (xtensa_regs[i].type == XT_REG_SPECIAL ||
- xtensa_regs[i].type == XT_REG_USER ||
- xtensa_regs[i].type == XT_REG_FR) {
+ if (rlist[ridx].type == XT_REG_SPECIAL ||
+ rlist[ridx].type == XT_REG_USER ||
+ rlist[ridx].type == XT_REG_FR) {
scratch_reg_dirty = true;
+ if (i == XT_REG_IDX_CPENABLE) {
+ delay_cpenable = true;
+ continue;
+ }
regval = xtensa_reg_get(target, i);
- LOG_TARGET_DEBUG(target, "Writing back reg %s val %08" PRIX32,
- xtensa_regs[i].name,
+ LOG_TARGET_DEBUG(target, "Writing back reg %s (%d) val %08" PRIX32,
+ reg_list[i].name,
+ rlist[ridx].reg_num,
regval);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval);
- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3));
- if (xtensa_regs[i].type == XT_REG_USER) {
- if (reg_list[i].exist)
- xtensa_queue_exec_ins(xtensa,
- XT_INS_WUR(xtensa_regs[i].reg_num,
- XT_REG_A3));
- } else if (xtensa_regs[i].type == XT_REG_FR) {
- if (reg_list[i].exist)
- xtensa_queue_exec_ins(xtensa,
- XT_INS_WFR(xtensa_regs[i].reg_num,
- XT_REG_A3));
- } else {/*SFR */
- if (reg_list[i].exist) {
- unsigned int reg_num = xtensa_regs[i].reg_num;
- if (reg_num == XT_PC_REG_NUM_BASE)
- /* reg number of PC for debug interrupt
- * depends on NDEBUGLEVEL */
- reg_num += xtensa->core_config->debug.irq_level;
-
- xtensa_queue_exec_ins(xtensa,
- XT_INS_WSR(reg_num, XT_REG_A3));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ if (reg_list[i].exist) {
+ unsigned int reg_num = rlist[ridx].reg_num;
+ if (rlist[ridx].type == XT_REG_USER) {
+ xtensa_queue_exec_ins(xtensa, XT_INS_WUR(xtensa, reg_num, XT_REG_A3));
+ } else if (rlist[ridx].type == XT_REG_FR) {
+ xtensa_queue_exec_ins(xtensa, XT_INS_WFR(xtensa, reg_num, XT_REG_A3));
+ } else {/*SFR */
+ 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);
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3));
}
}
reg_list[i].dirty = false;
@@ -652,31 +641,66 @@ static int xtensa_write_dirty_registers(struct target *target)
}
if (scratch_reg_dirty)
xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
+ if (delay_cpenable) {
+ regval = xtensa_reg_get(target, XT_REG_IDX_CPENABLE);
+ LOG_TARGET_DEBUG(target, "Writing back reg cpenable (224) val %08" PRIX32, regval);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa,
+ xtensa_regs[XT_REG_IDX_CPENABLE].reg_num,
+ XT_REG_A3));
+ reg_list[XT_REG_IDX_CPENABLE].dirty = false;
+ }
- if (xtensa->core_config->user_regs_num > 0 &&
- xtensa->core_config->queue_write_dirty_user_regs)
- xtensa->core_config->queue_write_dirty_user_regs(target);
+ preserve_a3 = (xtensa->core_config->windowed);
+ if (preserve_a3) {
+ /* Save (windowed) A3 for scratch use */
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf);
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ if (res != ERROR_OK)
+ return res;
+ xtensa_core_status_check(target);
+ a3 = buf_get_u32(a3_buf, 0, 32);
+ }
if (xtensa->core_config->windowed) {
- /*Grab the windowbase, we need it. */
+ res = xtensa_window_state_save(target, &woe);
+ if (res != ERROR_OK)
+ return res;
+ /* Grab the windowbase, we need it. */
windowbase = xtensa_reg_get(target, XT_REG_IDX_WINDOWBASE);
- /*Check if there are problems with both the ARx as well as the corresponding Rx
- * registers set and dirty. */
- /*Warn the user if this happens, not much else we can do... */
+ /* Check if there are mismatches between the ARx and corresponding Ax registers.
+ * When the user sets a register on a windowed config, xt-gdb may set the ARx
+ * register directly. Thus we take ARx as priority over Ax if both are dirty
+ * and it's unclear if the user set one over the other explicitly.
+ */
for (unsigned int i = XT_REG_IDX_A0; i <= XT_REG_IDX_A15; i++) {
- unsigned int j = xtensa_windowbase_offset_to_canonical(i, windowbase);
+ unsigned int j = xtensa_windowbase_offset_to_canonical(xtensa, i, windowbase);
if (reg_list[i].dirty && reg_list[j].dirty) {
- if (memcmp(reg_list[i].value, reg_list[j].value,
- sizeof(xtensa_reg_val_t)) != 0)
- LOG_WARNING(
- "Warning: Both A%d as well as the physical register it points to (AR%d) are dirty and differs in value. Results are undefined!",
- i - XT_REG_IDX_A0,
- j - XT_REG_IDX_AR0);
+ if (memcmp(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t)) != 0) {
+ bool show_warning = true;
+ if (i == XT_REG_IDX_A3)
+ show_warning = xtensa_scratch_regs_fixup(xtensa,
+ reg_list, i, j, XT_AR_SCRATCH_A3, XT_AR_SCRATCH_AR3);
+ else if (i == XT_REG_IDX_A4)
+ show_warning = xtensa_scratch_regs_fixup(xtensa,
+ reg_list, i, j, XT_AR_SCRATCH_A4, XT_AR_SCRATCH_AR4);
+ if (show_warning)
+ LOG_WARNING(
+ "Warning: Both A%d [0x%08" PRIx32
+ "] as well as its underlying physical register "
+ "(AR%d) [0x%08" PRIx32 "] are dirty and differ in value",
+ i - XT_REG_IDX_A0,
+ buf_get_u32(reg_list[i].value, 0, 32),
+ j - XT_REG_IDX_AR0,
+ buf_get_u32(reg_list[j].value, 0, 32));
+ }
}
}
}
- /*Write A0-A16 */
+ /* Write A0-A16. */
for (unsigned int i = 0; i < 16; i++) {
if (reg_list[XT_REG_IDX_A0 + i].dirty) {
regval = xtensa_reg_get(target, XT_REG_IDX_A0 + i);
@@ -684,22 +708,26 @@ static int xtensa_write_dirty_registers(struct target *target)
xtensa_regs[XT_REG_IDX_A0 + i].name,
regval,
xtensa_regs[XT_REG_IDX_A0 + i].reg_num);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval);
- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, i));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, i));
reg_list[XT_REG_IDX_A0 + i].dirty = false;
+ if (i == 3) {
+ /* Avoid stomping A3 during restore at end of function */
+ a3 = regval;
+ }
}
}
if (xtensa->core_config->windowed) {
- /*Now write AR0-AR63. */
- for (unsigned int j = 0; j < 64; j += 16) {
- /*Write the 16 registers we can see */
+ /* Now write AR registers */
+ for (unsigned int j = 0; j < XT_REG_IDX_ARLAST; j += 16) {
+ /* Write the 16 registers we can see */
for (unsigned int i = 0; i < 16; i++) {
if (i + j < xtensa->core_config->aregs_num) {
enum xtensa_reg_id realadr =
- xtensa_windowbase_offset_to_canonical(XT_REG_IDX_AR0 + i + j,
+ xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_AR0 + i + j,
windowbase);
- /*Write back any dirty un-windowed registers */
+ /* Write back any dirty un-windowed registers */
if (reg_list[realadr].dirty) {
regval = xtensa_reg_get(target, realadr);
LOG_TARGET_DEBUG(
@@ -708,55 +736,38 @@ static int xtensa_write_dirty_registers(struct target *target)
xtensa_regs[realadr].name,
regval,
xtensa_regs[realadr].reg_num);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
xtensa_queue_exec_ins(xtensa,
- XT_INS_RSR(XT_SR_DDR, xtensa_regs[XT_REG_IDX_AR0 + i].reg_num));
+ XT_INS_RSR(xtensa, XT_SR_DDR,
+ xtensa_regs[XT_REG_IDX_AR0 + i].reg_num));
reg_list[realadr].dirty = false;
+ if ((i + j) == 3)
+ /* Avoid stomping AR during A3 restore at end of function */
+ a3 = regval;
}
}
}
/*Now rotate the window so we'll see the next 16 registers. The final rotate
* will wraparound, */
/*leaving us in the state we were. */
- xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(4));
+ xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, 4));
}
- }
- res = jtag_execute_queue();
- xtensa_core_status_check(target);
- return res;
-}
+ xtensa_window_state_restore(target, woe);
-int xtensa_queue_write_dirty_user_regs_u32(struct target *target)
-{
- struct xtensa *xtensa = target_to_xtensa(target);
- struct reg *reg_list = xtensa->core_cache->reg_list;
- xtensa_reg_val_t reg_val;
- bool scratch_reg_dirty = false;
-
- LOG_TARGET_DEBUG(target, "start");
+ for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)
+ xtensa->scratch_ars[s].intval = false;
+ }
- /* We need to write the dirty registers in the cache list back to the processor.
- * Start by writing the SFR/user registers. */
- for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) {
- if (!reg_list[XT_USR_REG_START + i].dirty)
- continue;
- scratch_reg_dirty = true;
- reg_val = xtensa_reg_get(target, XT_USR_REG_START + i);
- LOG_TARGET_DEBUG(target, "Writing back reg %s val %08" PRIX32,
- xtensa->core_config->user_regs[i].name,
- reg_val);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, reg_val);
- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3));
- xtensa_queue_exec_ins(xtensa,
- XT_INS_WUR(xtensa->core_config->user_regs[i].reg_num,
- XT_REG_A3));
- reg_list[XT_USR_REG_START + i].dirty = false;
+ if (preserve_a3) {
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
}
- if (scratch_reg_dirty)
- xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
- return ERROR_OK;
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ xtensa_core_status_check(target);
+
+ return res;
}
static inline bool xtensa_is_stopped(struct target *target)
@@ -768,14 +779,20 @@ static inline bool xtensa_is_stopped(struct target *target)
int xtensa_examine(struct target *target)
{
struct xtensa *xtensa = target_to_xtensa(target);
- unsigned int cmd = PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP;
+ unsigned int cmd = PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) | PWRCTL_COREWAKEUP(xtensa);
LOG_DEBUG("coreid = %d", target->coreid);
- xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd);
- xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE);
+
+ if (xtensa->core_config->core_type == XT_UNDEF) {
+ LOG_ERROR("XTensa core not configured; is xtensa-core-openocd.cfg missing?");
+ return ERROR_FAIL;
+ }
+
+ xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd);
+ xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE(xtensa));
xtensa_dm_queue_enable(&xtensa->dbg_mod);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK)
return res;
if (!xtensa_dm_is_online(&xtensa->dbg_mod)) {
@@ -792,15 +809,15 @@ int xtensa_examine(struct target *target)
int xtensa_wakeup(struct target *target)
{
struct xtensa *xtensa = target_to_xtensa(target);
- unsigned int cmd = PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP;
+ unsigned int cmd = PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) | PWRCTL_COREWAKEUP(xtensa);
if (xtensa->reset_asserted)
- cmd |= PWRCTL_CORERESET;
- xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd);
+ cmd |= PWRCTL_CORERESET(xtensa);
+ xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd);
/* TODO: can we join this with the write above? */
- xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE);
+ xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE(xtensa));
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(&xtensa->dbg_mod);
}
int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set)
@@ -811,11 +828,11 @@ int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set)
OCDDCR_DEBUGMODEOUTEN | OCDDCR_ENABLEOCD);
LOG_TARGET_DEBUG(xtensa->target, "write smpbreak set=0x%" PRIx32 " clear=0x%" PRIx32, set, clear);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRSET, set | OCDDCR_ENABLEOCD);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRCLR, clear);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DSR, dsr_data);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, set | OCDDCR_ENABLEOCD);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, clear);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DSR, dsr_data);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(&xtensa->dbg_mod);
}
int xtensa_smpbreak_set(struct target *target, uint32_t set)
@@ -834,9 +851,9 @@ int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val)
{
uint8_t dcr_buf[sizeof(uint32_t)];
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DCRSET, dcr_buf);
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DCRSET, dcr_buf);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
*val = buf_get_u32(dcr_buf, 0, 32);
return res;
@@ -892,7 +909,7 @@ int xtensa_core_status_check(struct target *target)
OCDDSR_EXECEXCEPTION | OCDDSR_EXECOVERRUN);
if (res != ERROR_OK && !xtensa->suppress_dsr_errors)
LOG_TARGET_ERROR(target, "clearing DSR failed!");
- return xtensa->suppress_dsr_errors ? ERROR_OK : ERROR_FAIL;
+ return ERROR_FAIL;
}
return ERROR_OK;
}
@@ -901,7 +918,6 @@ xtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id
{
struct xtensa *xtensa = target_to_xtensa(target);
struct reg *reg = &xtensa->core_cache->reg_list[reg_id];
- assert(reg_id < xtensa->core_cache->num_regs && "Attempt to access non-existing reg!");
return xtensa_reg_get_value(reg);
}
@@ -909,28 +925,54 @@ void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg
{
struct xtensa *xtensa = target_to_xtensa(target);
struct reg *reg = &xtensa->core_cache->reg_list[reg_id];
- assert(reg_id < xtensa->core_cache->num_regs && "Attempt to access non-existing reg!");
if (xtensa_reg_get_value(reg) == value)
return;
xtensa_reg_set_value(reg, value);
}
+/* Set Ax (XT_REG_RELGEN) register along with its underlying ARx (XT_REG_GENERAL) */
+void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ uint32_t windowbase = (xtensa->core_config->windowed ?
+ xtensa_reg_get(target, XT_REG_IDX_WINDOWBASE) : 0);
+ int ar_idx = xtensa_windowbase_offset_to_canonical(xtensa, a_idx, windowbase);
+ xtensa_reg_set(target, a_idx, value);
+ xtensa_reg_set(target, ar_idx, value);
+}
+
+/* Read cause for entering halted state; return bitmask in DEBUGCAUSE_* format */
+uint32_t xtensa_cause_get(struct target *target)
+{
+ return xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE);
+}
+
+void xtensa_cause_clear(struct target *target)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0);
+ xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false;
+}
+
int xtensa_assert_reset(struct target *target)
{
struct xtensa *xtensa = target_to_xtensa(target);
LOG_TARGET_DEBUG(target, "target_number=%i, begin", target->target_number);
- target->state = TARGET_RESET;
xtensa_queue_pwr_reg_write(xtensa,
- DMREG_PWRCTL,
- PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP |
- PWRCTL_CORERESET);
+ XDMREG_PWRCTL,
+ PWRCTL_JTAGDEBUGUSE(xtensa) | PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) |
+ PWRCTL_COREWAKEUP(xtensa) | PWRCTL_CORERESET(xtensa));
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK)
return res;
+
+ /* registers are now invalid */
xtensa->reset_asserted = true;
- return res;
+ register_cache_invalidate(xtensa->core_cache);
+ target->state = TARGET_RESET;
+ return ERROR_OK;
}
int xtensa_deassert_reset(struct target *target)
@@ -940,13 +982,14 @@ int xtensa_deassert_reset(struct target *target)
LOG_TARGET_DEBUG(target, "halt=%d", target->reset_halt);
if (target->reset_halt)
xtensa_queue_dbg_reg_write(xtensa,
- NARADR_DCRSET,
+ XDMREG_DCRSET,
OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);
xtensa_queue_pwr_reg_write(xtensa,
- DMREG_PWRCTL,
- PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP);
+ XDMREG_PWRCTL,
+ PWRCTL_JTAGDEBUGUSE(xtensa) | PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) |
+ PWRCTL_COREWAKEUP(xtensa));
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK)
return res;
target->state = TARGET_RUNNING;
@@ -954,17 +997,43 @@ int xtensa_deassert_reset(struct target *target)
return res;
}
+int xtensa_soft_reset_halt(struct target *target)
+{
+ LOG_TARGET_DEBUG(target, "begin");
+ return xtensa_assert_reset(target);
+}
+
int xtensa_fetch_all_regs(struct target *target)
{
struct xtensa *xtensa = target_to_xtensa(target);
struct reg *reg_list = xtensa->core_cache->reg_list;
- xtensa_reg_val_t cpenable = 0, windowbase = 0;
- uint8_t regvals[XT_NUM_REGS][sizeof(xtensa_reg_val_t)];
- uint8_t dsrs[XT_NUM_REGS][sizeof(xtensa_dsr_t)];
+ unsigned int reg_list_size = xtensa->core_cache->num_regs;
+ xtensa_reg_val_t cpenable = 0, windowbase = 0, a3;
+ uint32_t woe;
+ uint8_t a3_buf[4];
bool debug_dsrs = !xtensa->regs_fetched || LOG_LEVEL_IS(LOG_LVL_DEBUG);
+ union xtensa_reg_val_u *regvals = calloc(reg_list_size, sizeof(*regvals));
+ if (!regvals) {
+ LOG_TARGET_ERROR(target, "unable to allocate memory for regvals!");
+ return ERROR_FAIL;
+ }
+ union xtensa_reg_val_u *dsrs = calloc(reg_list_size, sizeof(*dsrs));
+ if (!dsrs) {
+ LOG_TARGET_ERROR(target, "unable to allocate memory for dsrs!");
+ free(regvals);
+ return ERROR_FAIL;
+ }
+
LOG_TARGET_DEBUG(target, "start");
+ /* Save (windowed) A3 so cache matches physical AR3; A3 usable as scratch */
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf);
+ int res = xtensa_window_state_save(target, &woe);
+ if (res != ERROR_OK)
+ goto xtensa_fetch_all_regs_done;
+
/* Assume the CPU has just halted. We now want to fill the register cache with all the
* register contents GDB needs. For speed, we pipeline all the read operations, execute them
* in one go, then sort everything out from the regvals variable. */
@@ -975,176 +1044,181 @@ int xtensa_fetch_all_regs(struct target *target)
for (unsigned int i = 0; i < 16; i++) {
if (i + j < xtensa->core_config->aregs_num) {
xtensa_queue_exec_ins(xtensa,
- XT_INS_WSR(XT_SR_DDR, xtensa_regs[XT_REG_IDX_AR0 + i].reg_num));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[XT_REG_IDX_AR0 + i + j]);
+ XT_INS_WSR(xtensa, XT_SR_DDR, xtensa_regs[XT_REG_IDX_AR0 + i].reg_num));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR,
+ regvals[XT_REG_IDX_AR0 + i + j].buf);
if (debug_dsrs)
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DSR, dsrs[XT_REG_IDX_AR0 + i + j]);
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR,
+ dsrs[XT_REG_IDX_AR0 + i + j].buf);
}
}
- if (xtensa->core_config->windowed) {
+ if (xtensa->core_config->windowed)
/* Now rotate the window so we'll see the next 16 registers. The final rotate
* will wraparound, */
/* leaving us in the state we were. */
- xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(4));
- }
+ xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, 4));
}
+ xtensa_window_state_restore(target, woe);
+
if (xtensa->core_config->coproc) {
- /* As the very first thing after AREGS, go grab the CPENABLE registers. It indicates
- * if we can also grab the FP */
- /* (and theoretically other coprocessor) registers, or if this is a bad thing to do.*/
- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
- xtensa_queue_exec_ins(xtensa, XT_INS_WSR(XT_SR_DDR, XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[XT_REG_IDX_CPENABLE]);
- }
- int res = jtag_execute_queue();
+ /* As the very first thing after AREGS, go grab CPENABLE */
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[XT_REG_IDX_CPENABLE].buf);
+ }
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK) {
LOG_ERROR("Failed to read ARs (%d)!", res);
- return res;
+ goto xtensa_fetch_all_regs_done;
}
xtensa_core_status_check(target);
- if (xtensa->core_config->coproc)
- cpenable = buf_get_u32(regvals[XT_REG_IDX_CPENABLE], 0, 32);
+ a3 = buf_get_u32(a3_buf, 0, 32);
+
+ if (xtensa->core_config->coproc) {
+ cpenable = buf_get_u32(regvals[XT_REG_IDX_CPENABLE].buf, 0, 32);
+
+ /* Enable all coprocessors (by setting all bits in CPENABLE) so we can read FP and user registers. */
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
+
+ /* Save CPENABLE; flag dirty later (when regcache updated) so original value is always restored */
+ LOG_TARGET_DEBUG(target, "CPENABLE: was 0x%" PRIx32 ", all enabled", cpenable);
+ xtensa_reg_set(target, XT_REG_IDX_CPENABLE, cpenable);
+ }
/* We're now free to use any of A0-A15 as scratch registers
* Grab the SFRs and user registers first. We use A3 as a scratch register. */
- for (unsigned int i = 0; i < XT_NUM_REGS; i++) {
- if (xtensa_reg_is_readable(xtensa_regs[i].flags, cpenable) && reg_list[i].exist &&
- (xtensa_regs[i].type == XT_REG_SPECIAL ||
- xtensa_regs[i].type == XT_REG_USER || xtensa_regs[i].type == XT_REG_FR)) {
- if (xtensa_regs[i].type == XT_REG_USER) {
- xtensa_queue_exec_ins(xtensa, XT_INS_RUR(xtensa_regs[i].reg_num, XT_REG_A3));
- } else if (xtensa_regs[i].type == XT_REG_FR) {
- xtensa_queue_exec_ins(xtensa, XT_INS_RFR(xtensa_regs[i].reg_num, XT_REG_A3));
- } else { /*SFR */
- unsigned int reg_num = xtensa_regs[i].reg_num;
- if (reg_num == XT_PC_REG_NUM_BASE) {
+ for (unsigned int i = 0; i < reg_list_size; i++) {
+ struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
+ unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
+ if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) {
+ bool reg_fetched = true;
+ unsigned int reg_num = rlist[ridx].reg_num;
+ switch (rlist[ridx].type) {
+ case XT_REG_USER:
+ xtensa_queue_exec_ins(xtensa, XT_INS_RUR(xtensa, reg_num, XT_REG_A3));
+ break;
+ case XT_REG_FR:
+ xtensa_queue_exec_ins(xtensa, XT_INS_RFR(xtensa, reg_num, XT_REG_A3));
+ break;
+ case XT_REG_SPECIAL:
+ if (reg_num == XT_PC_REG_NUM_VIRTUAL) {
/* reg number of PC for debug interrupt depends on NDEBUGLEVEL */
- reg_num += xtensa->core_config->debug.irq_level;
+ reg_num = (XT_PC_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);
+ } else if (reg_num == xtensa_regs[XT_REG_IDX_CPENABLE].reg_num) {
+ /* CPENABLE already read/updated; don't re-read */
+ reg_fetched = false;
+ break;
}
- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(reg_num, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3));
+ break;
+ default:
+ reg_fetched = false;
+ }
+ if (reg_fetched) {
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[i].buf);
+ if (debug_dsrs)
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR, dsrs[i].buf);
}
- xtensa_queue_exec_ins(xtensa, XT_INS_WSR(XT_SR_DDR, XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[i]);
- if (debug_dsrs)
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DSR, dsrs[i]);
}
}
/* Ok, send the whole mess to the CPU. */
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK) {
LOG_ERROR("Failed to fetch AR regs!");
- return res;
+ goto xtensa_fetch_all_regs_done;
}
xtensa_core_status_check(target);
if (debug_dsrs) {
/* DSR checking: follows order in which registers are requested. */
- for (unsigned int i = 0; i < XT_NUM_REGS; i++) {
- if (xtensa_reg_is_readable(xtensa_regs[i].flags, cpenable) && reg_list[i].exist &&
- (xtensa_regs[i].type == XT_REG_SPECIAL || xtensa_regs[i].type == XT_REG_USER ||
- xtensa_regs[i].type == XT_REG_FR)) {
- if (buf_get_u32(dsrs[i], 0, 32) & OCDDSR_EXECEXCEPTION) {
- LOG_ERROR("Exception reading %s!", xtensa_regs[i].name);
- return ERROR_FAIL;
+ for (unsigned int i = 0; i < reg_list_size; i++) {
+ struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
+ unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
+ if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist &&
+ (rlist[ridx].type != XT_REG_DEBUG) &&
+ (rlist[ridx].type != XT_REG_RELGEN) &&
+ (rlist[ridx].type != XT_REG_TIE) &&
+ (rlist[ridx].type != XT_REG_OTHER)) {
+ if (buf_get_u32(dsrs[i].buf, 0, 32) & OCDDSR_EXECEXCEPTION) {
+ LOG_ERROR("Exception reading %s!", reg_list[i].name);
+ res = ERROR_FAIL;
+ goto xtensa_fetch_all_regs_done;
}
}
}
}
- if (xtensa->core_config->user_regs_num > 0 && xtensa->core_config->fetch_user_regs) {
- res = xtensa->core_config->fetch_user_regs(target);
- if (res != ERROR_OK)
- return res;
- }
-
- if (xtensa->core_config->windowed) {
+ if (xtensa->core_config->windowed)
/* We need the windowbase to decode the general addresses. */
- windowbase = buf_get_u32(regvals[XT_REG_IDX_WINDOWBASE], 0, 32);
- }
+ windowbase = buf_get_u32(regvals[XT_REG_IDX_WINDOWBASE].buf, 0, 32);
/* Decode the result and update the cache. */
- for (unsigned int i = 0; i < XT_NUM_REGS; i++) {
- if (xtensa_reg_is_readable(xtensa_regs[i].flags, cpenable) && reg_list[i].exist) {
- if (xtensa_regs[i].type == XT_REG_GENERAL) {
- /* TODO: add support for non-windowed configs */
- assert(
- xtensa->core_config->windowed &&
- "Regs fetch is not supported for non-windowed configs!");
+ for (unsigned int i = 0; i < reg_list_size; i++) {
+ struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
+ unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
+ if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) {
+ if ((xtensa->core_config->windowed) && (rlist[ridx].type == XT_REG_GENERAL)) {
/* The 64-value general register set is read from (windowbase) on down.
* We need to get the real register address by subtracting windowbase and
* wrapping around. */
- int realadr = xtensa_canonical_to_windowbase_offset(i, windowbase);
- buf_cpy(regvals[realadr], reg_list[i].value, reg_list[i].size);
- } else if (xtensa_regs[i].type == XT_REG_RELGEN) {
- buf_cpy(regvals[xtensa_regs[i].reg_num], reg_list[i].value, reg_list[i].size);
+ enum xtensa_reg_id realadr = xtensa_canonical_to_windowbase_offset(xtensa, i,
+ windowbase);
+ buf_cpy(regvals[realadr].buf, reg_list[i].value, reg_list[i].size);
+ } else if (rlist[ridx].type == XT_REG_RELGEN) {
+ buf_cpy(regvals[rlist[ridx].reg_num].buf, reg_list[i].value, reg_list[i].size);
+ if (xtensa_extra_debug_log) {
+ xtensa_reg_val_t regval = buf_get_u32(regvals[rlist[ridx].reg_num].buf, 0, 32);
+ LOG_DEBUG("%s = 0x%x", rlist[ridx].name, regval);
+ }
} else {
- buf_cpy(regvals[i], reg_list[i].value, reg_list[i].size);
+ xtensa_reg_val_t regval = buf_get_u32(regvals[i].buf, 0, 32);
+ bool is_dirty = (i == XT_REG_IDX_CPENABLE);
+ if (xtensa_extra_debug_log)
+ LOG_INFO("Register %s: 0x%X", reg_list[i].name, regval);
+ xtensa_reg_set(target, i, regval);
+ reg_list[i].dirty = is_dirty; /*always do this _after_ xtensa_reg_set! */
}
reg_list[i].valid = true;
} else {
- reg_list[i].valid = false;
- }
- }
- /* We have used A3 as a scratch register and we will need to write that back. */
- xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
- xtensa->regs_fetched = true;
-
- return ERROR_OK;
-}
-
-int xtensa_fetch_user_regs_u32(struct target *target)
-{
- struct xtensa *xtensa = target_to_xtensa(target);
- struct reg *reg_list = xtensa->core_cache->reg_list;
- xtensa_reg_val_t cpenable = 0;
- uint8_t regvals[XT_USER_REGS_NUM_MAX][sizeof(xtensa_reg_val_t)];
- uint8_t dsrs[XT_USER_REGS_NUM_MAX][sizeof(xtensa_dsr_t)];
- bool debug_dsrs = !xtensa->regs_fetched || LOG_LEVEL_IS(LOG_LVL_DEBUG);
-
- assert(xtensa->core_config->user_regs_num < XT_USER_REGS_NUM_MAX && "Too many user regs configured!");
- if (xtensa->core_config->coproc)
- cpenable = xtensa_reg_get(target, XT_REG_IDX_CPENABLE);
-
- for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) {
- if (!xtensa_reg_is_readable(xtensa->core_config->user_regs[i].flags, cpenable))
- continue;
- xtensa_queue_exec_ins(xtensa, XT_INS_RUR(xtensa->core_config->user_regs[i].reg_num, XT_REG_A3));
- xtensa_queue_exec_ins(xtensa, XT_INS_WSR(XT_SR_DDR, XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[i]);
- if (debug_dsrs)
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DSR, dsrs[i]);
- }
- /* Ok, send the whole mess to the CPU. */
- int res = jtag_execute_queue();
- if (res != ERROR_OK) {
- LOG_ERROR("Failed to fetch AR regs!");
- return res;
- }
- xtensa_core_status_check(target);
-
- if (debug_dsrs) {
- /* DSR checking: follows order in which registers are requested. */
- for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) {
- if (!xtensa_reg_is_readable(xtensa->core_config->user_regs[i].flags, cpenable))
- continue;
- if (buf_get_u32(dsrs[i], 0, 32) & OCDDSR_EXECEXCEPTION) {
- LOG_ERROR("Exception reading %s!", xtensa->core_config->user_regs[i].name);
- return ERROR_FAIL;
+ if ((rlist[ridx].flags & XT_REGF_MASK) == XT_REGF_NOREAD) {
+ /* Report read-only registers all-zero but valid */
+ reg_list[i].valid = true;
+ xtensa_reg_set(target, i, 0);
+ } else {
+ reg_list[i].valid = false;
}
}
}
- for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) {
- if (xtensa_reg_is_readable(xtensa->core_config->user_regs[i].flags, cpenable)) {
- buf_cpy(regvals[i], reg_list[XT_USR_REG_START + i].value, reg_list[XT_USR_REG_START + i].size);
- reg_list[XT_USR_REG_START + i].valid = true;
- } else {
- reg_list[XT_USR_REG_START + i].valid = false;
- }
- }
-
- /* We have used A3 as a scratch register and we will need to write that back. */
+ if (xtensa->core_config->windowed) {
+ /* We have used A3 as a scratch register.
+ * Windowed configs: restore A3's AR (XT_REG_GENERAL) and and flag for write-back.
+ */
+ enum xtensa_reg_id ar3_idx = xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_A3, windowbase);
+ xtensa_reg_set(target, ar3_idx, a3);
+ xtensa_mark_register_dirty(xtensa, ar3_idx);
+
+ /* Reset scratch_ars[] on fetch. .chrval tracks AR mapping and changes w/ window */
+ sprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR3].chrval, "ar%d", ar3_idx - XT_REG_IDX_AR0);
+ enum xtensa_reg_id ar4_idx = xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_A4, windowbase);
+ sprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR4].chrval, "ar%d", ar4_idx - XT_REG_IDX_AR0);
+ for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)
+ xtensa->scratch_ars[s].intval = false;
+ }
+
+ /* We have used A3 (XT_REG_RELGEN) as a scratch register. Restore and flag for write-back. */
+ xtensa_reg_set(target, XT_REG_IDX_A3, a3);
xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
- return ERROR_OK;
+ xtensa->regs_fetched = true;
+xtensa_fetch_all_regs_done:
+ free(regvals);
+ free(dsrs);
+ return res;
}
int xtensa_get_gdb_reg_list(struct target *target,
@@ -1153,23 +1227,65 @@ int xtensa_get_gdb_reg_list(struct target *target,
enum target_register_class reg_class)
{
struct xtensa *xtensa = target_to_xtensa(target);
- unsigned int num_regs = xtensa->core_config->gdb_general_regs_num;
+ unsigned int num_regs;
- if (reg_class == REG_CLASS_ALL)
- num_regs = xtensa->regs_num;
+ if (reg_class == REG_CLASS_GENERAL) {
+ if ((xtensa->genpkt_regs_num == 0) || !xtensa->contiguous_regs_list) {
+ LOG_ERROR("reg_class %d unhandled; 'xtgregs' not found", reg_class);
+ return ERROR_FAIL;
+ }
+ num_regs = xtensa->genpkt_regs_num;
+ } else {
+ /* Determine whether to return a contiguous or sparse register map */
+ num_regs = xtensa->regmap_contiguous ? xtensa->total_regs_num : xtensa->dbregs_num;
+ }
- LOG_DEBUG("reg_class=%i, num_regs=%d", reg_class, num_regs);
+ LOG_DEBUG("reg_class=%i, num_regs=%d", (int)reg_class, num_regs);
- *reg_list = malloc(num_regs * sizeof(struct reg *));
+ *reg_list = calloc(num_regs, sizeof(struct reg *));
if (!*reg_list)
return ERROR_FAIL;
- for (unsigned int k = 0; k < num_regs; k++) {
- unsigned int reg_id = xtensa->core_config->gdb_regs_mapping[k];
- (*reg_list)[k] = &xtensa->core_cache->reg_list[reg_id];
+ *reg_list_size = num_regs;
+ if (xtensa->regmap_contiguous) {
+ assert((num_regs <= xtensa->total_regs_num) && "contiguous regmap size internal error!");
+ for (unsigned int i = 0; i < num_regs; i++)
+ (*reg_list)[i] = xtensa->contiguous_regs_list[i];
+ return ERROR_OK;
}
- *reg_list_size = num_regs;
+ for (unsigned int i = 0; i < num_regs; i++)
+ (*reg_list)[i] = (struct reg *)&xtensa->empty_regs[i];
+ unsigned int k = 0;
+ for (unsigned int i = 0; i < xtensa->core_cache->num_regs && k < num_regs; i++) {
+ if (xtensa->core_cache->reg_list[i].exist) {
+ struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
+ unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
+ int sparse_idx = rlist[ridx].dbreg_num;
+ if (i == XT_REG_IDX_PS) {
+ if (xtensa->eps_dbglevel_idx == 0) {
+ LOG_ERROR("eps_dbglevel_idx not set\n");
+ return ERROR_FAIL;
+ }
+ (*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx];
+ if (xtensa_extra_debug_log)
+ LOG_DEBUG("SPARSE GDB reg 0x%x getting EPS%d 0x%x",
+ sparse_idx, xtensa->core_config->debug.irq_level,
+ xtensa_reg_get_value((*reg_list)[sparse_idx]));
+ } else if (rlist[ridx].type == XT_REG_RELGEN) {
+ (*reg_list)[sparse_idx - XT_REG_IDX_ARFIRST] = &xtensa->core_cache->reg_list[i];
+ } else {
+ (*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[i];
+ }
+ if (i == XT_REG_IDX_PC)
+ /* Make a duplicate copy of PC for external access */
+ (*reg_list)[XT_PC_DBREG_NUM_BASE] = &xtensa->core_cache->reg_list[i];
+ k++;
+ }
+ }
+
+ if (k == num_regs)
+ LOG_ERROR("SPARSE GDB reg list full (size %d)", k);
return ERROR_OK;
}
@@ -1199,9 +1315,9 @@ int xtensa_halt(struct target *target)
}
LOG_TARGET_DEBUG(target, "Core status 0x%" PRIx32, xtensa_dm_core_status_get(&xtensa->dbg_mod));
if (!xtensa_is_stopped(target)) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRSET, OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK)
LOG_TARGET_ERROR(target, "Failed to set OCDDCR_DEBUGINTERRUPT. Can't halt.");
}
@@ -1233,21 +1349,21 @@ int xtensa_prepare_resume(struct target *target,
if (address && !current) {
xtensa_reg_set(target, XT_REG_IDX_PC, address);
} else {
- xtensa_reg_val_t cause = xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE);
- if (cause & DEBUGCAUSE_DB) {
+ uint32_t cause = xtensa_cause_get(target);
+ LOG_TARGET_DEBUG(target, "DEBUGCAUSE 0x%x (watchpoint %lu) (break %lu)",
+ cause, (cause & DEBUGCAUSE_DB), (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)));
+ if (cause & DEBUGCAUSE_DB)
/* We stopped due to a watchpoint. We can't just resume executing the
* instruction again because */
/* that would trigger the watchpoint again. To fix this, we single-step,
* which ignores watchpoints. */
xtensa_do_step(target, current, address, handle_breakpoints);
- }
- if (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)) {
+ if (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))
/* We stopped due to a break instruction. We can't just resume executing the
* instruction again because */
/* that would trigger the break again. To fix this, we single-step, which
* ignores break. */
xtensa_do_step(target, current, address, handle_breakpoints);
- }
}
/* Write back hw breakpoints. Current FreeRTOS SMP code can set a hw breakpoint on an
@@ -1274,8 +1390,8 @@ int xtensa_do_resume(struct target *target)
LOG_TARGET_DEBUG(target, "start");
- xtensa_queue_exec_ins(xtensa, XT_INS_RFDO);
- int res = jtag_execute_queue();
+ xtensa_queue_exec_ins(xtensa, XT_INS_RFDO(xtensa));
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK) {
LOG_TARGET_ERROR(target, "Failed to exec RFDO %d!", res);
return res;
@@ -1315,18 +1431,19 @@ int xtensa_resume(struct target *target,
static bool xtensa_pc_in_winexc(struct target *target, target_addr_t pc)
{
+ struct xtensa *xtensa = target_to_xtensa(target);
uint8_t insn_buf[XT_ISNS_SZ_MAX];
int err = xtensa_read_buffer(target, pc, sizeof(insn_buf), insn_buf);
if (err != ERROR_OK)
return false;
xtensa_insn_t insn = buf_get_u32(insn_buf, 0, 24);
- xtensa_insn_t masked = insn & XT_INS_L32E_S32E_MASK;
- if (masked == XT_INS_L32E(0, 0, 0) || masked == XT_INS_S32E(0, 0, 0))
+ xtensa_insn_t masked = insn & XT_INS_L32E_S32E_MASK(xtensa);
+ if (masked == XT_INS_L32E(xtensa, 0, 0, 0) || masked == XT_INS_S32E(xtensa, 0, 0, 0))
return true;
- masked = insn & XT_INS_RFWO_RFWU_MASK;
- if (masked == XT_INS_RFWO || masked == XT_INS_RFWU)
+ masked = insn & XT_INS_RFWO_RFWU_MASK(xtensa);
+ if (masked == XT_INS_RFWO(xtensa) || masked == XT_INS_RFWU(xtensa))
return true;
return false;
@@ -1339,7 +1456,8 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
const uint32_t icount_val = -2; /* ICOUNT value to load for 1 step */
xtensa_reg_val_t dbreakc[XT_WATCHPOINTS_NUM_MAX];
xtensa_reg_val_t icountlvl, cause;
- xtensa_reg_val_t oldps, newps, oldpc, cur_pc;
+ xtensa_reg_val_t oldps, oldpc, cur_pc;
+ bool ps_lowered = false;
LOG_TARGET_DEBUG(target, "current=%d, address=" TARGET_ADDR_FMT ", handle_breakpoints=%i",
current, address, handle_breakpoints);
@@ -1349,16 +1467,16 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
return ERROR_TARGET_NOT_HALTED;
}
- if (xtensa->core_config->debug.icount_sz != 32) {
- LOG_TARGET_WARNING(target, "stepping for ICOUNT less then 32 bits is not implemented!");
+ if (xtensa->eps_dbglevel_idx == 0) {
+ LOG_ERROR("eps_dbglevel_idx not set\n");
return ERROR_FAIL;
}
- /* Save old ps/pc */
- oldps = xtensa_reg_get(target, XT_REG_IDX_PS);
+ /* Save old ps (EPS[dbglvl] on LX), pc */
+ oldps = xtensa_reg_get(target, xtensa->eps_dbglevel_idx);
oldpc = xtensa_reg_get(target, XT_REG_IDX_PC);
- cause = xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE);
+ cause = xtensa_cause_get(target);
LOG_TARGET_DEBUG(target, "oldps=%" PRIx32 ", oldpc=%" PRIx32 " dbg_cause=%" PRIx32 " exc_cause=%" PRIx32,
oldps,
oldpc,
@@ -1367,8 +1485,7 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
if (handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))) {
/* handle hard-coded SW breakpoints (e.g. syscalls) */
LOG_TARGET_DEBUG(target, "Increment PC to pass break instruction...");
- xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0); /* so we don't recurse into the same routine */
- xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false;
+ xtensa_cause_clear(target); /* so we don't recurse into the same routine */
/* pretend that we have stepped */
if (cause & DEBUGCAUSE_BI)
xtensa_reg_set(target, XT_REG_IDX_PC, oldpc + 3); /* PC = PC+3 */
@@ -1377,13 +1494,22 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
return ERROR_OK;
}
- /* Xtensa has an ICOUNTLEVEL register which sets the maximum interrupt level at which the
- * instructions are to be counted while stepping.
- * For example, if we need to step by 2 instructions, and an interrupt occurs inbetween,
- * the processor will execute the interrupt, return, and halt after the 2nd instruction.
- * However, sometimes we don't want the interrupt handlers to be executed at all, while
- * stepping through the code. In this case (XT_STEPPING_ISR_OFF), PS.INTLEVEL can be raised
- * to only allow Debug and NMI interrupts.
+ /* Xtensa LX has an ICOUNTLEVEL register which sets the maximum interrupt level
+ * at which the instructions are to be counted while stepping.
+ *
+ * For example, if we need to step by 2 instructions, and an interrupt occurs
+ * in between, the processor will trigger the interrupt and halt after the 2nd
+ * instruction within the interrupt vector and/or handler.
+ *
+ * However, sometimes we don't want the interrupt handlers to be executed at all
+ * while stepping through the code. In this case (XT_STEPPING_ISR_OFF),
+ * ICOUNTLEVEL can be lowered to the executing code's (level + 1) to prevent ISR
+ * code from being counted during stepping. Note that C exception handlers must
+ * run at level 0 and hence will be counted and stepped into, should one occur.
+ *
+ * TODO: Certain instructions should never be single-stepped and should instead
+ * be emulated (per DUG): RSIL >= DBGLEVEL, RSR/WSR [ICOUNT|ICOUNTLEVEL], and
+ * RFI >= DBGLEVEL.
*/
if (xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF) {
if (!xtensa->core_config->high_irq.enabled) {
@@ -1392,18 +1518,11 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
"disabling IRQs while stepping is not implemented w/o high prio IRQs option!");
return ERROR_FAIL;
}
- /* Mask all interrupts below Debug, i.e. PS.INTLEVEL = DEBUGLEVEL - 1 */
- xtensa_reg_val_t temp_ps = (oldps & ~0xF) | (xtensa->core_config->debug.irq_level - 1);
- xtensa_reg_set(target, XT_REG_IDX_PS, temp_ps);
+ /* Update ICOUNTLEVEL accordingly */
+ icountlvl = MIN((oldps & 0xF) + 1, xtensa->core_config->debug.irq_level);
+ } else {
+ icountlvl = xtensa->core_config->debug.irq_level;
}
- /* Regardless of ISRs masking mode we need to count instructions at any CINTLEVEL during step.
- So set `icountlvl` to DEBUGLEVEL.
- If ISRs are masked they are disabled in PS (see above), so having `icountlvl` set to DEBUGLEVEL
- will allow to step through any type of the code, e.g. 'high int level' ISR.
- If ISRs are not masked With `icountlvl` set to DEBUGLEVEL, we can step into any ISR
- which can happen (enabled in PS).
- */
- icountlvl = xtensa->core_config->debug.irq_level;
if (cause & DEBUGCAUSE_DB) {
/* We stopped due to a watchpoint. We can't just resume executing the instruction again because
@@ -1412,21 +1531,27 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
LOG_TARGET_DEBUG(
target,
"Single-stepping to get past instruction that triggered the watchpoint...");
- xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0); /*so we don't recurse into
- * the same routine */
- xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false;
- /*Save all DBREAKCx registers and set to 0 to disable watchpoints */
+ xtensa_cause_clear(target); /* so we don't recurse into the same routine */
+ /* Save all DBREAKCx registers and set to 0 to disable watchpoints */
for (unsigned int slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {
dbreakc[slot] = xtensa_reg_get(target, XT_REG_IDX_DBREAKC0 + slot);
xtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, 0);
}
}
- if (!handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))) {
+ if (!handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)))
/* handle normal SW breakpoint */
- xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0); /*so we don't recurse into
- * the same routine */
- xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false;
+ xtensa_cause_clear(target); /* so we don't recurse into the same routine */
+ if ((oldps & 0xf) >= icountlvl) {
+ /* Lower interrupt level to allow stepping, but flag eps[dbglvl] to be restored */
+ ps_lowered = true;
+ uint32_t newps = (oldps & ~0xf) | (icountlvl - 1);
+ xtensa_reg_set(target, xtensa->eps_dbglevel_idx, newps);
+ LOG_TARGET_DEBUG(target,
+ "Lowering PS.INTLEVEL to allow stepping: %s <- 0x%08" PRIx32 " (was 0x%08" PRIx32 ")",
+ xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name,
+ newps,
+ oldps);
}
do {
xtensa_reg_set(target, XT_REG_IDX_ICOUNTLEVEL, icountlvl);
@@ -1470,18 +1595,15 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
target->state = TARGET_RUNNING;
return ERROR_FAIL;
}
- target->debug_reason = DBG_REASON_SINGLESTEP;
- target->state = TARGET_HALTED;
xtensa_fetch_all_regs(target);
-
cur_pc = xtensa_reg_get(target, XT_REG_IDX_PC);
LOG_TARGET_DEBUG(target,
"cur_ps=%" PRIx32 ", cur_pc=%" PRIx32 " dbg_cause=%" PRIx32 " exc_cause=%" PRIx32,
xtensa_reg_get(target, XT_REG_IDX_PS),
cur_pc,
- xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE),
+ xtensa_cause_get(target),
xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE));
/* Do not step into WindowOverflow if ISRs are masked.
@@ -1504,6 +1626,10 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
LOG_DEBUG("Stepped from %" PRIX32 " to %" PRIX32, oldpc, cur_pc);
break;
} while (true);
+
+ 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) {
@@ -1514,12 +1640,11 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
}
/* Restore int level */
- /* TODO: Theoretically, this can mess up stepping over an instruction that modifies
- * ps.intlevel by itself. TODO: Look into this. */
- if (xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF) {
- newps = xtensa_reg_get(target, XT_REG_IDX_PS);
- newps = (newps & ~0xF) | (oldps & 0xf);
- xtensa_reg_set(target, XT_REG_IDX_PS, newps);
+ if (ps_lowered) {
+ LOG_DEBUG("Restoring %s after stepping: 0x%08" PRIx32,
+ xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name,
+ oldps);
+ xtensa_reg_set(target, xtensa->eps_dbglevel_idx, oldps);
}
/* write ICOUNTLEVEL back to zero */
@@ -1567,7 +1692,7 @@ static inline target_addr_t xtensa_get_overlap_size(target_addr_t r1_start,
}
/**
- * Check if the address gets to memory regions, and it's access mode
+ * Check if the address gets to memory regions, and its access mode
*/
static bool xtensa_memory_op_validate_range(struct xtensa *xtensa, target_addr_t address, size_t size, int access)
{
@@ -1598,6 +1723,7 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si
target_addr_t addrend_al = ALIGN_UP(address + size * count, 4);
target_addr_t adr = addrstart_al;
uint8_t *albuff;
+ bool bswap = xtensa->target->endianness == TARGET_BIG_ENDIAN;
if (target->state != TARGET_HALTED) {
LOG_TARGET_WARNING(target, "target not halted");
@@ -1612,39 +1738,62 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si
}
}
- if (addrstart_al == address && addrend_al == address + (size * count)) {
- albuff = buffer;
- } else {
- albuff = malloc(addrend_al - addrstart_al);
- if (!albuff) {
- LOG_TARGET_ERROR(target, "Out of memory allocating %" TARGET_PRIdADDR " bytes!",
- addrend_al - addrstart_al);
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
+ unsigned int alloc_bytes = ALIGN_UP(addrend_al - addrstart_al, sizeof(uint32_t));
+ albuff = calloc(alloc_bytes, 1);
+ if (!albuff) {
+ LOG_TARGET_ERROR(target, "Out of memory allocating %" PRId64 " bytes!",
+ addrend_al - addrstart_al);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
/* We're going to use A3 here */
xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
/* Write start address to A3 */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrstart_al);
- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
/* Now we can safely read data from addrstart_al up to addrend_al into albuff */
- for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
- xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, &albuff[i]);
+ if (xtensa->probe_lsddr32p != 0) {
+ xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));
+ for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t))
+ xtensa_queue_dbg_reg_read(xtensa,
+ (adr + sizeof(uint32_t) == addrend_al) ? XDMREG_DDR : XDMREG_DDREXEC,
+ &albuff[i]);
+ } else {
+ xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4);
+ for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
+ xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A4, 0));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A4));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[i]);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ }
}
- int res = jtag_execute_queue();
- if (res == ERROR_OK)
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ if (res == ERROR_OK) {
+ bool prev_suppress = xtensa->suppress_dsr_errors;
+ xtensa->suppress_dsr_errors = true;
res = xtensa_core_status_check(target);
- if (res != ERROR_OK)
- LOG_TARGET_WARNING(target, "Failed reading %d bytes at address " TARGET_ADDR_FMT,
- count * size, address);
-
- if (albuff != buffer) {
- memcpy(buffer, albuff + (address & 3), (size * count));
- free(albuff);
+ if (xtensa->probe_lsddr32p == -1)
+ xtensa->probe_lsddr32p = 1;
+ xtensa->suppress_dsr_errors = prev_suppress;
+ }
+ 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");
+ xtensa->probe_lsddr32p = 0;
+ res = xtensa_read_memory(target, address, size, count, buffer);
+ bswap = false;
+ } else {
+ LOG_TARGET_WARNING(target, "Failed reading %d bytes at address "TARGET_ADDR_FMT,
+ count * size, address);
+ }
}
+ if (bswap)
+ buf_bswap32(albuff, albuff, addrend_al - addrstart_al);
+ memcpy(buffer, albuff + (address & 3), (size * count));
+ free(albuff);
return res;
}
@@ -1670,6 +1819,7 @@ int xtensa_write_memory(struct target *target,
target_addr_t adr = addrstart_al;
int res;
uint8_t *albuff;
+ bool fill_head_tail = false;
if (target->state != TARGET_HALTED) {
LOG_TARGET_WARNING(target, "target not halted");
@@ -1688,38 +1838,53 @@ int xtensa_write_memory(struct target *target,
/* Allocate a temporary buffer to put the aligned bytes in, if needed. */
if (addrstart_al == address && addrend_al == address + (size * count)) {
- /* We discard the const here because albuff can also be non-const */
- albuff = (uint8_t *)buffer;
+ if (xtensa->target->endianness == TARGET_BIG_ENDIAN)
+ /* Need a buffer for byte-swapping */
+ albuff = malloc(addrend_al - addrstart_al);
+ else
+ /* We discard the const here because albuff can also be non-const */
+ albuff = (uint8_t *)buffer;
} else {
+ fill_head_tail = true;
albuff = malloc(addrend_al - addrstart_al);
- if (!albuff) {
- LOG_TARGET_ERROR(target, "Out of memory allocating %" TARGET_PRIdADDR " bytes!",
- addrend_al - addrstart_al);
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
+ }
+ if (!albuff) {
+ LOG_TARGET_ERROR(target, "Out of memory allocating %" PRId64 " bytes!",
+ addrend_al - addrstart_al);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
/* We're going to use A3 here */
xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
/* If we're using a temp aligned buffer, we need to fill the head and/or tail bit of it. */
- if (albuff != buffer) {
+ if (fill_head_tail) {
/* See if we need to read the first and/or last word. */
if (address & 3) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrstart_al);
- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3));
- xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, &albuff[0]);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ if (xtensa->probe_lsddr32p == 1) {
+ xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));
+ } else {
+ xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ }
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[0]);
}
if ((address + (size * count)) & 3) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrend_al - 4);
- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3));
- xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR,
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrend_al - 4);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ if (xtensa->probe_lsddr32p == 1) {
+ xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));
+ } else {
+ xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ }
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR,
&albuff[addrend_al - addrstart_al - 4]);
}
/* Grab bytes */
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK) {
LOG_ERROR("Error issuing unaligned memory write context instruction(s): %d", res);
if (albuff != buffer)
@@ -1727,24 +1892,110 @@ int xtensa_write_memory(struct target *target,
return res;
}
xtensa_core_status_check(target);
- /* Copy data to be written into the aligned buffer */
+ if (xtensa->target->endianness == TARGET_BIG_ENDIAN) {
+ bool swapped_w0 = false;
+ if (address & 3) {
+ buf_bswap32(&albuff[0], &albuff[0], 4);
+ swapped_w0 = true;
+ }
+ if ((address + (size * count)) & 3) {
+ if ((addrend_al - addrstart_al - 4 == 0) && swapped_w0) {
+ /* Don't double-swap if buffer start/end are within the same word */
+ } else {
+ buf_bswap32(&albuff[addrend_al - addrstart_al - 4],
+ &albuff[addrend_al - addrstart_al - 4], 4);
+ }
+ }
+ }
+ /* Copy data to be written into the aligned buffer (in host-endianness) */
memcpy(&albuff[address & 3], buffer, size * count);
/* Now we can write albuff in aligned uint32s. */
}
+ if (xtensa->target->endianness == TARGET_BIG_ENDIAN)
+ buf_bswap32(albuff, fill_head_tail ? albuff : buffer, addrend_al - addrstart_al);
+
/* Write start address to A3 */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrstart_al);
- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
/* Write the aligned buffer */
- for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, buf_get_u32(&albuff[i], 0, 32));
- xtensa_queue_exec_ins(xtensa, XT_INS_SDDR32P(XT_REG_A3));
+ if (xtensa->probe_lsddr32p != 0) {
+ for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
+ if (i == 0) {
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32));
+ xtensa_queue_exec_ins(xtensa, XT_INS_SDDR32P(xtensa, XT_REG_A3));
+ } else {
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDREXEC, buf_get_u32(&albuff[i], 0, 32));
+ }
+ }
+ } else {
+ xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4);
+ for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32));
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));
+ xtensa_queue_exec_ins(xtensa, XT_INS_S32I(xtensa, XT_REG_A3, XT_REG_A4, 0));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ }
}
- res = jtag_execute_queue();
- if (res == ERROR_OK)
+
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ if (res == ERROR_OK) {
+ bool prev_suppress = xtensa->suppress_dsr_errors;
+ xtensa->suppress_dsr_errors = true;
res = xtensa_core_status_check(target);
- if (res != ERROR_OK)
- LOG_TARGET_WARNING(target, "Failed writing %d bytes at address " TARGET_ADDR_FMT, count * size, address);
+ if (xtensa->probe_lsddr32p == -1)
+ xtensa->probe_lsddr32p = 1;
+ xtensa->suppress_dsr_errors = prev_suppress;
+ }
+ 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");
+ xtensa->probe_lsddr32p = 0;
+ res = xtensa_write_memory(target, address, size, count, buffer);
+ } else {
+ LOG_TARGET_WARNING(target, "Failed writing %d bytes at address "TARGET_ADDR_FMT,
+ count * size, address);
+ }
+ } else {
+ /* Invalidate ICACHE, writeback DCACHE if present */
+ uint32_t issue_ihi = xtensa_is_icacheable(xtensa, address);
+ uint32_t issue_dhwb = xtensa_is_dcacheable(xtensa, address);
+ if (issue_ihi || issue_dhwb) {
+ uint32_t ilinesize = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
+ uint32_t dlinesize = issue_dhwb ? xtensa->core_config->dcache.line_size : UINT32_MAX;
+ uint32_t linesize = MIN(ilinesize, dlinesize);
+ uint32_t off = 0;
+ adr = addrstart_al;
+
+ while ((adr + off) < addrend_al) {
+ if (off == 0) {
+ /* Write start address to A3 */
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ }
+ if (issue_ihi)
+ xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, off));
+ if (issue_dhwb)
+ xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, off));
+ off += linesize;
+ if (off > 1020) {
+ /* IHI, DHWB have 8-bit immediate operands (0..1020) */
+ adr += off;
+ off = 0;
+ }
+ }
+
+ /* Execute cache WB/INV instructions */
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ xtensa_core_status_check(target);
+ if (res != ERROR_OK)
+ LOG_TARGET_ERROR(target,
+ "Error issuing cache writeback/invaldate instruction(s): %d",
+ res);
+ }
+ }
if (albuff != buffer)
free(albuff);
@@ -1766,8 +2017,18 @@ int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_
int xtensa_poll(struct target *target)
{
struct xtensa *xtensa = target_to_xtensa(target);
+ if (xtensa_dm_poll(&xtensa->dbg_mod) != ERROR_OK) {
+ target->state = TARGET_UNKNOWN;
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
- int res = xtensa_dm_power_status_read(&xtensa->dbg_mod, PWRSTAT_DEBUGWASRESET | PWRSTAT_COREWASRESET);
+ int res = xtensa_dm_power_status_read(&xtensa->dbg_mod, PWRSTAT_DEBUGWASRESET(xtensa) |
+ PWRSTAT_COREWASRESET(xtensa));
+ if (xtensa->dbg_mod.power_status.stat != xtensa->dbg_mod.power_status.stath)
+ LOG_TARGET_DEBUG(target, "PWRSTAT: read 0x%08" PRIx32 ", clear 0x%08lx, reread 0x%08" PRIx32,
+ xtensa->dbg_mod.power_status.stat,
+ PWRSTAT_DEBUGWASRESET(xtensa) | PWRSTAT_COREWASRESET(xtensa),
+ xtensa->dbg_mod.power_status.stath);
if (res != ERROR_OK)
return res;
@@ -1785,10 +2046,16 @@ int xtensa_poll(struct target *target)
if (res != ERROR_OK)
return res;
+ uint32_t prev_dsr = xtensa->dbg_mod.core_status.dsr;
res = xtensa_dm_core_status_read(&xtensa->dbg_mod);
if (res != ERROR_OK)
return res;
- if (xtensa->dbg_mod.power_status.stath & PWRSTAT_COREWASRESET) {
+ if (prev_dsr != xtensa->dbg_mod.core_status.dsr)
+ LOG_TARGET_DEBUG(target,
+ "DSR has changed: was 0x%08" PRIx32 " now 0x%08" PRIx32,
+ prev_dsr,
+ xtensa->dbg_mod.core_status.dsr);
+ if (xtensa->dbg_mod.power_status.stath & PWRSTAT_COREWASRESET(xtensa)) {
/* if RESET state is persitent */
target->state = TARGET_RESET;
} else if (!xtensa_dm_is_powered(&xtensa->dbg_mod)) {
@@ -1811,7 +2078,7 @@ int xtensa_poll(struct target *target)
* priorities: watchpoint == breakpoint > single step > debug interrupt. */
/* Watchpoint and breakpoint events at the same time results in special
* debug reason: DBG_REASON_WPTANDBKPT. */
- xtensa_reg_val_t halt_cause = xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE);
+ uint32_t halt_cause = xtensa_cause_get(target);
/* TODO: Add handling of DBG_REASON_EXC_CATCH */
if (halt_cause & DEBUGCAUSE_IC)
target->debug_reason = DBG_REASON_SINGLESTEP;
@@ -1823,7 +2090,8 @@ int xtensa_poll(struct target *target)
} else if (halt_cause & DEBUGCAUSE_DB) {
target->debug_reason = DBG_REASON_WATCHPOINT;
}
- LOG_TARGET_DEBUG(target, "Target halted, pc=0x%08" PRIX32 ", debug_reason=%08x, oldstate=%08x",
+ LOG_TARGET_DEBUG(target, "Target halted, pc=0x%08" PRIx32
+ ", debug_reason=%08" PRIx32 ", oldstate=%08" PRIx32,
xtensa_reg_get(target, XT_REG_IDX_PC),
target->debug_reason,
oldstate);
@@ -1831,8 +2099,6 @@ int xtensa_poll(struct target *target)
halt_cause,
xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE),
xtensa->dbg_mod.core_status.dsr);
- LOG_TARGET_INFO(target, "Target halted, PC=0x%08" PRIX32 ", debug_reason=%08x",
- xtensa_reg_get(target, XT_REG_IDX_PC), target->debug_reason);
xtensa_dm_core_status_clear(
&xtensa->dbg_mod,
OCDDSR_DEBUGPENDBREAK | OCDDSR_DEBUGINTBREAK | OCDDSR_DEBUGPENDTRAX |
@@ -1866,25 +2132,101 @@ int xtensa_poll(struct target *target)
return ERROR_OK;
}
+static int xtensa_update_instruction(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ unsigned int issue_ihi = xtensa_is_icacheable(xtensa, address);
+ unsigned int issue_dhwbi = xtensa_is_dcacheable(xtensa, address);
+ uint32_t icache_line_size = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
+ uint32_t dcache_line_size = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX;
+ unsigned int same_ic_line = ((address & (icache_line_size - 1)) + size) <= icache_line_size;
+ unsigned int same_dc_line = ((address & (dcache_line_size - 1)) + size) <= dcache_line_size;
+ int ret;
+
+ if (size > icache_line_size)
+ return ERROR_FAIL;
+
+ if (issue_ihi || issue_dhwbi) {
+ /* We're going to use A3 here */
+ xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
+
+ /* Write start address to A3 and invalidate */
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ LOG_TARGET_DEBUG(target, "DHWBI, IHI for address "TARGET_ADDR_FMT, address);
+ if (issue_dhwbi) {
+ xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 0));
+ if (!same_dc_line) {
+ LOG_TARGET_DEBUG(target,
+ "DHWBI second dcache line for address "TARGET_ADDR_FMT,
+ address + 4);
+ xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 4));
+ }
+ }
+ if (issue_ihi) {
+ xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, 0));
+ if (!same_ic_line) {
+ LOG_TARGET_DEBUG(target,
+ "IHI second icache line for address "TARGET_ADDR_FMT,
+ address + 4);
+ xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, 4));
+ }
+ }
+
+ /* Execute invalidate instructions */
+ ret = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ xtensa_core_status_check(target);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Error issuing cache invaldate instruction(s): %d", ret);
+ return ret;
+ }
+ }
+
+ /* Write new instructions to memory */
+ ret = target_write_buffer(target, address, size, buffer);
+ if (ret != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "Error writing instruction to memory: %d", ret);
+ return ret;
+ }
+
+ if (issue_dhwbi) {
+ /* Flush dcache so instruction propagates. A3 may be corrupted during memory write */
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_DHWB(xtensa, XT_REG_A3, 0));
+ LOG_DEBUG("DHWB dcache line for address "TARGET_ADDR_FMT, address);
+ if (!same_dc_line) {
+ LOG_TARGET_DEBUG(target, "DHWB second dcache line for address "TARGET_ADDR_FMT, address + 4);
+ xtensa_queue_exec_ins(xtensa, XT_INS_DHWB(xtensa, XT_REG_A3, 4));
+ }
+
+ /* Execute invalidate instructions */
+ ret = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ xtensa_core_status_check(target);
+ }
+
+ /* TODO: Handle L2 cache if present */
+ return ret;
+}
+
static int xtensa_sw_breakpoint_add(struct target *target,
struct breakpoint *breakpoint,
struct xtensa_sw_breakpoint *sw_bp)
{
+ struct xtensa *xtensa = target_to_xtensa(target);
int ret = target_read_buffer(target, breakpoint->address, XT_ISNS_SZ_MAX, sw_bp->insn);
if (ret != ERROR_OK) {
LOG_TARGET_ERROR(target, "Failed to read original instruction (%d)!", ret);
return ret;
}
- sw_bp->insn_sz = xtensa_insn_size_get(buf_get_u32(sw_bp->insn, 0, 24));
+ sw_bp->insn_sz = MIN(XT_ISNS_SZ_MAX, breakpoint->length);
sw_bp->oocd_bp = breakpoint;
- uint32_t break_insn = sw_bp->insn_sz == XT_ISNS_SZ_MAX ? XT_INS_BREAK(0, 0) : XT_INS_BREAKN(0);
- /* convert to target endianness */
- uint8_t break_insn_buff[4];
- target_buffer_set_u32(target, break_insn_buff, break_insn);
+ uint32_t break_insn = sw_bp->insn_sz == XT_ISNS_SZ_MAX ? XT_INS_BREAK(xtensa, 0, 0) : XT_INS_BREAKN(xtensa, 0);
- ret = target_write_buffer(target, breakpoint->address, sw_bp->insn_sz, break_insn_buff);
+ /* Underlying memory write will convert instruction endianness, don't do that here */
+ ret = xtensa_update_instruction(target, breakpoint->address, sw_bp->insn_sz, (uint8_t *)&break_insn);
if (ret != ERROR_OK) {
LOG_TARGET_ERROR(target, "Failed to write breakpoint instruction (%d)!", ret);
return ret;
@@ -1895,9 +2237,9 @@ static int xtensa_sw_breakpoint_add(struct target *target,
static int xtensa_sw_breakpoint_remove(struct target *target, struct xtensa_sw_breakpoint *sw_bp)
{
- int ret = target_write_buffer(target, sw_bp->oocd_bp->address, sw_bp->insn_sz, sw_bp->insn);
+ int ret = xtensa_update_instruction(target, sw_bp->oocd_bp->address, sw_bp->insn_sz, sw_bp->insn);
if (ret != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Failed to read insn (%d)!", ret);
+ LOG_TARGET_ERROR(target, "Failed to write insn (%d)!", ret);
return ret;
}
sw_bp->oocd_bp = NULL;
@@ -1941,7 +2283,8 @@ int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint)
xtensa->hw_brps[slot] = breakpoint;
/* We will actually write the breakpoints when we resume the target. */
- LOG_TARGET_DEBUG(target, "placed HW breakpoint @ " TARGET_ADDR_FMT,
+ LOG_TARGET_DEBUG(target, "placed HW breakpoint %u @ " TARGET_ADDR_FMT,
+ slot,
breakpoint->address);
return ERROR_OK;
@@ -2063,6 +2406,12 @@ static int xtensa_build_reg_cache(struct target *target)
{
struct xtensa *xtensa = target_to_xtensa(target);
struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
+ unsigned int last_dbreg_num = 0;
+
+ if (xtensa->core_regs_num + xtensa->num_optregs != xtensa->total_regs_num)
+ LOG_TARGET_WARNING(target, "Register count MISMATCH: %d core regs, %d extended regs; %d expected",
+ xtensa->core_regs_num, xtensa->num_optregs, xtensa->total_regs_num);
+
struct reg_cache *reg_cache = calloc(1, sizeof(struct reg_cache));
if (!reg_cache) {
@@ -2071,86 +2420,101 @@ static int xtensa_build_reg_cache(struct target *target)
}
reg_cache->name = "Xtensa registers";
reg_cache->next = NULL;
- reg_cache->num_regs = XT_NUM_REGS + xtensa->core_config->user_regs_num;
/* Init reglist */
- struct reg *reg_list = calloc(reg_cache->num_regs, sizeof(struct reg));
+ unsigned int reg_list_size = XT_NUM_REGS + xtensa->num_optregs;
+ struct reg *reg_list = calloc(reg_list_size, sizeof(struct reg));
if (!reg_list) {
LOG_ERROR("Failed to alloc reg list!");
goto fail;
}
- xtensa->regs_num = 0;
-
- for (unsigned int i = 0; i < XT_NUM_REGS; i++) {
- reg_list[i].exist = false;
- if (xtensa_regs[i].type == XT_REG_USER) {
- if (xtensa_user_reg_exists(xtensa, i))
- reg_list[i].exist = true;
- else
- LOG_DEBUG("User reg '%s' (%d) does not exist", xtensa_regs[i].name, i);
- } else if (xtensa_regs[i].type == XT_REG_FR) {
- if (xtensa_fp_reg_exists(xtensa, i))
- reg_list[i].exist = true;
- else
- LOG_DEBUG("FP reg '%s' (%d) does not exist", xtensa_regs[i].name, i);
- } else if (xtensa_regs[i].type == XT_REG_SPECIAL) {
- if (xtensa_special_reg_exists(xtensa, i))
- reg_list[i].exist = true;
- else
- LOG_DEBUG("Special reg '%s' (%d) does not exist", xtensa_regs[i].name, i);
- } else {
- if (xtensa_regular_reg_exists(xtensa, i))
- reg_list[i].exist = true;
- else
- LOG_DEBUG("Regular reg '%s' (%d) does not exist", xtensa_regs[i].name, i);
- }
- reg_list[i].name = xtensa_regs[i].name;
- reg_list[i].size = 32;
- reg_list[i].value = calloc(1, 4 /*XT_REG_LEN*/);/* make Clang Static Analyzer happy */
- if (!reg_list[i].value) {
- LOG_ERROR("Failed to alloc reg list value!");
+ xtensa->dbregs_num = 0;
+ unsigned int didx = 0;
+ for (unsigned int whichlist = 0; whichlist < 2; whichlist++) {
+ struct xtensa_reg_desc *rlist = (whichlist == 0) ? xtensa_regs : xtensa->optregs;
+ unsigned int listsize = (whichlist == 0) ? XT_NUM_REGS : xtensa->num_optregs;
+ for (unsigned int i = 0; i < listsize; i++, didx++) {
+ reg_list[didx].exist = rlist[i].exist;
+ reg_list[didx].name = rlist[i].name;
+ reg_list[didx].size = 32;
+ reg_list[didx].value = calloc(1, 4 /*XT_REG_LEN*/); /* make Clang Static Analyzer happy */
+ if (!reg_list[didx].value) {
+ LOG_ERROR("Failed to alloc reg list value!");
+ goto fail;
+ }
+ reg_list[didx].dirty = false;
+ reg_list[didx].valid = false;
+ reg_list[didx].type = &xtensa_reg_type;
+ reg_list[didx].arch_info = xtensa;
+ if (rlist[i].exist && (rlist[i].dbreg_num > last_dbreg_num))
+ last_dbreg_num = rlist[i].dbreg_num;
+
+ if (xtensa_extra_debug_log) {
+ LOG_TARGET_DEBUG(target,
+ "POPULATE %-16s list %d exist %d, idx %d, type %d, dbreg_num 0x%04x",
+ reg_list[didx].name,
+ whichlist,
+ reg_list[didx].exist,
+ didx,
+ rlist[i].type,
+ rlist[i].dbreg_num);
+ }
+ }
+ }
+
+ xtensa->dbregs_num = last_dbreg_num + 1;
+ reg_cache->reg_list = reg_list;
+ reg_cache->num_regs = reg_list_size;
+
+ LOG_TARGET_DEBUG(target, "xtensa->total_regs_num %d reg_list_size %d xtensa->dbregs_num %d",
+ xtensa->total_regs_num, reg_list_size, xtensa->dbregs_num);
+
+ /* Construct empty-register list for handling unknown register requests */
+ xtensa->empty_regs = calloc(xtensa->dbregs_num, sizeof(struct reg));
+ if (!xtensa->empty_regs) {
+ LOG_TARGET_ERROR(target, "ERROR: Out of memory");
+ goto fail;
+ }
+ for (unsigned int i = 0; i < xtensa->dbregs_num; i++) {
+ xtensa->empty_regs[i].name = calloc(8, sizeof(char));
+ if (!xtensa->empty_regs[i].name) {
+ LOG_TARGET_ERROR(target, "ERROR: Out of memory");
goto fail;
}
- reg_list[i].dirty = false;
- reg_list[i].valid = false;
- reg_list[i].type = &xtensa_reg_type;
- reg_list[i].arch_info = xtensa;
- if (reg_list[i].exist)
- xtensa->regs_num++;
- }
- for (unsigned int i = 0; i < xtensa->core_config->user_regs_num; i++) {
- reg_list[XT_USR_REG_START + i].exist = true;
- reg_list[XT_USR_REG_START + i].name = xtensa->core_config->user_regs[i].name;
- reg_list[XT_USR_REG_START + i].size = xtensa->core_config->user_regs[i].size;
- reg_list[XT_USR_REG_START + i].value = calloc(1, reg_list[XT_USR_REG_START + i].size / 8);
- if (!reg_list[XT_USR_REG_START + i].value) {
- LOG_ERROR("Failed to alloc user reg list value!");
+ sprintf((char *)xtensa->empty_regs[i].name, "?0x%04x", i & 0x0000FFFF);
+ xtensa->empty_regs[i].size = 32;
+ xtensa->empty_regs[i].type = &xtensa_reg_type;
+ xtensa->empty_regs[i].value = calloc(1, 4 /*XT_REG_LEN*/); /* make Clang Static Analyzer happy */
+ if (!xtensa->empty_regs[i].value) {
+ LOG_ERROR("Failed to alloc empty reg list value!");
goto fail;
}
- reg_list[XT_USR_REG_START + i].dirty = false;
- reg_list[XT_USR_REG_START + i].valid = false;
- reg_list[XT_USR_REG_START + i].type = xtensa->core_config->user_regs[i].type;
- reg_list[XT_USR_REG_START + i].arch_info = xtensa;
- xtensa->regs_num++;
- }
- if (xtensa->core_config->gdb_general_regs_num >= xtensa->regs_num) {
- LOG_ERROR("Regs number less then GDB general regs number!");
- goto fail;
+ xtensa->empty_regs[i].arch_info = xtensa;
}
- /* assign GDB reg numbers to registers */
- for (unsigned int gdb_reg_id = 0; gdb_reg_id < xtensa->regs_num; gdb_reg_id++) {
- unsigned int reg_id = xtensa->core_config->gdb_regs_mapping[gdb_reg_id];
- if (reg_id >= reg_cache->num_regs) {
- LOG_ERROR("Invalid GDB map!");
+ /* Construct contiguous register list from contiguous descriptor list */
+ if (xtensa->regmap_contiguous && xtensa->contiguous_regs_desc) {
+ xtensa->contiguous_regs_list = calloc(xtensa->total_regs_num, sizeof(struct reg *));
+ if (!xtensa->contiguous_regs_list) {
+ LOG_TARGET_ERROR(target, "ERROR: Out of memory");
goto fail;
}
- if (!reg_list[reg_id].exist) {
- LOG_ERROR("Non-existing reg in GDB map!");
- goto fail;
+ for (unsigned int i = 0; i < xtensa->total_regs_num; i++) {
+ 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)) {
+ xtensa->contiguous_regs_list[i] = &(reg_cache->reg_list[j]);
+ LOG_TARGET_DEBUG(target,
+ "POPULATE contiguous regs list: %-16s, dbreg_num 0x%04x",
+ xtensa->contiguous_regs_list[i]->name,
+ xtensa->contiguous_regs_desc[i]->dbreg_num);
+ break;
+ }
+ }
+ if (j == reg_cache->num_regs)
+ LOG_TARGET_WARNING(target, "contiguous register %s not found",
+ xtensa->contiguous_regs_desc[i]->name);
}
- reg_list[reg_id].number = gdb_reg_id;
}
- reg_cache->reg_list = reg_list;
xtensa->algo_context_backup = calloc(reg_cache->num_regs, sizeof(void *));
if (!xtensa->algo_context_backup) {
@@ -2165,7 +2529,6 @@ static int xtensa_build_reg_cache(struct target *target)
goto fail;
}
}
-
xtensa->core_cache = reg_cache;
if (cache_p)
*cache_p = reg_cache;
@@ -2173,10 +2536,17 @@ static int xtensa_build_reg_cache(struct target *target)
fail:
if (reg_list) {
- for (unsigned int i = 0; i < reg_cache->num_regs; i++)
+ for (unsigned int i = 0; i < reg_list_size; i++)
free(reg_list[i].value);
free(reg_list);
}
+ if (xtensa->empty_regs) {
+ for (unsigned int i = 0; i < xtensa->dbregs_num; i++) {
+ free((void *)xtensa->empty_regs[i].name);
+ free(xtensa->empty_regs[i].value);
+ }
+ free(xtensa->empty_regs);
+ }
if (xtensa->algo_context_backup) {
for (unsigned int i = 0; i < reg_cache->num_regs; i++)
free(xtensa->algo_context_backup[i]);
@@ -2187,21 +2557,322 @@ fail:
return ERROR_FAIL;
}
+static int32_t xtensa_gdbqc_parse_exec_tie_ops(struct target *target, char *opstr)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ int32_t status = ERROR_COMMAND_ARGUMENT_INVALID;
+ /* Process op[] list */
+ while (opstr && (*opstr == ':')) {
+ uint8_t ops[32];
+ unsigned int oplen = strtoul(opstr + 1, &opstr, 16);
+ if (oplen > 32) {
+ LOG_TARGET_ERROR(target, "TIE access instruction too long (%d)\n", oplen);
+ break;
+ }
+ unsigned int i = 0;
+ while ((i < oplen) && opstr && (*opstr == ':'))
+ ops[i++] = strtoul(opstr + 1, &opstr, 16);
+ if (i != oplen) {
+ LOG_TARGET_ERROR(target, "TIE access instruction malformed (%d)\n", i);
+ break;
+ }
+
+ char insn_buf[128];
+ sprintf(insn_buf, "Exec %d-byte TIE sequence: ", oplen);
+ for (i = 0; i < oplen; i++)
+ sprintf(insn_buf + strlen(insn_buf), "%02x:", ops[i]);
+ LOG_TARGET_DEBUG(target, "%s", insn_buf);
+ xtensa_queue_exec_ins_wide(xtensa, ops, oplen); /* Handles endian-swap */
+ status = ERROR_OK;
+ }
+ return status;
+}
+
+static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char **response_p)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ bool iswrite = (packet[0] == 'Q');
+ enum xtensa_qerr_e error;
+
+ /* Read/write TIE register. Requires spill location.
+ * qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>]
+ * Qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>]=<value>
+ */
+ if (!(xtensa->spill_buf)) {
+ LOG_ERROR("Spill location not specified. Try 'target remote <host>:3333 &spill_location0'");
+ error = XT_QERR_FAIL;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+
+ char *delim;
+ uint32_t regnum = strtoul(packet + 6, &delim, 16);
+ if (*delim != ':') {
+ LOG_ERROR("Malformed qxtreg packet");
+ error = XT_QERR_INVAL;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+ uint32_t reglen = strtoul(delim + 1, &delim, 16);
+ if (*delim != ':') {
+ LOG_ERROR("Malformed qxtreg packet");
+ error = XT_QERR_INVAL;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+ uint8_t regbuf[XT_QUERYPKT_RESP_MAX];
+ memset(regbuf, 0, XT_QUERYPKT_RESP_MAX);
+ LOG_DEBUG("TIE reg 0x%08" PRIx32 " %s (%d bytes)", regnum, iswrite ? "write" : "read", reglen);
+ if (reglen * 2 + 1 > XT_QUERYPKT_RESP_MAX) {
+ LOG_ERROR("TIE register too large");
+ error = XT_QERR_MEM;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+
+ /* (1) Save spill memory, (1.5) [if write then store value to spill location],
+ * (2) read old a4, (3) write spill address to a4.
+ * NOTE: ensure a4 is restored properly by all error handling logic
+ */
+ unsigned int memop_size = (xtensa->spill_loc & 3) ? 1 : 4;
+ int status = xtensa_read_memory(target, xtensa->spill_loc, memop_size,
+ xtensa->spill_bytes / memop_size, xtensa->spill_buf);
+ if (status != ERROR_OK) {
+ LOG_ERROR("Spill memory save");
+ error = XT_QERR_MEM;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+ if (iswrite) {
+ /* Extract value and store in spill memory */
+ unsigned int b = 0;
+ char *valbuf = strchr(delim, '=');
+ if (!(valbuf && (*valbuf == '='))) {
+ LOG_ERROR("Malformed Qxtreg packet");
+ error = XT_QERR_INVAL;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+ valbuf++;
+ while (*valbuf && *(valbuf + 1)) {
+ char bytestr[3] = { 0, 0, 0 };
+ strncpy(bytestr, valbuf, 2);
+ regbuf[b++] = strtoul(bytestr, NULL, 16);
+ valbuf += 2;
+ }
+ if (b != reglen) {
+ LOG_ERROR("Malformed Qxtreg packet");
+ error = XT_QERR_INVAL;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+ status = xtensa_write_memory(target, xtensa->spill_loc, memop_size,
+ reglen / memop_size, regbuf);
+ if (status != ERROR_OK) {
+ LOG_ERROR("TIE value store");
+ error = XT_QERR_MEM;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+ }
+ xtensa_reg_val_t orig_a4 = xtensa_reg_get(target, XT_REG_IDX_A4);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, xtensa->spill_loc);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));
+
+ int32_t tieop_status = xtensa_gdbqc_parse_exec_tie_ops(target, delim);
+
+ /* Restore a4 but not yet spill memory. Execute it all... */
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, orig_a4);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));
+ status = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ if (status != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "TIE queue execute: %d\n", status);
+ tieop_status = status;
+ }
+ status = xtensa_core_status_check(target);
+ if (status != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "TIE instr execute: %d\n", status);
+ tieop_status = status;
+ }
+
+ if (tieop_status == ERROR_OK) {
+ if (iswrite) {
+ /* TIE write succeeded; send OK */
+ strcpy(*response_p, "OK");
+ } else {
+ /* TIE read succeeded; copy result from spill memory */
+ status = xtensa_read_memory(target, xtensa->spill_loc, memop_size, reglen, regbuf);
+ if (status != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "TIE result read");
+ tieop_status = status;
+ }
+ unsigned int i;
+ for (i = 0; i < reglen; i++)
+ sprintf(*response_p + 2 * i, "%02x", regbuf[i]);
+ *(*response_p + 2 * i) = '\0';
+ LOG_TARGET_DEBUG(target, "TIE response: %s", *response_p);
+ }
+ }
+
+ /* Restore spill memory first, then report any previous errors */
+ status = xtensa_write_memory(target, xtensa->spill_loc, memop_size,
+ xtensa->spill_bytes / memop_size, xtensa->spill_buf);
+ if (status != ERROR_OK) {
+ LOG_ERROR("Spill memory restore");
+ error = XT_QERR_MEM;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+ if (tieop_status != ERROR_OK) {
+ LOG_ERROR("TIE execution");
+ error = XT_QERR_FAIL;
+ goto xtensa_gdbqc_qxtreg_fail;
+ }
+ return ERROR_OK;
+
+xtensa_gdbqc_qxtreg_fail:
+ strcpy(*response_p, xt_qerr[error].chrval);
+ return xt_qerr[error].intval;
+}
+
+int xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ enum xtensa_qerr_e error;
+ if (!packet || !response_p) {
+ LOG_TARGET_ERROR(target, "invalid parameter: packet %p response_p %p", packet, response_p);
+ return ERROR_FAIL;
+ }
+
+ *response_p = xtensa->qpkt_resp;
+ if (strncmp(packet, "qxtn", 4) == 0) {
+ strcpy(*response_p, "OpenOCD");
+ return ERROR_OK;
+ } else if (strncasecmp(packet, "qxtgdbversion=", 14) == 0) {
+ return ERROR_OK;
+ } else if ((strncmp(packet, "Qxtsis=", 7) == 0) || (strncmp(packet, "Qxtsds=", 7) == 0)) {
+ /* Confirm host cache params match core .cfg file */
+ struct xtensa_cache_config *cachep = (packet[4] == 'i') ?
+ &xtensa->core_config->icache : &xtensa->core_config->dcache;
+ unsigned int line_size = 0, size = 0, way_count = 0;
+ sscanf(&packet[7], "%x,%x,%x", &line_size, &size, &way_count);
+ if ((cachep->line_size != line_size) ||
+ (cachep->size != size) ||
+ (cachep->way_count != way_count)) {
+ LOG_TARGET_WARNING(target, "%cCache mismatch; check xtensa-core-XXX.cfg file",
+ cachep == &xtensa->core_config->icache ? 'I' : 'D');
+ }
+ strcpy(*response_p, "OK");
+ return ERROR_OK;
+ } else if ((strncmp(packet, "Qxtiram=", 8) == 0) || (strncmp(packet, "Qxtirom=", 8) == 0)) {
+ /* Confirm host IRAM/IROM params match core .cfg file */
+ struct xtensa_local_mem_config *memp = (packet[5] == 'a') ?
+ &xtensa->core_config->iram : &xtensa->core_config->irom;
+ unsigned int base = 0, size = 0, i;
+ char *pkt = (char *)&packet[7];
+ do {
+ pkt++;
+ size = strtoul(pkt, &pkt, 16);
+ pkt++;
+ base = strtoul(pkt, &pkt, 16);
+ LOG_TARGET_DEBUG(target, "memcheck: %dB @ 0x%08x", size, base);
+ for (i = 0; i < memp->count; i++) {
+ if ((memp->regions[i].base == base) && (memp->regions[i].size == size))
+ break;
+ }
+ if (i == memp->count) {
+ LOG_TARGET_WARNING(target, "%s mismatch; check xtensa-core-XXX.cfg file",
+ memp == &xtensa->core_config->iram ? "IRAM" : "IROM");
+ break;
+ }
+ for (i = 0; i < 11; i++) {
+ pkt++;
+ strtoul(pkt, &pkt, 16);
+ }
+ } while (pkt && (pkt[0] == ','));
+ strcpy(*response_p, "OK");
+ return ERROR_OK;
+ } else if (strncmp(packet, "Qxtexcmlvl=", 11) == 0) {
+ /* Confirm host EXCM_LEVEL matches core .cfg file */
+ unsigned int excm_level = strtoul(&packet[11], NULL, 0);
+ if (!xtensa->core_config->high_irq.enabled ||
+ (excm_level != xtensa->core_config->high_irq.excm_level))
+ LOG_TARGET_WARNING(target, "EXCM_LEVEL mismatch; check xtensa-core-XXX.cfg file");
+ strcpy(*response_p, "OK");
+ return ERROR_OK;
+ } else if ((strncmp(packet, "Qxtl2cs=", 8) == 0) ||
+ (strncmp(packet, "Qxtl2ca=", 8) == 0) ||
+ (strncmp(packet, "Qxtdensity=", 11) == 0)) {
+ strcpy(*response_p, "OK");
+ return ERROR_OK;
+ } else if (strncmp(packet, "Qxtspill=", 9) == 0) {
+ char *delim;
+ uint32_t spill_loc = strtoul(packet + 9, &delim, 16);
+ if (*delim != ':') {
+ LOG_ERROR("Malformed Qxtspill packet");
+ error = XT_QERR_INVAL;
+ goto xtensa_gdb_query_custom_fail;
+ }
+ xtensa->spill_loc = spill_loc;
+ xtensa->spill_bytes = strtoul(delim + 1, NULL, 16);
+ if (xtensa->spill_buf)
+ free(xtensa->spill_buf);
+ xtensa->spill_buf = calloc(1, xtensa->spill_bytes);
+ if (!xtensa->spill_buf) {
+ LOG_ERROR("Spill buf alloc");
+ error = XT_QERR_MEM;
+ goto xtensa_gdb_query_custom_fail;
+ }
+ LOG_TARGET_DEBUG(target, "Set spill 0x%08" PRIx32 " (%d)", xtensa->spill_loc, xtensa->spill_bytes);
+ strcpy(*response_p, "OK");
+ return ERROR_OK;
+ } else if (strncasecmp(packet, "qxtreg", 6) == 0) {
+ return xtensa_gdbqc_qxtreg(target, packet, response_p);
+ } else if ((strncmp(packet, "qTStatus", 8) == 0) ||
+ (strncmp(packet, "qxtftie", 7) == 0) ||
+ (strncmp(packet, "qxtstie", 7) == 0)) {
+ /* Return empty string to indicate trace, TIE wire debug are unsupported */
+ strcpy(*response_p, "");
+ return ERROR_OK;
+ }
+
+ /* Warn for all other queries, but do not return errors */
+ LOG_TARGET_WARNING(target, "Unknown target-specific query packet: %s", packet);
+ strcpy(*response_p, "");
+ return ERROR_OK;
+
+xtensa_gdb_query_custom_fail:
+ strcpy(*response_p, xt_qerr[error].chrval);
+ return xt_qerr[error].intval;
+}
+
int xtensa_init_arch_info(struct target *target, struct xtensa *xtensa,
- const struct xtensa_config *xtensa_config,
const struct xtensa_debug_module_config *dm_cfg)
{
target->arch_info = xtensa;
xtensa->common_magic = XTENSA_COMMON_MAGIC;
xtensa->target = target;
- xtensa->core_config = xtensa_config;
xtensa->stepping_isr_mode = XT_STEPPING_ISR_ON;
- if (!xtensa->core_config->exc.enabled || !xtensa->core_config->irq.enabled ||
- !xtensa->core_config->high_irq.enabled || !xtensa->core_config->debug.enabled) {
- LOG_ERROR("Xtensa configuration does not support debugging!");
+ xtensa->core_config = calloc(1, sizeof(struct xtensa_config));
+ if (!xtensa->core_config) {
+ LOG_ERROR("Xtensa configuration alloc failed\n");
return ERROR_FAIL;
}
+
+ /* Default cache settings are disabled with 1 way */
+ xtensa->core_config->icache.way_count = 1;
+ xtensa->core_config->dcache.way_count = 1;
+
+ /* chrval: AR3/AR4 register names will change with window mapping.
+ * intval: tracks whether scratch register was set through gdb P packet.
+ */
+ for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) {
+ xtensa->scratch_ars[s].chrval = calloc(8, sizeof(char));
+ if (!xtensa->scratch_ars[s].chrval) {
+ for (enum xtensa_ar_scratch_set_e f = 0; f < s; f++)
+ free(xtensa->scratch_ars[f].chrval);
+ free(xtensa->core_config);
+ LOG_ERROR("Xtensa scratch AR alloc failed\n");
+ return ERROR_FAIL;
+ }
+ xtensa->scratch_ars[s].intval = false;
+ sprintf(xtensa->scratch_ars[s].chrval, "%s%d",
+ ((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_A4)) ? "a" : "ar",
+ ((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_AR3)) ? 3 : 4);
+ }
+
return xtensa_dm_init(&xtensa->dbg_mod, dm_cfg);
}
@@ -2215,12 +2886,12 @@ int xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
struct xtensa *xtensa = target_to_xtensa(target);
xtensa->come_online_probes_num = 3;
- xtensa->hw_brps = calloc(xtensa->core_config->debug.ibreaks_num, sizeof(struct breakpoint *));
+ xtensa->hw_brps = calloc(XT_HW_IBREAK_MAX_NUM, sizeof(struct breakpoint *));
if (!xtensa->hw_brps) {
LOG_ERROR("Failed to alloc memory for HW breakpoints!");
return ERROR_FAIL;
}
- xtensa->hw_wps = calloc(xtensa->core_config->debug.dbreaks_num, sizeof(struct watchpoint *));
+ xtensa->hw_wps = calloc(XT_HW_DBREAK_MAX_NUM, sizeof(struct watchpoint *));
if (!xtensa->hw_wps) {
free(xtensa->hw_brps);
LOG_ERROR("Failed to alloc memory for HW watchpoints!");
@@ -2234,6 +2905,11 @@ int xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
return ERROR_FAIL;
}
+ xtensa->spill_loc = 0xffffffff;
+ xtensa->spill_bytes = 0;
+ xtensa->spill_buf = NULL;
+ xtensa->probe_lsddr32p = -1; /* Probe for fast load/store operations */
+
return xtensa_build_reg_cache(target);
}
@@ -2254,6 +2930,21 @@ static void xtensa_free_reg_cache(struct target *target)
}
xtensa->core_cache = NULL;
xtensa->algo_context_backup = NULL;
+
+ if (xtensa->empty_regs) {
+ for (unsigned int i = 0; i < xtensa->dbregs_num; i++) {
+ free((void *)xtensa->empty_regs[i].name);
+ free(xtensa->empty_regs[i].value);
+ }
+ free(xtensa->empty_regs);
+ }
+ xtensa->empty_regs = NULL;
+ if (xtensa->optregs) {
+ for (unsigned int i = 0; i < xtensa->num_optregs; i++)
+ free((void *)xtensa->optregs[i].name);
+ free(xtensa->optregs);
+ }
+ xtensa->optregs = NULL;
}
void xtensa_target_deinit(struct target *target)
@@ -2263,22 +2954,30 @@ void xtensa_target_deinit(struct target *target)
LOG_DEBUG("start");
if (target_was_examined(target)) {
- int ret = xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRCLR, OCDDCR_ENABLEOCD);
+ int ret = xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, OCDDCR_ENABLEOCD);
if (ret != ERROR_OK) {
LOG_ERROR("Failed to queue OCDDCR_ENABLEOCD clear operation!");
return;
}
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- ret = jtag_execute_queue();
+ ret = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (ret != ERROR_OK) {
LOG_ERROR("Failed to clear OCDDCR_ENABLEOCD!");
return;
}
+ xtensa_dm_deinit(&xtensa->dbg_mod);
}
xtensa_free_reg_cache(target);
free(xtensa->hw_brps);
free(xtensa->hw_wps);
free(xtensa->sw_brps);
+ if (xtensa->spill_buf) {
+ free(xtensa->spill_buf);
+ xtensa->spill_buf = NULL;
+ }
+ for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)
+ free(xtensa->scratch_ars[s].chrval);
+ free(xtensa->core_config);
}
const char *xtensa_get_gdb_arch(struct target *target)
@@ -2286,6 +2985,523 @@ const char *xtensa_get_gdb_arch(struct target *target)
return "xtensa";
}
+/* exe <ascii-encoded hexadecimal instruction bytes> */
+static COMMAND_HELPER(xtensa_cmd_exe_do, struct target *target)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ /* Process ascii-encoded hex byte string */
+ const char *parm = CMD_ARGV[0];
+ unsigned int parm_len = strlen(parm);
+ if ((parm_len >= 64) || (parm_len & 1)) {
+ LOG_ERROR("Invalid parameter length (%d): must be even, < 64 characters", parm_len);
+ return ERROR_FAIL;
+ }
+
+ uint8_t ops[32];
+ memset(ops, 0, 32);
+ unsigned int oplen = parm_len / 2;
+ char encoded_byte[3] = { 0, 0, 0 };
+ for (unsigned int i = 0; i < oplen; i++) {
+ encoded_byte[0] = *parm++;
+ encoded_byte[1] = *parm++;
+ ops[i] = strtoul(encoded_byte, NULL, 16);
+ }
+
+ /* GDB must handle state save/restore.
+ * Flush reg cache in case spill location is in an AR
+ * Update CPENABLE only for this execution; later restore cached copy
+ * Keep a copy of exccause in case executed code triggers an exception
+ */
+ int status = xtensa_write_dirty_registers(target);
+ if (status != ERROR_OK) {
+ LOG_ERROR("%s: Failed to write back register cache.", target_name(target));
+ return ERROR_FAIL;
+ }
+ xtensa_reg_val_t exccause = xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE);
+ xtensa_reg_val_t cpenable = xtensa_reg_get(target, XT_REG_IDX_CPENABLE);
+ xtensa_reg_val_t a3 = xtensa_reg_get(target, XT_REG_IDX_A3);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa,
+ xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+
+ /* Queue instruction list and execute everything */
+ LOG_TARGET_DEBUG(target, "execute stub: %s", CMD_ARGV[0]);
+ xtensa_queue_exec_ins_wide(xtensa, ops, oplen); /* Handles endian-swap */
+ status = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ if (status != ERROR_OK)
+ LOG_TARGET_ERROR(target, "TIE queue execute: %d\n", status);
+ status = xtensa_core_status_check(target);
+ if (status != ERROR_OK)
+ LOG_TARGET_ERROR(target, "TIE instr execute: %d\n", status);
+
+ /* Reread register cache and restore saved regs after instruction execution */
+ if (xtensa_fetch_all_regs(target) != ERROR_OK)
+ LOG_TARGET_ERROR(target, "%s: Failed to fetch register cache (post-exec).", target_name(target));
+ xtensa_reg_set(target, XT_REG_IDX_EXCCAUSE, exccause);
+ xtensa_reg_set(target, XT_REG_IDX_CPENABLE, cpenable);
+ return status;
+}
+
+COMMAND_HANDLER(xtensa_cmd_exe)
+{
+ return CALL_COMMAND_HANDLER(xtensa_cmd_exe_do, get_current_target(CMD_CTX));
+}
+
+/* xtdef <name> */
+COMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa)
+{
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ const char *core_name = CMD_ARGV[0];
+ if (strcasecmp(core_name, "LX") == 0) {
+ xtensa->core_config->core_type = XT_LX;
+ } else {
+ LOG_ERROR("xtdef [LX]\n");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(xtensa_cmd_xtdef)
+{
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do,
+ target_to_xtensa(get_current_target(CMD_CTX)));
+}
+
+static inline bool xtensa_cmd_xtopt_legal_val(char *opt, int val, int min, int max)
+{
+ if ((val < min) || (val > max)) {
+ LOG_ERROR("xtopt %s (%d) out of range [%d..%d]\n", opt, val, min, max);
+ return false;
+ }
+ return true;
+}
+
+/* xtopt <name> <value> */
+COMMAND_HELPER(xtensa_cmd_xtopt_do, struct xtensa *xtensa)
+{
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ const char *opt_name = CMD_ARGV[0];
+ int opt_val = strtol(CMD_ARGV[1], NULL, 0);
+ if (strcasecmp(opt_name, "arnum") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("arnum", opt_val, 0, 64))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->aregs_num = opt_val;
+ } else if (strcasecmp(opt_name, "windowed") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("windowed", opt_val, 0, 1))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->windowed = opt_val;
+ } else if (strcasecmp(opt_name, "cpenable") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("cpenable", opt_val, 0, 1))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->coproc = opt_val;
+ } else if (strcasecmp(opt_name, "exceptions") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("exceptions", opt_val, 0, 1))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->exceptions = opt_val;
+ } else if (strcasecmp(opt_name, "intnum") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("intnum", opt_val, 0, 32))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->irq.enabled = (opt_val > 0);
+ xtensa->core_config->irq.irq_num = opt_val;
+ } else if (strcasecmp(opt_name, "hipriints") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("hipriints", opt_val, 0, 1))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->high_irq.enabled = opt_val;
+ } else if (strcasecmp(opt_name, "excmlevel") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("excmlevel", opt_val, 1, 6))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ if (!xtensa->core_config->high_irq.enabled) {
+ LOG_ERROR("xtopt excmlevel requires hipriints\n");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+ xtensa->core_config->high_irq.excm_level = opt_val;
+ } else if (strcasecmp(opt_name, "intlevels") == 0) {
+ if (xtensa->core_config->core_type == XT_LX) {
+ if (!xtensa_cmd_xtopt_legal_val("intlevels", opt_val, 2, 6))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ } else {
+ if (!xtensa_cmd_xtopt_legal_val("intlevels", opt_val, 1, 255))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+ if (!xtensa->core_config->high_irq.enabled) {
+ LOG_ERROR("xtopt intlevels requires hipriints\n");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+ xtensa->core_config->high_irq.level_num = opt_val;
+ } else if (strcasecmp(opt_name, "debuglevel") == 0) {
+ if (xtensa->core_config->core_type == XT_LX) {
+ if (!xtensa_cmd_xtopt_legal_val("debuglevel", opt_val, 2, 6))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ } else {
+ if (!xtensa_cmd_xtopt_legal_val("debuglevel", opt_val, 0, 0))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+ xtensa->core_config->debug.enabled = 1;
+ xtensa->core_config->debug.irq_level = opt_val;
+ } else if (strcasecmp(opt_name, "ibreaknum") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("ibreaknum", opt_val, 0, 2))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->debug.ibreaks_num = opt_val;
+ } else if (strcasecmp(opt_name, "dbreaknum") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("dbreaknum", opt_val, 0, 2))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->debug.dbreaks_num = opt_val;
+ } else if (strcasecmp(opt_name, "tracemem") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("tracemem", opt_val, 0, 256 * 1024))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->trace.mem_sz = opt_val;
+ xtensa->core_config->trace.enabled = (opt_val > 0);
+ } else if (strcasecmp(opt_name, "tracememrev") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("tracememrev", opt_val, 0, 1))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->trace.reversed_mem_access = opt_val;
+ } else if (strcasecmp(opt_name, "perfcount") == 0) {
+ if (!xtensa_cmd_xtopt_legal_val("perfcount", opt_val, 0, 8))
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ xtensa->core_config->debug.perfcount_num = opt_val;
+ } else {
+ LOG_WARNING("Unknown xtensa command ignored: \"xtopt %s %s\"", CMD_ARGV[0], CMD_ARGV[1]);
+ return ERROR_OK;
+ }
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(xtensa_cmd_xtopt)
+{
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do,
+ target_to_xtensa(get_current_target(CMD_CTX)));
+}
+
+/* xtmem <type> [parameters] */
+COMMAND_HELPER(xtensa_cmd_xtmem_do, struct xtensa *xtensa)
+{
+ struct xtensa_cache_config *cachep = NULL;
+ struct xtensa_local_mem_config *memp = NULL;
+ int mem_access = 0;
+ bool is_dcache = false;
+
+ if (CMD_ARGC == 0) {
+ LOG_ERROR("xtmem <type> [parameters]\n");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ const char *mem_name = CMD_ARGV[0];
+ if (strcasecmp(mem_name, "icache") == 0) {
+ cachep = &xtensa->core_config->icache;
+ } else if (strcasecmp(mem_name, "dcache") == 0) {
+ cachep = &xtensa->core_config->dcache;
+ is_dcache = true;
+ } else if (strcasecmp(mem_name, "l2cache") == 0) {
+ /* TODO: support L2 cache */
+ } else if (strcasecmp(mem_name, "l2addr") == 0) {
+ /* TODO: support L2 cache */
+ } else if (strcasecmp(mem_name, "iram") == 0) {
+ memp = &xtensa->core_config->iram;
+ mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;
+ } else if (strcasecmp(mem_name, "dram") == 0) {
+ memp = &xtensa->core_config->dram;
+ mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;
+ } else if (strcasecmp(mem_name, "sram") == 0) {
+ memp = &xtensa->core_config->sram;
+ mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;
+ } else if (strcasecmp(mem_name, "irom") == 0) {
+ memp = &xtensa->core_config->irom;
+ mem_access = XT_MEM_ACCESS_READ;
+ } else if (strcasecmp(mem_name, "drom") == 0) {
+ memp = &xtensa->core_config->drom;
+ mem_access = XT_MEM_ACCESS_READ;
+ } else if (strcasecmp(mem_name, "srom") == 0) {
+ memp = &xtensa->core_config->srom;
+ mem_access = XT_MEM_ACCESS_READ;
+ } else {
+ LOG_ERROR("xtmem types: <icache|dcache|l2cache|l2addr|iram|irom|dram|drom|sram|srom>\n");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
+ if (cachep) {
+ if ((CMD_ARGC != 4) && (CMD_ARGC != 5)) {
+ LOG_ERROR("xtmem <cachetype> <linebytes> <cachebytes> <ways> [writeback]\n");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ cachep->line_size = strtoul(CMD_ARGV[1], NULL, 0);
+ cachep->size = strtoul(CMD_ARGV[2], NULL, 0);
+ cachep->way_count = strtoul(CMD_ARGV[3], NULL, 0);
+ cachep->writeback = ((CMD_ARGC == 5) && is_dcache) ?
+ strtoul(CMD_ARGV[4], NULL, 0) : 0;
+ } else if (memp) {
+ if (CMD_ARGC != 3) {
+ LOG_ERROR("xtmem <memtype> <baseaddr> <bytes>\n");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ struct xtensa_local_mem_region_config *memcfgp = &memp->regions[memp->count];
+ memcfgp->base = strtoul(CMD_ARGV[1], NULL, 0);
+ memcfgp->size = strtoul(CMD_ARGV[2], NULL, 0);
+ memcfgp->access = mem_access;
+ memp->count++;
+ }
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(xtensa_cmd_xtmem)
+{
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do,
+ target_to_xtensa(get_current_target(CMD_CTX)));
+}
+
+/* xtmpu <num FG seg> <min seg size> <lockable> <executeonly> */
+COMMAND_HELPER(xtensa_cmd_xtmpu_do, struct xtensa *xtensa)
+{
+ if (CMD_ARGC != 4) {
+ LOG_ERROR("xtmpu <num FG seg> <min seg size> <lockable> <executeonly>\n");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ unsigned int nfgseg = strtoul(CMD_ARGV[0], NULL, 0);
+ unsigned int minsegsize = strtoul(CMD_ARGV[1], NULL, 0);
+ unsigned int lockable = strtoul(CMD_ARGV[2], NULL, 0);
+ unsigned int execonly = strtoul(CMD_ARGV[3], NULL, 0);
+
+ if ((nfgseg > 32)) {
+ LOG_ERROR("<nfgseg> must be within [0..32]\n");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ } else if (minsegsize & (minsegsize - 1)) {
+ LOG_ERROR("<minsegsize> must be a power of 2 >= 32\n");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ } else if (lockable > 1) {
+ LOG_ERROR("<lockable> must be 0 or 1\n");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ } else if (execonly > 1) {
+ LOG_ERROR("<execonly> must be 0 or 1\n");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
+ xtensa->core_config->mpu.enabled = true;
+ xtensa->core_config->mpu.nfgseg = nfgseg;
+ xtensa->core_config->mpu.minsegsize = minsegsize;
+ xtensa->core_config->mpu.lockable = lockable;
+ xtensa->core_config->mpu.execonly = execonly;
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(xtensa_cmd_xtmpu)
+{
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do,
+ target_to_xtensa(get_current_target(CMD_CTX)));
+}
+
+/* xtmmu <NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56> */
+COMMAND_HELPER(xtensa_cmd_xtmmu_do, struct xtensa *xtensa)
+{
+ if (CMD_ARGC != 2) {
+ LOG_ERROR("xtmmu <NIREFILLENTRIES> <NDREFILLENTRIES>\n");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ unsigned int nirefillentries = strtoul(CMD_ARGV[0], NULL, 0);
+ unsigned int ndrefillentries = strtoul(CMD_ARGV[1], NULL, 0);
+ if ((nirefillentries != 16) && (nirefillentries != 32)) {
+ LOG_ERROR("<nirefillentries> must be 16 or 32\n");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ } else if ((ndrefillentries != 16) && (ndrefillentries != 32)) {
+ LOG_ERROR("<ndrefillentries> must be 16 or 32\n");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
+ xtensa->core_config->mmu.enabled = true;
+ xtensa->core_config->mmu.itlb_entries_count = nirefillentries;
+ xtensa->core_config->mmu.dtlb_entries_count = ndrefillentries;
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(xtensa_cmd_xtmmu)
+{
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do,
+ target_to_xtensa(get_current_target(CMD_CTX)));
+}
+
+/* xtregs <numregs>
+ * xtreg <regname> <regnum> */
+COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa)
+{
+ if (CMD_ARGC == 1) {
+ int32_t numregs = strtoul(CMD_ARGV[0], NULL, 0);
+ if ((numregs <= 0) || (numregs > UINT16_MAX)) {
+ LOG_ERROR("xtreg <numregs>: Invalid 'numregs' (%d)", numregs);
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ if ((xtensa->genpkt_regs_num > 0) && (numregs < (int32_t)xtensa->genpkt_regs_num)) {
+ LOG_ERROR("xtregs (%d) must be larger than numgenregs (%d) (if xtregfmt specified)",
+ numregs, xtensa->genpkt_regs_num);
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ xtensa->total_regs_num = numregs;
+ xtensa->core_regs_num = 0;
+ xtensa->num_optregs = 0;
+ /* A little more memory than required, but saves a second initialization pass */
+ xtensa->optregs = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc));
+ if (!xtensa->optregs) {
+ LOG_ERROR("Failed to allocate xtensa->optregs!");
+ return ERROR_FAIL;
+ }
+ return ERROR_OK;
+ } else if (CMD_ARGC != 2) {
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ /* "xtregfmt contiguous" must be specified prior to the first "xtreg" definition
+ * if general register (g-packet) requests or contiguous register maps are supported */
+ if (xtensa->regmap_contiguous && !xtensa->contiguous_regs_desc) {
+ xtensa->contiguous_regs_desc = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc *));
+ if (!xtensa->contiguous_regs_desc) {
+ LOG_ERROR("Failed to allocate xtensa->contiguous_regs_desc!");
+ return ERROR_FAIL;
+ }
+ }
+
+ const char *regname = CMD_ARGV[0];
+ unsigned int regnum = strtoul(CMD_ARGV[1], NULL, 0);
+ if (regnum > UINT16_MAX) {
+ LOG_ERROR("<regnum> must be a 16-bit number");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
+ if ((xtensa->num_optregs + xtensa->core_regs_num) >= xtensa->total_regs_num) {
+ if (xtensa->total_regs_num)
+ LOG_ERROR("'xtreg %s 0x%04x': Too many registers (%d expected, %d core %d extended)",
+ regname, regnum,
+ xtensa->total_regs_num, xtensa->core_regs_num, xtensa->num_optregs);
+ else
+ LOG_ERROR("'xtreg %s 0x%04x': Number of registers unspecified",
+ regname, regnum);
+ return ERROR_FAIL;
+ }
+
+ /* Determine whether register belongs in xtensa_regs[] or xtensa->xtensa_spec_regs[] */
+ struct xtensa_reg_desc *rptr = &xtensa->optregs[xtensa->num_optregs];
+ bool is_extended_reg = true;
+ unsigned int ridx;
+ for (ridx = 0; ridx < XT_NUM_REGS; ridx++) {
+ if (strcmp(CMD_ARGV[0], xtensa_regs[ridx].name) == 0) {
+ /* Flag core register as defined */
+ rptr = &xtensa_regs[ridx];
+ xtensa->core_regs_num++;
+ is_extended_reg = false;
+ break;
+ }
+ }
+
+ rptr->exist = true;
+ if (is_extended_reg) {
+ /* Register ID, debugger-visible register ID */
+ rptr->name = strdup(CMD_ARGV[0]);
+ rptr->dbreg_num = regnum;
+ rptr->reg_num = (regnum & XT_REG_INDEX_MASK);
+ xtensa->num_optregs++;
+
+ /* Register type */
+ if ((regnum & XT_REG_GENERAL_MASK) == XT_REG_GENERAL_VAL) {
+ rptr->type = XT_REG_GENERAL;
+ } else if ((regnum & XT_REG_USER_MASK) == XT_REG_USER_VAL) {
+ rptr->type = XT_REG_USER;
+ } else if ((regnum & XT_REG_FR_MASK) == XT_REG_FR_VAL) {
+ rptr->type = XT_REG_FR;
+ } else if ((regnum & XT_REG_SPECIAL_MASK) == XT_REG_SPECIAL_VAL) {
+ rptr->type = XT_REG_SPECIAL;
+ } else if ((regnum & XT_REG_RELGEN_MASK) == XT_REG_RELGEN_VAL) {
+ /* WARNING: For these registers, regnum points to the
+ * index of the corresponding ARx registers, NOT to
+ * the processor register number! */
+ rptr->type = XT_REG_RELGEN;
+ rptr->reg_num += XT_REG_IDX_ARFIRST;
+ rptr->dbreg_num += XT_REG_IDX_ARFIRST;
+ } else if ((regnum & XT_REG_TIE_MASK) != 0) {
+ rptr->type = XT_REG_TIE;
+ } else {
+ rptr->type = XT_REG_OTHER;
+ }
+
+ /* Register flags */
+ if ((strcmp(rptr->name, "mmid") == 0) || (strcmp(rptr->name, "eraccess") == 0) ||
+ (strcmp(rptr->name, "ddr") == 0) || (strcmp(rptr->name, "intset") == 0) ||
+ (strcmp(rptr->name, "intclear") == 0))
+ rptr->flags = XT_REGF_NOREAD;
+ 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)) {
+ 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);
+ }
+ } else if (strcmp(rptr->name, "cpenable") == 0) {
+ xtensa->core_config->coproc = true;
+ }
+
+ /* Build out list of contiguous registers in specified order */
+ unsigned int running_reg_count = xtensa->num_optregs + xtensa->core_regs_num;
+ if (xtensa->contiguous_regs_desc) {
+ assert((running_reg_count <= xtensa->total_regs_num) && "contiguous register address internal error!");
+ xtensa->contiguous_regs_desc[running_reg_count - 1] = rptr;
+ }
+ if (xtensa_extra_debug_log)
+ LOG_DEBUG("Added %s register %-16s: 0x%04x/0x%02x t%d (%d of %d)",
+ is_extended_reg ? "config-specific" : "core",
+ rptr->name, rptr->dbreg_num, rptr->reg_num, rptr->type,
+ is_extended_reg ? xtensa->num_optregs : ridx,
+ is_extended_reg ? xtensa->total_regs_num : XT_NUM_REGS);
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(xtensa_cmd_xtreg)
+{
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do,
+ target_to_xtensa(get_current_target(CMD_CTX)));
+}
+
+/* xtregfmt <contiguous|sparse> [numgregs] */
+COMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa)
+{
+ if ((CMD_ARGC == 1) || (CMD_ARGC == 2)) {
+ if (!strcasecmp(CMD_ARGV[0], "sparse")) {
+ return ERROR_OK;
+ } else if (!strcasecmp(CMD_ARGV[0], "contiguous")) {
+ xtensa->regmap_contiguous = true;
+ if (CMD_ARGC == 2) {
+ unsigned int numgregs = strtoul(CMD_ARGV[1], NULL, 0);
+ if ((numgregs <= 0) ||
+ ((numgregs > xtensa->total_regs_num) &&
+ (xtensa->total_regs_num > 0))) {
+ LOG_ERROR("xtregfmt: if specified, numgregs (%d) must be <= numregs (%d)",
+ numgregs, xtensa->total_regs_num);
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ xtensa->genpkt_regs_num = numgregs;
+ }
+ return ERROR_OK;
+ }
+ }
+ return ERROR_COMMAND_SYNTAX_ERROR;
+}
+
+COMMAND_HANDLER(xtensa_cmd_xtregfmt)
+{
+ return CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do,
+ target_to_xtensa(get_current_target(CMD_CTX)));
+}
+
COMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa)
{
return CALL_COMMAND_HANDLER(handle_command_parse_bool,
@@ -2436,7 +3652,7 @@ COMMAND_HANDLER(xtensa_cmd_mask_interrupts)
COMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target)
{
- int res = ERROR_OK;
+ int res;
uint32_t val = 0;
if (CMD_ARGC >= 1) {
@@ -2469,16 +3685,15 @@ COMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target)
} else {
struct xtensa *xtensa = target_to_xtensa(target);
res = xtensa_smpbreak_read(xtensa, &val);
- if (res == ERROR_OK) {
+ if (res == ERROR_OK)
command_print(CMD, "Current bits set:%s%s%s%s",
(val & OCDDCR_BREAKINEN) ? " BreakIn" : "",
(val & OCDDCR_BREAKOUTEN) ? " BreakOut" : "",
(val & OCDDCR_RUNSTALLINEN) ? " RunStallIn" : "",
(val & OCDDCR_DEBUGMODEOUTEN) ? " DebugModeOut" : ""
);
- } else {
+ else
command_print(CMD, "Failed to get smpbreak config %d", res);
- }
}
return res;
}
@@ -2667,12 +3882,68 @@ COMMAND_HANDLER(xtensa_cmd_tracedump)
target_to_xtensa(get_current_target(CMD_CTX)), CMD_ARGV[0]);
}
-const struct command_registration xtensa_command_handlers[] = {
+static const struct command_registration xtensa_any_command_handlers[] = {
+ {
+ .name = "xtdef",
+ .handler = xtensa_cmd_xtdef,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa core type",
+ .usage = "<type>",
+ },
+ {
+ .name = "xtopt",
+ .handler = xtensa_cmd_xtopt,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa core option",
+ .usage = "<name> <value>",
+ },
+ {
+ .name = "xtmem",
+ .handler = xtensa_cmd_xtmem,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa memory/cache option",
+ .usage = "<type> [parameters]",
+ },
+ {
+ .name = "xtmmu",
+ .handler = xtensa_cmd_xtmmu,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa MMU option",
+ .usage = "<NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56>",
+ },
+ {
+ .name = "xtmpu",
+ .handler = xtensa_cmd_xtmpu,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa MPU option",
+ .usage = "<num FG seg> <min seg size> <lockable> <executeonly>",
+ },
+ {
+ .name = "xtreg",
+ .handler = xtensa_cmd_xtreg,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure Xtensa register",
+ .usage = "<regname> <regnum>",
+ },
+ {
+ .name = "xtregs",
+ .handler = xtensa_cmd_xtreg,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure number of Xtensa registers",
+ .usage = "<numregs>",
+ },
+ {
+ .name = "xtregfmt",
+ .handler = xtensa_cmd_xtregfmt,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure format of Xtensa register map",
+ .usage = "<contiguous|sparse> [numgregs]",
+ },
{
.name = "set_permissive",
.handler = xtensa_cmd_permissive_mode,
.mode = COMMAND_ANY,
- .help = "When set to 1, enable Xtensa permissive mode (less client-side checks)",
+ .help = "When set to 1, enable Xtensa permissive mode (fewer client-side checks)",
.usage = "[0|1]",
},
{
@@ -2687,8 +3958,7 @@ const struct command_registration xtensa_command_handlers[] = {
.handler = xtensa_cmd_smpbreak,
.mode = COMMAND_ANY,
.help = "Set the way the CPU chains OCD breaks",
- .usage =
- "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]",
+ .usage = "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]",
},
{
.name = "perfmon_enable",
@@ -2701,8 +3971,7 @@ const struct command_registration xtensa_command_handlers[] = {
.name = "perfmon_dump",
.handler = xtensa_cmd_perfmon_dump,
.mode = COMMAND_EXEC,
- .help =
- "Dump performance counter value. If no argument specified, dumps all counters.",
+ .help = "Dump performance counter value. If no argument specified, dumps all counters.",
.usage = "[counter_id]",
},
{
@@ -2727,5 +3996,23 @@ const struct command_registration xtensa_command_handlers[] = {
.help = "Tracing: Dump trace memory to a files. One file per core.",
.usage = "<outfile>",
},
+ {
+ .name = "exe",
+ .handler = xtensa_cmd_exe,
+ .mode = COMMAND_ANY,
+ .help = "Xtensa stub execution",
+ .usage = "<ascii-encoded hexadecimal instruction bytes>",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+const struct command_registration xtensa_command_handlers[] = {
+ {
+ .name = "xtensa",
+ .mode = COMMAND_ANY,
+ .help = "Xtensa command group",
+ .usage = "",
+ .chain = xtensa_any_command_handlers,
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/xtensa/xtensa.h b/src/target/xtensa/xtensa.h
index d8b15e1..4d98f3a 100644
--- a/src/target/xtensa/xtensa.h
+++ b/src/target/xtensa/xtensa.h
@@ -1,20 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Generic Xtensa target *
+ * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
* Copyright (C) 2019 Espressif Systems Ltd. *
- * Author: Alexey Gerenkov <alexey@espressif.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_TARGET_XTENSA_H
@@ -31,41 +20,77 @@
* Holds the interface to Xtensa cores.
*/
-#define XT_ISNS_SZ_MAX 3
+/* Big-endian vs. little-endian detection */
+#define XT_ISBE(X) ((X)->target->endianness == TARGET_BIG_ENDIAN)
+
+/* 24-bit break; BE version field-swapped then byte-swapped for use in memory R/W fns */
+#define XT_INS_BREAK_LE(S, T) (0x004000 | (((S) & 0xF) << 8) | (((T) & 0xF) << 4))
+#define XT_INS_BREAK_BE(S, T) (0x000400 | (((S) & 0xF) << 12) | ((T) & 0xF))
+#define XT_INS_BREAK(X, S, T) (XT_ISBE(X) ? XT_INS_BREAK_BE(S, T) : XT_INS_BREAK_LE(S, T))
+
+/* 16-bit break; BE version field-swapped then byte-swapped for use in memory R/W fns */
+#define XT_INS_BREAKN_LE(IMM4) (0xF02D | (((IMM4) & 0xF) << 8))
+#define XT_INS_BREAKN_BE(IMM4) (0x0FD2 | (((IMM4) & 0xF) << 12))
+#define XT_INS_BREAKN(X, IMM4) (XT_ISBE(X) ? XT_INS_BREAKN_BE(IMM4) : XT_INS_BREAKN_LE(IMM4))
+
+#define XT_ISNS_SZ_MAX 3
+
+#define XT_PS_RING(_v_) ((uint32_t)((_v_) & 0x3) << 6)
+#define XT_PS_RING_MSK (0x3 << 6)
+#define XT_PS_RING_GET(_v_) (((_v_) >> 6) & 0x3)
+#define XT_PS_CALLINC_MSK (0x3 << 16)
+#define XT_PS_OWB_MSK (0xF << 8)
+#define XT_PS_WOE_MSK BIT(18)
-#define XT_PS_RING(_v_) ((uint32_t)((_v_) & 0x3) << 6)
-#define XT_PS_RING_MSK (0x3 << 6)
-#define XT_PS_RING_GET(_v_) (((_v_) >> 6) & 0x3)
-#define XT_PS_CALLINC_MSK (0x3 << 16)
-#define XT_PS_OWB_MSK (0xF << 8)
+#define XT_LOCAL_MEM_REGIONS_NUM_MAX 8
-#define XT_LOCAL_MEM_REGIONS_NUM_MAX 8
+#define XT_AREGS_NUM_MAX 64
+#define XT_USER_REGS_NUM_MAX 256
-#define XT_AREGS_NUM_MAX 64
-#define XT_USER_REGS_NUM_MAX 256
+#define XT_MEM_ACCESS_NONE 0x0
+#define XT_MEM_ACCESS_READ 0x1
+#define XT_MEM_ACCESS_WRITE 0x2
+
+#define XT_MAX_TIE_REG_WIDTH (512) /* TIE register file max 4096 bits */
+#define XT_QUERYPKT_RESP_MAX (XT_MAX_TIE_REG_WIDTH * 2 + 1)
+
+enum xtensa_qerr_e {
+ XT_QERR_INTERNAL = 0,
+ XT_QERR_FAIL,
+ XT_QERR_INVAL,
+ XT_QERR_MEM,
+ XT_QERR_NUM,
+};
+
+/* An and ARn registers potentially used as scratch regs */
+enum xtensa_ar_scratch_set_e {
+ XT_AR_SCRATCH_A3 = 0,
+ XT_AR_SCRATCH_AR3,
+ XT_AR_SCRATCH_A4,
+ XT_AR_SCRATCH_AR4,
+ XT_AR_SCRATCH_NUM
+};
-#define XT_MEM_ACCESS_NONE 0x0
-#define XT_MEM_ACCESS_READ 0x1
-#define XT_MEM_ACCESS_WRITE 0x2
+struct xtensa_keyval_info_s {
+ char *chrval;
+ int intval;
+};
-enum xtensa_mem_err_detect {
- XT_MEM_ERR_DETECT_NONE,
- XT_MEM_ERR_DETECT_PARITY,
- XT_MEM_ERR_DETECT_ECC,
+enum xtensa_type {
+ XT_UNDEF = 0,
+ XT_LX,
};
struct xtensa_cache_config {
uint8_t way_count;
- uint8_t line_size;
- uint16_t size;
- bool writeback;
- enum xtensa_mem_err_detect mem_err_check;
+ uint32_t line_size;
+ uint32_t size;
+ int writeback;
};
struct xtensa_local_mem_region_config {
target_addr_t base;
uint32_t size;
- enum xtensa_mem_err_detect mem_err_check;
int access;
};
@@ -78,13 +103,14 @@ struct xtensa_mmu_config {
bool enabled;
uint8_t itlb_entries_count;
uint8_t dtlb_entries_count;
- bool ivarway56;
- bool dvarway56;
};
-struct xtensa_exception_config {
+struct xtensa_mpu_config {
bool enabled;
- uint8_t depc_num;
+ uint8_t nfgseg;
+ uint32_t minsegsize;
+ bool lockable;
+ bool execonly;
};
struct xtensa_irq_config {
@@ -94,8 +120,8 @@ struct xtensa_irq_config {
struct xtensa_high_prio_irq_config {
bool enabled;
+ uint8_t level_num;
uint8_t excm_level;
- uint8_t nmi_num;
};
struct xtensa_debug_config {
@@ -103,7 +129,7 @@ struct xtensa_debug_config {
uint8_t irq_level;
uint8_t ibreaks_num;
uint8_t dbreaks_num;
- uint8_t icount_sz;
+ uint8_t perfcount_num;
};
struct xtensa_tracing_config {
@@ -112,48 +138,26 @@ struct xtensa_tracing_config {
bool reversed_mem_access;
};
-struct xtensa_timer_irq_config {
- bool enabled;
- uint8_t comp_num;
-};
-
struct xtensa_config {
- bool density;
+ enum xtensa_type core_type;
uint8_t aregs_num;
bool windowed;
bool coproc;
- bool fp_coproc;
- bool loop;
- uint8_t miscregs_num;
- bool threadptr;
- bool boolean;
- bool cond_store;
- bool ext_l32r;
- bool mac16;
- bool reloc_vec;
- bool proc_id;
- bool mem_err_check;
- uint16_t user_regs_num;
- const struct xtensa_user_reg_desc *user_regs;
- int (*fetch_user_regs)(struct target *target);
- int (*queue_write_dirty_user_regs)(struct target *target);
+ bool exceptions;
+ struct xtensa_irq_config irq;
+ struct xtensa_high_prio_irq_config high_irq;
+ struct xtensa_mmu_config mmu;
+ struct xtensa_mpu_config mpu;
+ struct xtensa_debug_config debug;
+ struct xtensa_tracing_config trace;
struct xtensa_cache_config icache;
struct xtensa_cache_config dcache;
struct xtensa_local_mem_config irom;
struct xtensa_local_mem_config iram;
struct xtensa_local_mem_config drom;
struct xtensa_local_mem_config dram;
- struct xtensa_local_mem_config uram;
- struct xtensa_local_mem_config xlmi;
- struct xtensa_mmu_config mmu;
- struct xtensa_exception_config exc;
- struct xtensa_irq_config irq;
- struct xtensa_high_prio_irq_config high_irq;
- struct xtensa_timer_irq_config tim_irq;
- struct xtensa_debug_config debug;
- struct xtensa_tracing_config trace;
- unsigned int gdb_general_regs_num;
- const unsigned int *gdb_regs_mapping;
+ struct xtensa_local_mem_config sram;
+ struct xtensa_local_mem_config srom;
};
typedef uint32_t xtensa_insn_t;
@@ -187,13 +191,26 @@ struct xtensa_sw_breakpoint {
*/
struct xtensa {
unsigned int common_magic;
- const struct xtensa_config *core_config;
+ struct xtensa_chip_common *xtensa_chip;
+ struct xtensa_config *core_config;
struct xtensa_debug_module dbg_mod;
struct reg_cache *core_cache;
- unsigned int regs_num;
+ unsigned int total_regs_num;
+ unsigned int core_regs_num;
+ bool regmap_contiguous;
+ unsigned int genpkt_regs_num;
+ struct xtensa_reg_desc **contiguous_regs_desc;
+ struct reg **contiguous_regs_list;
+ /* Per-config Xtensa registers as specified via "xtreg" in xtensa-core*.cfg */
+ struct xtensa_reg_desc *optregs;
+ unsigned int num_optregs;
+ struct reg *empty_regs;
+ char qpkt_resp[XT_QUERYPKT_RESP_MAX];
/* An array of pointers to buffers to backup registers' values while algo is run on target.
* Size is 'regs_num'. */
void **algo_context_backup;
+ unsigned int eps_dbglevel_idx;
+ unsigned int dbregs_num;
struct target *target;
bool reset_asserted;
enum xtensa_stepping_isr_mode stepping_isr_mode;
@@ -204,11 +221,18 @@ struct xtensa {
bool permissive_mode; /* bypass memory checks */
bool suppress_dsr_errors;
uint32_t smp_break;
+ uint32_t spill_loc;
+ unsigned int spill_bytes;
+ uint8_t *spill_buf;
+ int8_t probe_lsddr32p;
/* Sometimes debug module's 'powered' bit is cleared after reset, but get set after some
* time.This is the number of polling periods after which core is considered to be powered
* off (marked as unexamined) if the bit retains to be cleared (e.g. if core is disabled by
* SW running on target).*/
uint8_t come_online_probes_num;
+ bool proc_syscall;
+ bool halt_request;
+ struct xtensa_keyval_info_s scratch_ars[XT_AR_SCRATCH_NUM];
bool regs_fetched; /* true after first register fetch completed successfully */
};
@@ -222,7 +246,6 @@ static inline struct xtensa *target_to_xtensa(struct target *target)
int xtensa_init_arch_info(struct target *target,
struct xtensa *xtensa,
- const struct xtensa_config *cfg,
const struct xtensa_debug_module_config *dm_cfg);
int xtensa_target_init(struct command_context *cmd_ctx, struct target *target);
void xtensa_target_deinit(struct target *target);
@@ -245,11 +268,41 @@ static inline bool xtensa_data_addr_valid(struct target *target, uint32_t addr)
return true;
if (xtensa_addr_in_mem(&xtensa->core_config->dram, addr))
return true;
- if (xtensa_addr_in_mem(&xtensa->core_config->uram, addr))
+ if (xtensa_addr_in_mem(&xtensa->core_config->sram, addr))
return true;
return false;
}
+static inline int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint8_t *data)
+{
+ struct xtensa_debug_module *dm = &xtensa->dbg_mod;
+
+ if (!xtensa->core_config->trace.enabled &&
+ (reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) {
+ LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg);
+ return ERROR_FAIL;
+ }
+ return dm->dbg_ops->queue_reg_read(dm, reg, data);
+}
+
+static inline int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint32_t data)
+{
+ struct xtensa_debug_module *dm = &xtensa->dbg_mod;
+
+ if (!xtensa->core_config->trace.enabled &&
+ (reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) {
+ LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg);
+ return ERROR_FAIL;
+ }
+ return dm->dbg_ops->queue_reg_write(dm, reg, data);
+}
+
+static inline int xtensa_core_status_clear(struct target *target, uint32_t bits)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ return xtensa_dm_core_status_clear(&xtensa->dbg_mod, bits);
+}
+
int xtensa_core_status_check(struct target *target);
int xtensa_examine(struct target *target);
@@ -260,11 +313,15 @@ int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set);
int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val);
xtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id);
void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg_val_t value);
+void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value);
int xtensa_fetch_all_regs(struct target *target);
int xtensa_get_gdb_reg_list(struct target *target,
struct reg **reg_list[],
int *reg_list_size,
enum target_register_class reg_class);
+uint32_t xtensa_cause_get(struct target *target);
+void xtensa_cause_clear(struct target *target);
+void xtensa_cause_reset(struct target *target);
int xtensa_poll(struct target *target);
void xtensa_on_poll(struct target *target);
int xtensa_halt(struct target *target);
@@ -293,17 +350,31 @@ int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t c
int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum);
int xtensa_assert_reset(struct target *target);
int xtensa_deassert_reset(struct target *target);
+int xtensa_soft_reset_halt(struct target *target);
int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint);
int xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint);
int xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint);
int xtensa_watchpoint_remove(struct target *target, struct watchpoint *watchpoint);
void xtensa_set_permissive_mode(struct target *target, bool state);
-int xtensa_fetch_user_regs_u32(struct target *target);
-int xtensa_queue_write_dirty_user_regs_u32(struct target *target);
const char *xtensa_get_gdb_arch(struct target *target);
+int xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p);
+
+COMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_xtopt_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_xtmem_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_xtmpu_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_xtmmu_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target);
+COMMAND_HELPER(xtensa_cmd_perfmon_dump_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_perfmon_enable_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_tracestart_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_tracestop_do, struct xtensa *xtensa);
+COMMAND_HELPER(xtensa_cmd_tracedump_do, struct xtensa *xtensa, const char *fname);
-extern const struct reg_arch_type xtensa_user_reg_u32_type;
-extern const struct reg_arch_type xtensa_user_reg_u128_type;
extern const struct command_registration xtensa_command_handlers[];
#endif /* OPENOCD_TARGET_XTENSA_H */
diff --git a/src/target/xtensa/xtensa_chip.c b/src/target/xtensa/xtensa_chip.c
new file mode 100644
index 0000000..c62992f
--- /dev/null
+++ b/src/target/xtensa/xtensa_chip.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * Xtensa Chip-level Target Support for OpenOCD *
+ * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "assert.h"
+#include <target/target.h>
+#include <target/target_type.h>
+#include <target/arm_adi_v5.h>
+#include <rtos/rtos.h>
+#include "xtensa_chip.h"
+
+int xtensa_chip_init_arch_info(struct target *target, void *arch_info,
+ struct xtensa_debug_module_config *dm_cfg)
+{
+ struct xtensa_chip_common *xtensa_chip = (struct xtensa_chip_common *)arch_info;
+ int ret = xtensa_init_arch_info(target, &xtensa_chip->xtensa, dm_cfg);
+ if (ret != ERROR_OK)
+ return ret;
+ /* All xtensa target structures point back to original xtensa_chip */
+ xtensa_chip->xtensa.xtensa_chip = arch_info;
+ return ERROR_OK;
+}
+
+int xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target)
+{
+ return xtensa_target_init(cmd_ctx, target);
+}
+
+int xtensa_chip_arch_state(struct target *target)
+{
+ return ERROR_OK;
+}
+
+static int xtensa_chip_poll(struct target *target)
+{
+ enum target_state old_state = target->state;
+ int ret = xtensa_poll(target);
+
+ if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
+ /*Call any event callbacks that are applicable */
+ if (old_state == TARGET_DEBUG_RUNNING)
+ target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
+ else
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+ }
+
+ return ret;
+}
+
+static int xtensa_chip_virt2phys(struct target *target,
+ target_addr_t virtual, target_addr_t *physical)
+{
+ if (physical) {
+ *physical = virtual;
+ return ERROR_OK;
+ }
+ return ERROR_FAIL;
+}
+
+static const struct xtensa_debug_ops xtensa_chip_dm_dbg_ops = {
+ .queue_enable = xtensa_dm_queue_enable,
+ .queue_reg_read = xtensa_dm_queue_reg_read,
+ .queue_reg_write = xtensa_dm_queue_reg_write
+};
+
+static const struct xtensa_power_ops xtensa_chip_dm_pwr_ops = {
+ .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
+ .queue_reg_write = xtensa_dm_queue_pwr_reg_write
+};
+
+static int xtensa_chip_target_create(struct target *target, Jim_Interp *interp)
+{
+ struct xtensa_debug_module_config xtensa_chip_dm_cfg = {
+ .dbg_ops = &xtensa_chip_dm_dbg_ops,
+ .pwr_ops = &xtensa_chip_dm_pwr_ops,
+ .tap = NULL,
+ .queue_tdi_idle = NULL,
+ .queue_tdi_idle_arg = NULL,
+ .dap = NULL,
+ .debug_ap = NULL,
+ .debug_apsel = DP_APSEL_INVALID,
+ .ap_offset = 0,
+ };
+
+ struct adiv5_private_config *pc = target->private_config;
+ if (adiv5_verify_config(pc) == ERROR_OK) {
+ xtensa_chip_dm_cfg.dap = pc->dap;
+ xtensa_chip_dm_cfg.debug_apsel = pc->ap_num;
+ xtensa_chip_dm_cfg.ap_offset = target->dbgbase;
+ LOG_DEBUG("DAP: ap_num %" PRId64 " DAP %p\n", pc->ap_num, pc->dap);
+ } else {
+ xtensa_chip_dm_cfg.tap = target->tap;
+ LOG_DEBUG("JTAG: %s:%s pos %d", target->tap->chip, target->tap->tapname,
+ target->tap->abs_chain_position);
+ }
+
+ struct xtensa_chip_common *xtensa_chip = calloc(1, sizeof(struct xtensa_chip_common));
+ if (!xtensa_chip) {
+ LOG_ERROR("Failed to alloc chip-level memory!");
+ return ERROR_FAIL;
+ }
+
+ int ret = xtensa_chip_init_arch_info(target, xtensa_chip, &xtensa_chip_dm_cfg);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Failed to init arch info!");
+ free(xtensa_chip);
+ return ret;
+ }
+
+ /*Assume running target. If different, the first poll will fix this. */
+ target->state = TARGET_RUNNING;
+ target->debug_reason = DBG_REASON_NOTHALTED;
+ return ERROR_OK;
+}
+
+static void xtensa_chip_target_deinit(struct target *target)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ xtensa_target_deinit(target);
+ free(xtensa->xtensa_chip);
+}
+
+static int xtensa_chip_examine(struct target *target)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ int retval = xtensa_dm_examine(&xtensa->dbg_mod);
+ if (retval == ERROR_OK)
+ retval = xtensa_examine(target);
+ return retval;
+}
+
+static int xtensa_chip_jim_configure(struct target *target, struct jim_getopt_info *goi)
+{
+ static bool dap_configured;
+ int ret = adiv5_jim_configure(target, goi);
+ if (ret == JIM_OK) {
+ LOG_DEBUG("xtensa '-dap' target option found");
+ dap_configured = true;
+ }
+ if (!dap_configured) {
+ LOG_DEBUG("xtensa '-dap' target option not yet found, assuming JTAG...");
+ target->has_dap = false;
+ }
+ return ret;
+}
+
+/** Methods for generic example of Xtensa-based chip-level targets. */
+struct target_type xtensa_chip_target = {
+ .name = "xtensa",
+
+ .poll = xtensa_chip_poll,
+ .arch_state = xtensa_chip_arch_state,
+
+ .halt = xtensa_halt,
+ .resume = xtensa_resume,
+ .step = xtensa_step,
+
+ .assert_reset = xtensa_assert_reset,
+ .deassert_reset = xtensa_deassert_reset,
+ .soft_reset_halt = xtensa_soft_reset_halt,
+
+ .virt2phys = xtensa_chip_virt2phys,
+ .mmu = xtensa_mmu_is_enabled,
+ .read_memory = xtensa_read_memory,
+ .write_memory = xtensa_write_memory,
+
+ .read_buffer = xtensa_read_buffer,
+ .write_buffer = xtensa_write_buffer,
+
+ .checksum_memory = xtensa_checksum_memory,
+
+ .get_gdb_reg_list = xtensa_get_gdb_reg_list,
+
+ .add_breakpoint = xtensa_breakpoint_add,
+ .remove_breakpoint = xtensa_breakpoint_remove,
+
+ .add_watchpoint = xtensa_watchpoint_add,
+ .remove_watchpoint = xtensa_watchpoint_remove,
+
+ .target_create = xtensa_chip_target_create,
+ .target_jim_configure = xtensa_chip_jim_configure,
+ .init_target = xtensa_chip_target_init,
+ .examine = xtensa_chip_examine,
+ .deinit_target = xtensa_chip_target_deinit,
+
+ .gdb_query_custom = xtensa_gdb_query_custom,
+
+ .commands = xtensa_command_handlers,
+};
diff --git a/src/target/xtensa/xtensa_chip.h b/src/target/xtensa/xtensa_chip.h
new file mode 100644
index 0000000..5200deb
--- /dev/null
+++ b/src/target/xtensa/xtensa_chip.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/***************************************************************************
+ * Xtensa Chip-level Target Support for OpenOCD *
+ * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
+ ***************************************************************************/
+
+#ifndef OPENOCD_TARGET_XTENSA_CHIP_H
+#define OPENOCD_TARGET_XTENSA_CHIP_H
+
+#include <target/target.h>
+#include "xtensa.h"
+#include "xtensa_debug_module.h"
+
+struct xtensa_chip_common {
+ struct xtensa xtensa;
+ /* Chip-specific extensions can be added here */
+};
+
+static inline struct xtensa_chip_common *target_to_xtensa_chip(struct target *target)
+{
+ return container_of(target->arch_info, struct xtensa_chip_common, xtensa);
+}
+
+int xtensa_chip_init_arch_info(struct target *target, void *arch_info,
+ struct xtensa_debug_module_config *dm_cfg);
+int xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target);
+int xtensa_chip_arch_state(struct target *target);
+void xtensa_chip_queue_tdi_idle(struct target *target);
+void xtensa_chip_on_reset(struct target *target);
+bool xtensa_chip_on_halt(struct target *target);
+void xtensa_chip_on_poll(struct target *target);
+
+#endif /* OPENOCD_TARGET_XTENSA_CHIP_H */
diff --git a/src/target/xtensa/xtensa_debug_module.c b/src/target/xtensa/xtensa_debug_module.c
index c6959ae..31d7a94 100644
--- a/src/target/xtensa/xtensa_debug_module.c
+++ b/src/target/xtensa/xtensa_debug_module.c
@@ -1,25 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
- * Generic Xtensa debug module API for OpenOCD *
+ * Xtensa Debug Module (XDM) Support for OpenOCD *
+ * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
* Copyright (C) 2019 Espressif Systems Ltd. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <helper/align.h>
#include "xtensa_debug_module.h"
#define TAPINS_PWRCTL 0x08
@@ -35,11 +26,18 @@
#define TAPINS_IDCODE_LEN 32
#define TAPINS_BYPASS_LEN 1
+/* Table of power register offsets for APB space */
+static const struct xtensa_dm_pwr_reg_offsets xdm_pwr_regs[XDMREG_PWRNUM] =
+ XTENSA_DM_PWR_REG_OFFSETS;
+
+/* Table of debug register offsets for Nexus and APB space */
+static const struct xtensa_dm_reg_offsets xdm_regs[XDMREG_NUM] =
+ XTENSA_DM_REG_OFFSETS;
static void xtensa_dm_add_set_ir(struct xtensa_debug_module *dm, uint8_t value)
{
struct scan_field field;
- uint8_t t[4] = { 0 };
+ uint8_t t[4] = { 0, 0, 0, 0 };
memset(&field, 0, sizeof(field));
field.num_bits = dm->tap->ir_length;
@@ -67,87 +65,167 @@ int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_mod
{
if (!dm || !cfg)
return ERROR_FAIL;
+ if (!IS_ALIGNED(cfg->ap_offset, XTENSA_DM_APB_ALIGN)) {
+ LOG_ERROR("Xtensa DM APB offset must be aligned to a %dKB multiple",
+ XTENSA_DM_APB_ALIGN / 1024);
+ return ERROR_FAIL;
+ }
dm->pwr_ops = cfg->pwr_ops;
dm->dbg_ops = cfg->dbg_ops;
dm->tap = cfg->tap;
dm->queue_tdi_idle = cfg->queue_tdi_idle;
dm->queue_tdi_idle_arg = cfg->queue_tdi_idle_arg;
+ dm->dap = cfg->dap;
+ dm->debug_ap = cfg->debug_ap;
+ dm->debug_apsel = cfg->debug_apsel;
+ dm->ap_offset = cfg->ap_offset;
return ERROR_OK;
}
-int xtensa_dm_queue_enable(struct xtensa_debug_module *dm)
+void xtensa_dm_deinit(struct xtensa_debug_module *dm)
{
- return dm->dbg_ops->queue_reg_write(dm, NARADR_DCRSET, OCDDCR_ENABLEOCD);
+ if (dm->debug_ap) {
+ dap_put_ap(dm->debug_ap);
+ dm->debug_ap = NULL;
+ }
}
-int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *value)
+int xtensa_dm_poll(struct xtensa_debug_module *dm)
{
- uint8_t regdata = (reg << 1) | 0;
- uint8_t dummy[4] = { 0, 0, 0, 0 };
+ /* 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.
+ */
+ return (!dm || (dm->dap && !dm->debug_ap)) ? ERROR_FAIL : ERROR_OK;
+}
+
+int xtensa_dm_examine(struct xtensa_debug_module *dm)
+{
+ struct adiv5_dap *swjdp = dm->dap;
+ int retval = ERROR_OK;
+
+ if (swjdp) {
+ LOG_DEBUG("DM examine: DAP AP select %d", dm->debug_apsel);
+ if (dm->debug_ap) {
+ dap_put_ap(dm->debug_ap);
+ dm->debug_ap = NULL;
+ }
+ if (dm->debug_apsel == DP_APSEL_INVALID) {
+ LOG_DEBUG("DM examine: search for APB-type MEM-AP...");
+ /* TODO: Determine whether AP_TYPE_AXI_AP APs can be supported... */
+ retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &dm->debug_ap);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Could not find MEM-AP to control the core");
+ return retval;
+ }
+ } else {
+ dm->debug_ap = dap_get_ap(swjdp, dm->debug_apsel);
+ }
+
+ /* TODO: Allow a user-specified AP instead of relying on AP_TYPE_APB_AP */
+ dm->debug_apsel = dm->debug_ap->ap_num;
+ LOG_DEBUG("DM examine: Setting apsel to %d", dm->debug_apsel);
+
+ /* Leave (only) generic DAP stuff for debugport_init(); */
+ dm->debug_ap->memaccess_tck = 8;
+
+ retval = mem_ap_init(dm->debug_ap);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("MEM-AP init failed: %d", retval);
+ return retval;
+ }
+
+ /* TODO: how to set autoincrement range? Hard-code it to 1024 bytes for now */
+ dm->debug_ap->tar_autoincr_block = (1 << 10);
+ }
+
+ return retval;
+}
- if (reg > NARADR_MAX) {
+int xtensa_dm_queue_enable(struct xtensa_debug_module *dm)
+{
+ return dm->dbg_ops->queue_reg_write(dm, XDMREG_DCRSET, OCDDCR_ENABLEOCD);
+}
+
+int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value)
+{
+ if (reg >= XDMREG_NUM) {
LOG_ERROR("Invalid DBG reg ID %d!", reg);
return ERROR_FAIL;
}
+ if (dm->dap)
+ /* NOTE: Future optimization: mem_ap_read_u32() offers higher performance with
+ * queued reads, but requires an API change to pass value as a 32-bit pointer.
+ */
+ return mem_ap_read_buf(dm->debug_ap, value, 4, 1, xdm_regs[reg].apb + dm->ap_offset);
+ uint8_t regdata = (xdm_regs[reg].nar << 1) | 0;
+ uint8_t dummy[4] = { 0, 0, 0, 0 };
xtensa_dm_add_set_ir(dm, TAPINS_NARSEL);
xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_ADRLEN, &regdata, NULL, TAP_IDLE);
xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_DATALEN, dummy, value, TAP_IDLE);
return ERROR_OK;
}
-int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint32_t value)
+int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value)
{
- uint8_t regdata = (reg << 1) | 1;
- uint8_t valdata[] = { value, value >> 8, value >> 16, value >> 24 };
-
- if (reg > NARADR_MAX) {
+ if (reg >= XDMREG_NUM) {
LOG_ERROR("Invalid DBG reg ID %d!", reg);
return ERROR_FAIL;
}
+ if (dm->dap)
+ return mem_ap_write_u32(dm->debug_ap, xdm_regs[reg].apb + dm->ap_offset, value);
+ uint8_t regdata = (xdm_regs[reg].nar << 1) | 1;
+ uint8_t valdata[] = { value, value >> 8, value >> 16, value >> 24 };
xtensa_dm_add_set_ir(dm, TAPINS_NARSEL);
xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_ADRLEN, &regdata, NULL, TAP_IDLE);
xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_DATALEN, valdata, NULL, TAP_IDLE);
return ERROR_OK;
}
-int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, uint8_t clear)
+int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm,
+ enum xtensa_dm_pwr_reg reg,
+ uint8_t *data,
+ uint32_t clear)
{
- uint8_t value_clr = clear;
- uint8_t tap_insn;
- int tap_insn_sz;
-
- if (reg == DMREG_PWRCTL) {
- tap_insn = TAPINS_PWRCTL;
- tap_insn_sz = TAPINS_PWRCTL_LEN;
- } else if (reg == DMREG_PWRSTAT) {
- tap_insn = TAPINS_PWRSTAT;
- tap_insn_sz = TAPINS_PWRSTAT_LEN;
- } else {
+ if (reg >= XDMREG_PWRNUM) {
LOG_ERROR("Invalid PWR reg ID %d!", reg);
return ERROR_FAIL;
}
+ if (dm->dap) {
+ /* NOTE: Future optimization: mem_ap_read_u32() offers higher performance with
+ * queued reads, but requires an API change to pass value as a 32-bit pointer.
+ */
+ uint32_t apbreg = xdm_pwr_regs[reg].apb + dm->ap_offset;
+ int retval = mem_ap_read_buf(dm->debug_ap, data, 4, 1, apbreg);
+ if (retval == ERROR_OK)
+ retval = mem_ap_write_u32(dm->debug_ap, apbreg, clear);
+ return retval;
+ }
+ uint8_t value_clr = (uint8_t)clear;
+ uint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT;
+ int tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN;
xtensa_dm_add_set_ir(dm, tap_insn);
xtensa_dm_add_dr_scan(dm, tap_insn_sz, &value_clr, data, TAP_IDLE);
return ERROR_OK;
}
-int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data)
+int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm,
+ enum xtensa_dm_pwr_reg reg,
+ uint32_t data)
{
- uint8_t value = data;
- uint8_t tap_insn;
- int tap_insn_sz;
-
- if (reg == DMREG_PWRCTL) {
- tap_insn = TAPINS_PWRCTL;
- tap_insn_sz = TAPINS_PWRCTL_LEN;
- } else if (reg == DMREG_PWRSTAT) {
- tap_insn = TAPINS_PWRSTAT;
- tap_insn_sz = TAPINS_PWRSTAT_LEN;
- } else {
+ if (reg >= XDMREG_PWRNUM) {
LOG_ERROR("Invalid PWR reg ID %d!", reg);
return ERROR_FAIL;
}
+ if (dm->dap) {
+ uint32_t apbreg = xdm_pwr_regs[reg].apb + dm->ap_offset;
+ return mem_ap_write_u32(dm->debug_ap, apbreg, data);
+ }
+ uint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT;
+ int tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN;
+ uint8_t value = (uint8_t)data;
xtensa_dm_add_set_ir(dm, tap_insn);
xtensa_dm_add_dr_scan(dm, tap_insn_sz, &value, NULL, TAP_IDLE);
return ERROR_OK;
@@ -157,9 +235,9 @@ int xtensa_dm_device_id_read(struct xtensa_debug_module *dm)
{
uint8_t id_buf[sizeof(uint32_t)];
- dm->dbg_ops->queue_reg_read(dm, NARADR_OCDID, id_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
dm->device_id = buf_get_u32(id_buf, 0, 32);
@@ -168,16 +246,22 @@ int xtensa_dm_device_id_read(struct xtensa_debug_module *dm)
int xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear)
{
- /* uint8_t id_buf[sizeof(uint32_t)]; */
+ uint8_t stat_buf[sizeof(uint32_t)] = { 0, 0, 0, 0 };
+ uint8_t stath_buf[sizeof(uint32_t)] = { 0, 0, 0, 0 };
/* TODO: JTAG does not work when PWRCTL_JTAGDEBUGUSE is not set.
- * It is set in xtensa_examine(), need to move reading of NARADR_OCDID out of this function */
- /* dm->dbg_ops->queue_reg_read(dm, NARADR_OCDID, id_buf);
+ * It is set in xtensa_examine(), need to move reading of XDMREG_OCDID out of this function */
+ /* dm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf);
*Read reset state */
- dm->pwr_ops->queue_reg_read(dm, DMREG_PWRSTAT, &dm->power_status.stat, clear);
- dm->pwr_ops->queue_reg_read(dm, DMREG_PWRSTAT, &dm->power_status.stath, clear);
+ dm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stat_buf, clear);
+ dm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stath_buf, clear);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
+ if (res != ERROR_OK)
+ return res;
+ dm->power_status.stat = buf_get_u32(stat_buf, 0, 32);
+ dm->power_status.stath = buf_get_u32(stath_buf, 0, 32);
+ return res;
}
int xtensa_dm_core_status_read(struct xtensa_debug_module *dm)
@@ -185,9 +269,9 @@ int xtensa_dm_core_status_read(struct xtensa_debug_module *dm)
uint8_t dsr_buf[sizeof(uint32_t)];
xtensa_dm_queue_enable(dm);
- dm->dbg_ops->queue_reg_read(dm, NARADR_DSR, dsr_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_DSR, dsr_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
dm->core_status.dsr = buf_get_u32(dsr_buf, 0, 32);
@@ -196,37 +280,37 @@ int xtensa_dm_core_status_read(struct xtensa_debug_module *dm)
int xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bits)
{
- dm->dbg_ops->queue_reg_write(dm, NARADR_DSR, bits);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_DSR, bits);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(dm);
}
int xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg)
{
/*Turn off trace unit so we can start a new trace. */
- dm->dbg_ops->queue_reg_write(dm, NARADR_TRAXCTRL, 0);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXCTRL, 0);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
/*Set up parameters */
- dm->dbg_ops->queue_reg_write(dm, NARADR_TRAXADDR, 0);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXADDR, 0);
if (cfg->stopmask != XTENSA_STOPMASK_DISABLED) {
- dm->dbg_ops->queue_reg_write(dm, NARADR_PCMATCHCTRL,
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_PCMATCHCTRL,
(cfg->stopmask << PCMATCHCTRL_PCML_SHIFT));
- dm->dbg_ops->queue_reg_write(dm, NARADR_TRIGGERPC, cfg->stoppc);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_TRIGGERPC, cfg->stoppc);
}
- dm->dbg_ops->queue_reg_write(dm, NARADR_DELAYCNT, cfg->after);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_DELAYCNT, cfg->after);
/*Options are mostly hardcoded for now. ToDo: make this more configurable. */
dm->dbg_ops->queue_reg_write(
dm,
- NARADR_TRAXCTRL,
+ XDMREG_TRAXCTRL,
TRAXCTRL_TREN |
((cfg->stopmask != XTENSA_STOPMASK_DISABLED) ? TRAXCTRL_PCMEN : 0) | TRAXCTRL_TMEN |
(cfg->after_is_words ? 0 : TRAXCTRL_CNTU) | (0 << TRAXCTRL_SMPER_SHIFT) | TRAXCTRL_PTOWS);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(dm);
}
int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable)
@@ -235,9 +319,9 @@ int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable)
uint32_t traxctl;
struct xtensa_trace_status trace_status;
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXCTRL, traxctl_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
traxctl = buf_get_u32(traxctl_buf, 0, 32);
@@ -245,9 +329,9 @@ int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable)
if (!pto_enable)
traxctl &= ~(TRAXCTRL_PTOWS | TRAXCTRL_PTOWT);
- dm->dbg_ops->queue_reg_write(dm, NARADR_TRAXCTRL, traxctl | TRAXCTRL_TRSTP);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXCTRL, traxctl | TRAXCTRL_TRSTP);
xtensa_dm_queue_tdi_idle(dm);
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
@@ -267,9 +351,9 @@ int xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_tr
{
uint8_t traxstat_buf[sizeof(uint32_t)];
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXSTAT, traxstat_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXSTAT, traxstat_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res == ERROR_OK && status)
status->stat = buf_get_u32(traxstat_buf, 0, 32);
return res;
@@ -285,12 +369,12 @@ int xtensa_dm_trace_config_read(struct xtensa_debug_module *dm, struct xtensa_tr
if (!config)
return ERROR_FAIL;
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXCTRL, traxctl_buf);
- dm->dbg_ops->queue_reg_read(dm, NARADR_MEMADDRSTART, memadrstart_buf);
- dm->dbg_ops->queue_reg_read(dm, NARADR_MEMADDREND, memadrend_buf);
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXADDR, adr_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDRSTART, memadrstart_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDREND, memadrend_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXADDR, adr_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res == ERROR_OK) {
config->ctrl = buf_get_u32(traxctl_buf, 0, 32);
config->memaddr_start = buf_get_u32(memadrstart_buf, 0, 32);
@@ -306,9 +390,9 @@ int xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uin
return ERROR_FAIL;
for (unsigned int i = 0; i < size / 4; i++)
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXDATA, &dest[i * 4]);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXDATA, &dest[i * 4]);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(dm);
}
int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id,
@@ -324,13 +408,13 @@ int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id,
(config->kernelcnt << 3);
/* enable performance monitor */
- dm->dbg_ops->queue_reg_write(dm, NARADR_PMG, 0x1);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_PMG, 0x1);
/* reset counter */
- dm->dbg_ops->queue_reg_write(dm, NARADR_PM0 + counter_id, 0);
- dm->dbg_ops->queue_reg_write(dm, NARADR_PMCTRL0 + counter_id, pmctrl);
- dm->dbg_ops->queue_reg_read(dm, NARADR_PMSTAT0 + counter_id, pmstat_buf);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_PM0 + counter_id, 0);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_PMCTRL0 + counter_id, pmctrl);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(dm);
}
int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id,
@@ -339,10 +423,10 @@ int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id,
uint8_t pmstat_buf[4];
uint8_t pmcount_buf[4];
- dm->dbg_ops->queue_reg_read(dm, NARADR_PMSTAT0 + counter_id, pmstat_buf);
- dm->dbg_ops->queue_reg_read(dm, NARADR_PM0 + counter_id, pmcount_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_PM0 + counter_id, pmcount_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res == ERROR_OK) {
uint32_t stat = buf_get_u32(pmstat_buf, 0, 32);
uint64_t result = buf_get_u32(pmcount_buf, 0, 32);
diff --git a/src/target/xtensa/xtensa_debug_module.h b/src/target/xtensa/xtensa_debug_module.h
index 692f0f6..b382e03 100644
--- a/src/target/xtensa/xtensa_debug_module.h
+++ b/src/target/xtensa/xtensa_debug_module.h
@@ -1,36 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
- * Xtensa debug module API *
+ * Xtensa Debug Module (XDM) Support for OpenOCD *
+ * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
* Copyright (C) 2019 Espressif Systems Ltd. *
- * <alexey@espressif.com> *
- * *
* Derived from original ESP8266 target. *
- * Copyright (C) 2015 by Angus Gratton *
- * gus@projectgus.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ * Author: Angus Gratton gus@projectgus.com *
***************************************************************************/
#ifndef OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
#define OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
#include <jtag/jtag.h>
+#include <target/arm_adi_v5.h>
#include <helper/bits.h>
#include <target/target.h>
/* Virtual IDs for using with xtensa_power_ops API */
-#define DMREG_PWRCTL 0x00
-#define DMREG_PWRSTAT 0x01
+enum xtensa_dm_pwr_reg {
+ XDMREG_PWRCTL = 0x00,
+ XDMREG_PWRSTAT,
+ XDMREG_PWRNUM
+};
+
+/* Debug Module Power Register offsets within APB */
+struct xtensa_dm_pwr_reg_offsets {
+ uint16_t apb;
+};
+
+/* Debug Module Power Register offset structure; must include XDMREG_PWRNUM entries */
+#define XTENSA_DM_PWR_REG_OFFSETS { \
+ /* Power/Reset Registers */ \
+ { .apb = 0x3020 }, /* XDMREG_PWRCTL */ \
+ { .apb = 0x3024 }, /* XDMREG_PWRSTAT */ \
+}
/*
From the manual:
@@ -43,81 +46,203 @@
Module to happen correctly. When it is set, any write to this bit clears it.
Either don't access it, or re-write it to 1 so JTAG accesses continue.
*/
-#define PWRCTL_JTAGDEBUGUSE BIT(7)
-#define PWRCTL_DEBUGRESET BIT(6)
-#define PWRCTL_CORERESET BIT(4)
-#define PWRCTL_DEBUGWAKEUP BIT(2)
-#define PWRCTL_MEMWAKEUP BIT(1)
-#define PWRCTL_COREWAKEUP BIT(0)
-
-#define PWRSTAT_DEBUGWASRESET BIT(6)
-#define PWRSTAT_COREWASRESET BIT(4)
-#define PWRSTAT_CORESTILLNEEDED BIT(3)
-#define PWRSTAT_DEBUGDOMAINON BIT(2)
-#define PWRSTAT_MEMDOMAINON BIT(1)
-#define PWRSTAT_COREDOMAINON BIT(0)
-
-/* *** NAR addresses (also used as IDs for debug registers in xtensa_debug_ops API) ***
- *TRAX registers */
-#define NARADR_TRAXID 0x00
-#define NARADR_TRAXCTRL 0x01
-#define NARADR_TRAXSTAT 0x02
-#define NARADR_TRAXDATA 0x03
-#define NARADR_TRAXADDR 0x04
-#define NARADR_TRIGGERPC 0x05
-#define NARADR_PCMATCHCTRL 0x06
-#define NARADR_DELAYCNT 0x07
-#define NARADR_MEMADDRSTART 0x08
-#define NARADR_MEMADDREND 0x09
-/*Performance monitor registers */
-#define NARADR_PMG 0x20
-#define NARADR_INTPC 0x24
-#define NARADR_PM0 0x28
-/*... */
-#define NARADR_PM7 0x2F
-#define NARADR_PMCTRL0 0x30
-/*... */
-#define NARADR_PMCTRL7 0x37
-#define NARADR_PMSTAT0 0x38
-/*... */
-#define NARADR_PMSTAT7 0x3F
-/*OCD registers */
-#define NARADR_OCDID 0x40
-#define NARADR_DCRCLR 0x42
-#define NARADR_DCRSET 0x43
-#define NARADR_DSR 0x44
-#define NARADR_DDR 0x45
-#define NARADR_DDREXEC 0x46
-#define NARADR_DIR0EXEC 0x47
-#define NARADR_DIR0 0x48
-#define NARADR_DIR1 0x49
-/*... */
-#define NARADR_DIR7 0x4F
-/*Misc registers */
-#define NARADR_PWRCTL 0x58
-#define NARADR_PWRSTAT 0x59
-#define NARADR_ERISTAT 0x5A
-/*CoreSight registers */
-#define NARADR_ITCTRL 0x60
-#define NARADR_CLAIMSET 0x68
-#define NARADR_CLAIMCLR 0x69
-#define NARADR_LOCKACCESS 0x6c
-#define NARADR_LOCKSTATUS 0x6d
-#define NARADR_AUTHSTATUS 0x6e
-#define NARADR_DEVID 0x72
-#define NARADR_DEVTYPE 0x73
-#define NARADR_PERID4 0x74
-/*... */
-#define NARADR_PERID7 0x77
-#define NARADR_PERID0 0x78
-/*... */
-#define NARADR_PERID3 0x7b
-#define NARADR_COMPID0 0x7c
-/*... */
-#define NARADR_COMPID3 0x7f
-#define NARADR_MAX NARADR_COMPID3
-
-/*OCD registers, bit definitions */
+#define PWRCTL_JTAGDEBUGUSE(x) (((x)->dbg_mod.dap) ? (0) : BIT(7))
+#define PWRCTL_DEBUGRESET(x) (((x)->dbg_mod.dap) ? BIT(28) : BIT(6))
+#define PWRCTL_CORERESET(x) (((x)->dbg_mod.dap) ? BIT(16) : BIT(4))
+#define PWRCTL_DEBUGWAKEUP(x) (((x)->dbg_mod.dap) ? BIT(12) : BIT(2))
+#define PWRCTL_MEMWAKEUP(x) (((x)->dbg_mod.dap) ? BIT(8) : BIT(1))
+#define PWRCTL_COREWAKEUP(x) (((x)->dbg_mod.dap) ? BIT(0) : BIT(0))
+
+#define PWRSTAT_DEBUGWASRESET_DM(d) (((d)->dap) ? BIT(28) : BIT(6))
+#define PWRSTAT_COREWASRESET_DM(d) (((d)->dap) ? BIT(16) : BIT(4))
+#define PWRSTAT_DEBUGWASRESET(x) (PWRSTAT_DEBUGWASRESET_DM(&((x)->dbg_mod)))
+#define PWRSTAT_COREWASRESET(x) (PWRSTAT_COREWASRESET_DM(&((x)->dbg_mod)))
+#define PWRSTAT_CORESTILLNEEDED(x) (((x)->dbg_mod.dap) ? BIT(4) : BIT(3))
+#define PWRSTAT_DEBUGDOMAINON(x) (((x)->dbg_mod.dap) ? BIT(12) : BIT(2))
+#define PWRSTAT_MEMDOMAINON(x) (((x)->dbg_mod.dap) ? BIT(8) : BIT(1))
+#define PWRSTAT_COREDOMAINON(x) (((x)->dbg_mod.dap) ? BIT(0) : BIT(0))
+
+/* Virtual IDs for using with xtensa_debug_ops API */
+enum xtensa_dm_reg {
+ /* TRAX Registers */
+ XDMREG_TRAXID = 0x00,
+ XDMREG_TRAXCTRL,
+ XDMREG_TRAXSTAT,
+ XDMREG_TRAXDATA,
+ XDMREG_TRAXADDR,
+ XDMREG_TRIGGERPC,
+ XDMREG_PCMATCHCTRL,
+ XDMREG_DELAYCNT,
+ XDMREG_MEMADDRSTART,
+ XDMREG_MEMADDREND,
+
+ /* Performance Monitor Registers */
+ XDMREG_PMG,
+ XDMREG_INTPC,
+ XDMREG_PM0,
+ XDMREG_PM1,
+ XDMREG_PM2,
+ XDMREG_PM3,
+ XDMREG_PM4,
+ XDMREG_PM5,
+ XDMREG_PM6,
+ XDMREG_PM7,
+ XDMREG_PMCTRL0,
+ XDMREG_PMCTRL1,
+ XDMREG_PMCTRL2,
+ XDMREG_PMCTRL3,
+ XDMREG_PMCTRL4,
+ XDMREG_PMCTRL5,
+ XDMREG_PMCTRL6,
+ XDMREG_PMCTRL7,
+ XDMREG_PMSTAT0,
+ XDMREG_PMSTAT1,
+ XDMREG_PMSTAT2,
+ XDMREG_PMSTAT3,
+ XDMREG_PMSTAT4,
+ XDMREG_PMSTAT5,
+ XDMREG_PMSTAT6,
+ XDMREG_PMSTAT7,
+
+ /* OCD Registers */
+ XDMREG_OCDID,
+ XDMREG_DCRCLR,
+ XDMREG_DCRSET,
+ XDMREG_DSR,
+ XDMREG_DDR,
+ XDMREG_DDREXEC,
+ XDMREG_DIR0EXEC,
+ XDMREG_DIR0,
+ XDMREG_DIR1,
+ XDMREG_DIR2,
+ XDMREG_DIR3,
+ XDMREG_DIR4,
+ XDMREG_DIR5,
+ XDMREG_DIR6,
+ XDMREG_DIR7,
+
+ /* Misc Registers */
+ XDMREG_ERISTAT,
+
+ /* CoreSight Registers */
+ XDMREG_ITCTRL,
+ XDMREG_CLAIMSET,
+ XDMREG_CLAIMCLR,
+ XDMREG_LOCKACCESS,
+ XDMREG_LOCKSTATUS,
+ XDMREG_AUTHSTATUS,
+ XDMREG_DEVID,
+ XDMREG_DEVTYPE,
+ XDMREG_PERID4,
+ XDMREG_PERID5,
+ XDMREG_PERID6,
+ XDMREG_PERID7,
+ XDMREG_PERID0,
+ XDMREG_PERID1,
+ XDMREG_PERID2,
+ XDMREG_PERID3,
+ XDMREG_COMPID0,
+ XDMREG_COMPID1,
+ XDMREG_COMPID2,
+ XDMREG_COMPID3,
+
+ XDMREG_NUM
+};
+
+/* Debug Module Register offsets within Nexus (NAR) or APB */
+struct xtensa_dm_reg_offsets {
+ uint8_t nar;
+ uint16_t apb;
+};
+
+/* Debug Module Register offset structure; must include XDMREG_NUM entries */
+#define XTENSA_DM_REG_OFFSETS { \
+ /* TRAX Registers */ \
+ { .nar = 0x00, .apb = 0x0000 }, /* XDMREG_TRAXID */ \
+ { .nar = 0x01, .apb = 0x0004 }, /* XDMREG_TRAXCTRL */ \
+ { .nar = 0x02, .apb = 0x0008 }, /* XDMREG_TRAXSTAT */ \
+ { .nar = 0x03, .apb = 0x000c }, /* XDMREG_TRAXDATA */ \
+ { .nar = 0x04, .apb = 0x0010 }, /* XDMREG_TRAXADDR */ \
+ { .nar = 0x05, .apb = 0x0014 }, /* XDMREG_TRIGGERPC */ \
+ { .nar = 0x06, .apb = 0x0018 }, /* XDMREG_PCMATCHCTRL */ \
+ { .nar = 0x07, .apb = 0x001c }, /* XDMREG_DELAYCNT */ \
+ { .nar = 0x08, .apb = 0x0020 }, /* XDMREG_MEMADDRSTART */ \
+ { .nar = 0x09, .apb = 0x0024 }, /* XDMREG_MEMADDREND */ \
+ \
+ /* Performance Monitor Registers */ \
+ { .nar = 0x20, .apb = 0x1000 }, /* XDMREG_PMG */ \
+ { .nar = 0x24, .apb = 0x1010 }, /* XDMREG_INTPC */ \
+ { .nar = 0x28, .apb = 0x1080 }, /* XDMREG_PM0 */ \
+ { .nar = 0x29, .apb = 0x1084 }, /* XDMREG_PM1 */ \
+ { .nar = 0x2a, .apb = 0x1088 }, /* XDMREG_PM2 */ \
+ { .nar = 0x2b, .apb = 0x108c }, /* XDMREG_PM3 */ \
+ { .nar = 0x2c, .apb = 0x1090 }, /* XDMREG_PM4 */ \
+ { .nar = 0x2d, .apb = 0x1094 }, /* XDMREG_PM5 */ \
+ { .nar = 0x2e, .apb = 0x1098 }, /* XDMREG_PM6 */ \
+ { .nar = 0x2f, .apb = 0x109c }, /* XDMREG_PM7 */ \
+ { .nar = 0x30, .apb = 0x1100 }, /* XDMREG_PMCTRL0 */ \
+ { .nar = 0x31, .apb = 0x1104 }, /* XDMREG_PMCTRL1 */ \
+ { .nar = 0x32, .apb = 0x1108 }, /* XDMREG_PMCTRL2 */ \
+ { .nar = 0x33, .apb = 0x110c }, /* XDMREG_PMCTRL3 */ \
+ { .nar = 0x34, .apb = 0x1110 }, /* XDMREG_PMCTRL4 */ \
+ { .nar = 0x35, .apb = 0x1114 }, /* XDMREG_PMCTRL5 */ \
+ { .nar = 0x36, .apb = 0x1118 }, /* XDMREG_PMCTRL6 */ \
+ { .nar = 0x37, .apb = 0x111c }, /* XDMREG_PMCTRL7 */ \
+ { .nar = 0x38, .apb = 0x1180 }, /* XDMREG_PMSTAT0 */ \
+ { .nar = 0x39, .apb = 0x1184 }, /* XDMREG_PMSTAT1 */ \
+ { .nar = 0x3a, .apb = 0x1188 }, /* XDMREG_PMSTAT2 */ \
+ { .nar = 0x3b, .apb = 0x118c }, /* XDMREG_PMSTAT3 */ \
+ { .nar = 0x3c, .apb = 0x1190 }, /* XDMREG_PMSTAT4 */ \
+ { .nar = 0x3d, .apb = 0x1194 }, /* XDMREG_PMSTAT5 */ \
+ { .nar = 0x3e, .apb = 0x1198 }, /* XDMREG_PMSTAT6 */ \
+ { .nar = 0x3f, .apb = 0x119c }, /* XDMREG_PMSTAT7 */ \
+ \
+ /* OCD Registers */ \
+ { .nar = 0x40, .apb = 0x2000 }, /* XDMREG_OCDID */ \
+ { .nar = 0x42, .apb = 0x2008 }, /* XDMREG_DCRCLR */ \
+ { .nar = 0x43, .apb = 0x200c }, /* XDMREG_DCRSET */ \
+ { .nar = 0x44, .apb = 0x2010 }, /* XDMREG_DSR */ \
+ { .nar = 0x45, .apb = 0x2014 }, /* XDMREG_DDR */ \
+ { .nar = 0x46, .apb = 0x2018 }, /* XDMREG_DDREXEC */ \
+ { .nar = 0x47, .apb = 0x201c }, /* XDMREG_DIR0EXEC */ \
+ { .nar = 0x48, .apb = 0x2020 }, /* XDMREG_DIR0 */ \
+ { .nar = 0x49, .apb = 0x2024 }, /* XDMREG_DIR1 */ \
+ { .nar = 0x4a, .apb = 0x2028 }, /* XDMREG_DIR2 */ \
+ { .nar = 0x4b, .apb = 0x202c }, /* XDMREG_DIR3 */ \
+ { .nar = 0x4c, .apb = 0x2030 }, /* XDMREG_DIR4 */ \
+ { .nar = 0x4d, .apb = 0x2034 }, /* XDMREG_DIR5 */ \
+ { .nar = 0x4e, .apb = 0x2038 }, /* XDMREG_DIR6 */ \
+ { .nar = 0x4f, .apb = 0x203c }, /* XDMREG_DIR7 */ \
+ \
+ /* Misc Registers */ \
+ { .nar = 0x5a, .apb = 0x3028 }, /* XDMREG_ERISTAT */ \
+ \
+ /* CoreSight Registers */ \
+ { .nar = 0x60, .apb = 0x3f00 }, /* XDMREG_ITCTRL */ \
+ { .nar = 0x68, .apb = 0x3fa0 }, /* XDMREG_CLAIMSET */ \
+ { .nar = 0x69, .apb = 0x3fa4 }, /* XDMREG_CLAIMCLR */ \
+ { .nar = 0x6c, .apb = 0x3fb0 }, /* XDMREG_LOCKACCESS */ \
+ { .nar = 0x6d, .apb = 0x3fb4 }, /* XDMREG_LOCKSTATUS */ \
+ { .nar = 0x6e, .apb = 0x3fb8 }, /* XDMREG_AUTHSTATUS */ \
+ { .nar = 0x72, .apb = 0x3fc8 }, /* XDMREG_DEVID */ \
+ { .nar = 0x73, .apb = 0x3fcc }, /* XDMREG_DEVTYPE */ \
+ { .nar = 0x74, .apb = 0x3fd0 }, /* XDMREG_PERID4 */ \
+ { .nar = 0x75, .apb = 0x3fd4 }, /* XDMREG_PERID5 */ \
+ { .nar = 0x76, .apb = 0x3fd8 }, /* XDMREG_PERID6 */ \
+ { .nar = 0x77, .apb = 0x3fdc }, /* XDMREG_PERID7 */ \
+ { .nar = 0x78, .apb = 0x3fe0 }, /* XDMREG_PERID0 */ \
+ { .nar = 0x79, .apb = 0x3fe4 }, /* XDMREG_PERID1 */ \
+ { .nar = 0x7a, .apb = 0x3fe8 }, /* XDMREG_PERID2 */ \
+ { .nar = 0x7b, .apb = 0x3fec }, /* XDMREG_PERID3 */ \
+ { .nar = 0x7c, .apb = 0x3ff0 }, /* XDMREG_COMPID0 */ \
+ { .nar = 0x7d, .apb = 0x3ff4 }, /* XDMREG_COMPID1 */ \
+ { .nar = 0x7e, .apb = 0x3ff8 }, /* XDMREG_COMPID2 */ \
+ { .nar = 0x7f, .apb = 0x3ffc }, /* XDMREG_COMPID3 */ \
+}
+
+#define XTENSA_DM_APB_ALIGN 0x4000
+
+/* OCD registers, bit definitions */
#define OCDDCR_ENABLEOCD BIT(0)
#define OCDDCR_DEBUGINTERRUPT BIT(1)
#define OCDDCR_INTERRUPTALLCONDS BIT(2)
@@ -164,7 +289,7 @@
#define TRAXCTRL_CTIEN BIT(5) /* Cross-trigger enable */
#define TRAXCTRL_TMEN BIT(7) /* Tracemem Enable. Always set. */
#define TRAXCTRL_CNTU BIT(9) /* Post-stop-trigger countdown units; selects when DelayCount-- happens.
- *0 - every 32-bit word written to tracemem, 1 - every cpu instruction */
+ * 0 - every 32-bit word written to tracemem, 1 - every cpu instruction */
#define TRAXCTRL_TSEN BIT(11) /* Undocumented/deprecated? */
#define TRAXCTRL_SMPER_SHIFT 12 /* Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg */
#define TRAXCTRL_SMPER_MASK 0x07 /* Synchronization message period */
@@ -202,7 +327,7 @@
#define PCMATCHCTRL_PCML_SHIFT 0 /* Amount of lower bits to ignore in pc trigger register */
#define PCMATCHCTRL_PCML_MASK 0x1F
#define PCMATCHCTRL_PCMS BIT(31) /* PC Match Sense, 0-match when procs PC is in-range, 1-match when
- *out-of-range */
+ * out-of-range */
#define XTENSA_MAX_PERF_COUNTERS 2
#define XTENSA_MAX_PERF_SELECT 32
@@ -216,20 +341,24 @@ struct xtensa_debug_ops {
/** enable operation */
int (*queue_enable)(struct xtensa_debug_module *dm);
/** register read. */
- int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data);
+ int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *data);
/** register write. */
- int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint32_t data);
+ int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t data);
};
+/* Xtensa power registers are 8 bits wide on JTAG interfaces but 32 bits wide
+ * when accessed via APB/DAP. In order to use DAP queuing APIs (for optimal
+ * performance), the XDM power register APIs take 32-bit register params.
+ */
struct xtensa_power_ops {
/** register read. */
- int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data,
- uint8_t clear);
+ int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint8_t *data,
+ uint32_t clear);
/** register write. */
- int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data);
+ int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint32_t data);
};
-typedef uint8_t xtensa_pwrstat_t;
+typedef uint32_t xtensa_pwrstat_t;
typedef uint32_t xtensa_ocdid_t;
typedef uint32_t xtensa_dsr_t;
typedef uint32_t xtensa_traxstat_t;
@@ -283,29 +412,62 @@ struct xtensa_perfmon_result {
struct xtensa_debug_module_config {
const struct xtensa_power_ops *pwr_ops;
const struct xtensa_debug_ops *dbg_ops;
+
+ /* Either JTAG or DAP structures will be populated */
struct jtag_tap *tap;
void (*queue_tdi_idle)(struct target *target);
void *queue_tdi_idle_arg;
+
+ /* For targets conforming to ARM Debug Interface v5,
+ * "dap" references the Debug Access Port (DAP)
+ * used to make requests to the target;
+ * "debug_ap" is AP instance connected to processor
+ */
+ struct adiv5_dap *dap;
+ struct adiv5_ap *debug_ap;
+ int debug_apsel;
+ uint32_t ap_offset;
};
struct xtensa_debug_module {
const struct xtensa_power_ops *pwr_ops;
const struct xtensa_debug_ops *dbg_ops;
+
+ /* Either JTAG or DAP structures will be populated */
struct jtag_tap *tap;
void (*queue_tdi_idle)(struct target *target);
void *queue_tdi_idle_arg;
+ /* DAP struct; AP instance connected to processor */
+ struct adiv5_dap *dap;
+ struct adiv5_ap *debug_ap;
+ int debug_apsel;
+
struct xtensa_power_status power_status;
struct xtensa_core_status core_status;
xtensa_ocdid_t device_id;
+ uint32_t ap_offset;
};
int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg);
+void xtensa_dm_deinit(struct xtensa_debug_module *dm);
+int xtensa_dm_poll(struct xtensa_debug_module *dm);
+int xtensa_dm_examine(struct xtensa_debug_module *dm);
int xtensa_dm_queue_enable(struct xtensa_debug_module *dm);
-int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *value);
-int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint32_t value);
-int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, uint8_t clear);
-int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data);
+int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value);
+int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value);
+int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm,
+ enum xtensa_dm_pwr_reg reg,
+ uint8_t *data,
+ uint32_t clear);
+int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm,
+ enum xtensa_dm_pwr_reg reg,
+ uint32_t data);
+
+static inline int xtensa_dm_queue_execute(struct xtensa_debug_module *dm)
+{
+ return dm->dap ? dap_run(dm->dap) : jtag_execute_queue();
+}
static inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
{
@@ -352,19 +514,19 @@ static inline bool xtensa_dm_is_online(struct xtensa_debug_module *dm)
int res = xtensa_dm_device_id_read(dm);
if (res != ERROR_OK)
return false;
- return (dm->device_id != 0xffffffff && dm->device_id != 0);
+ return dm->device_id != 0xffffffff && dm->device_id != 0;
}
static inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)
{
- return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET) &&
- dm->power_status.stat & PWRSTAT_DEBUGWASRESET;
+ return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET_DM(dm)) &&
+ dm->power_status.stat & PWRSTAT_DEBUGWASRESET_DM(dm);
}
static inline bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm)
{
- return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET) &&
- dm->power_status.stat & PWRSTAT_COREWASRESET;
+ return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET_DM(dm)) &&
+ dm->power_status.stat & PWRSTAT_COREWASRESET_DM(dm);
}
static inline bool xtensa_dm_core_is_stalled(struct xtensa_debug_module *dm)
diff --git a/src/target/xtensa/xtensa_regs.h b/src/target/xtensa/xtensa_regs.h
index 7602131..1d9d365 100644
--- a/src/target/xtensa/xtensa_regs.h
+++ b/src/target/xtensa/xtensa_regs.h
@@ -1,22 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Generic Xtensa target API for OpenOCD *
+ * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
* Copyright (C) 2016-2019 Espressif Systems Ltd. *
* Author: Angus Gratton gus@projectgus.com *
- * Author: Jeroen Domburg <jeroen@espressif.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
+
#ifndef OPENOCD_TARGET_XTENSA_REGS_H
#define OPENOCD_TARGET_XTENSA_REGS_H
@@ -25,6 +15,7 @@ struct reg_arch_type;
enum xtensa_reg_id {
XT_REG_IDX_PC = 0,
XT_REG_IDX_AR0,
+ XT_REG_IDX_ARFIRST = XT_REG_IDX_AR0,
XT_REG_IDX_AR1,
XT_REG_IDX_AR2,
XT_REG_IDX_AR3,
@@ -40,152 +31,23 @@ enum xtensa_reg_id {
XT_REG_IDX_AR13,
XT_REG_IDX_AR14,
XT_REG_IDX_AR15,
- XT_REG_IDX_AR16,
- XT_REG_IDX_AR17,
- XT_REG_IDX_AR18,
- XT_REG_IDX_AR19,
- XT_REG_IDX_AR20,
- XT_REG_IDX_AR21,
- XT_REG_IDX_AR22,
- XT_REG_IDX_AR23,
- XT_REG_IDX_AR24,
- XT_REG_IDX_AR25,
- XT_REG_IDX_AR26,
- XT_REG_IDX_AR27,
- XT_REG_IDX_AR28,
- XT_REG_IDX_AR29,
- XT_REG_IDX_AR30,
- XT_REG_IDX_AR31,
- XT_REG_IDX_AR32,
- XT_REG_IDX_AR33,
- XT_REG_IDX_AR34,
- XT_REG_IDX_AR35,
- XT_REG_IDX_AR36,
- XT_REG_IDX_AR37,
- XT_REG_IDX_AR38,
- XT_REG_IDX_AR39,
- XT_REG_IDX_AR40,
- XT_REG_IDX_AR41,
- XT_REG_IDX_AR42,
- XT_REG_IDX_AR43,
- XT_REG_IDX_AR44,
- XT_REG_IDX_AR45,
- XT_REG_IDX_AR46,
- XT_REG_IDX_AR47,
- XT_REG_IDX_AR48,
- XT_REG_IDX_AR49,
- XT_REG_IDX_AR50,
- XT_REG_IDX_AR51,
- XT_REG_IDX_AR52,
- XT_REG_IDX_AR53,
- XT_REG_IDX_AR54,
- XT_REG_IDX_AR55,
- XT_REG_IDX_AR56,
- XT_REG_IDX_AR57,
- XT_REG_IDX_AR58,
- XT_REG_IDX_AR59,
- XT_REG_IDX_AR60,
- XT_REG_IDX_AR61,
- XT_REG_IDX_AR62,
- XT_REG_IDX_AR63,
- XT_REG_IDX_LBEG,
- XT_REG_IDX_LEND,
- XT_REG_IDX_LCOUNT,
- XT_REG_IDX_SAR,
+ XT_REG_IDX_ARLAST = 64, /* Max 64 ARs */
XT_REG_IDX_WINDOWBASE,
XT_REG_IDX_WINDOWSTART,
- XT_REG_IDX_CONFIGID0,
- XT_REG_IDX_CONFIGID1,
XT_REG_IDX_PS,
- XT_REG_IDX_THREADPTR,
- XT_REG_IDX_BR,
- XT_REG_IDX_SCOMPARE1,
- XT_REG_IDX_ACCLO,
- XT_REG_IDX_ACCHI,
- XT_REG_IDX_M0,
- XT_REG_IDX_M1,
- XT_REG_IDX_M2,
- XT_REG_IDX_M3,
- XT_REG_IDX_F0,
- XT_REG_IDX_F1,
- XT_REG_IDX_F2,
- XT_REG_IDX_F3,
- XT_REG_IDX_F4,
- XT_REG_IDX_F5,
- XT_REG_IDX_F6,
- XT_REG_IDX_F7,
- XT_REG_IDX_F8,
- XT_REG_IDX_F9,
- XT_REG_IDX_F10,
- XT_REG_IDX_F11,
- XT_REG_IDX_F12,
- XT_REG_IDX_F13,
- XT_REG_IDX_F14,
- XT_REG_IDX_F15,
- XT_REG_IDX_FCR,
- XT_REG_IDX_FSR,
- XT_REG_IDX_MMID,
XT_REG_IDX_IBREAKENABLE,
- XT_REG_IDX_MEMCTL,
- XT_REG_IDX_ATOMCTL,
+ XT_REG_IDX_DDR,
XT_REG_IDX_IBREAKA0,
XT_REG_IDX_IBREAKA1,
XT_REG_IDX_DBREAKA0,
XT_REG_IDX_DBREAKA1,
XT_REG_IDX_DBREAKC0,
XT_REG_IDX_DBREAKC1,
- XT_REG_IDX_EPC1,
- XT_REG_IDX_EPC2,
- XT_REG_IDX_EPC3,
- XT_REG_IDX_EPC4,
- XT_REG_IDX_EPC5,
- XT_REG_IDX_EPC6,
- XT_REG_IDX_EPC7,
- XT_REG_IDX_DEPC,
- XT_REG_IDX_EPS2,
- XT_REG_IDX_EPS3,
- XT_REG_IDX_EPS4,
- XT_REG_IDX_EPS5,
- XT_REG_IDX_EPS6,
- XT_REG_IDX_EPS7,
- XT_REG_IDX_EXCSAVE1,
- XT_REG_IDX_EXCSAVE2,
- XT_REG_IDX_EXCSAVE3,
- XT_REG_IDX_EXCSAVE4,
- XT_REG_IDX_EXCSAVE5,
- XT_REG_IDX_EXCSAVE6,
- XT_REG_IDX_EXCSAVE7,
XT_REG_IDX_CPENABLE,
- XT_REG_IDX_INTERRUPT,
- XT_REG_IDX_INTSET,
- XT_REG_IDX_INTCLEAR,
- XT_REG_IDX_INTENABLE,
- XT_REG_IDX_VECBASE,
XT_REG_IDX_EXCCAUSE,
XT_REG_IDX_DEBUGCAUSE,
- XT_REG_IDX_CCOUNT,
- XT_REG_IDX_PRID,
XT_REG_IDX_ICOUNT,
XT_REG_IDX_ICOUNTLEVEL,
- XT_REG_IDX_EXCVADDR,
- XT_REG_IDX_CCOMPARE0,
- XT_REG_IDX_CCOMPARE1,
- XT_REG_IDX_CCOMPARE2,
- XT_REG_IDX_MISC0,
- XT_REG_IDX_MISC1,
- XT_REG_IDX_MISC2,
- XT_REG_IDX_MISC3,
- XT_REG_IDX_LITBASE,
- XT_REG_IDX_PTEVADDR,
- XT_REG_IDX_RASID,
- XT_REG_IDX_ITLBCFG,
- XT_REG_IDX_DTLBCFG,
- XT_REG_IDX_MEPC,
- XT_REG_IDX_MEPS,
- XT_REG_IDX_MESAVE,
- XT_REG_IDX_MESR,
- XT_REG_IDX_MECR,
- XT_REG_IDX_MEVADDR,
XT_REG_IDX_A0,
XT_REG_IDX_A1,
XT_REG_IDX_A2,
@@ -202,77 +64,72 @@ enum xtensa_reg_id {
XT_REG_IDX_A13,
XT_REG_IDX_A14,
XT_REG_IDX_A15,
- XT_REG_IDX_PWRCTL,
- XT_REG_IDX_PWRSTAT,
- XT_REG_IDX_ERISTAT,
- XT_REG_IDX_CS_ITCTRL,
- XT_REG_IDX_CS_CLAIMSET,
- XT_REG_IDX_CS_CLAIMCLR,
- XT_REG_IDX_CS_LOCKACCESS,
- XT_REG_IDX_CS_LOCKSTATUS,
- XT_REG_IDX_CS_AUTHSTATUS,
- XT_REG_IDX_FAULT_INFO,
- XT_REG_IDX_TRAX_ID,
- XT_REG_IDX_TRAX_CTRL,
- XT_REG_IDX_TRAX_STAT,
- XT_REG_IDX_TRAX_DATA,
- XT_REG_IDX_TRAX_ADDR,
- XT_REG_IDX_TRAX_PCTRIGGER,
- XT_REG_IDX_TRAX_PCMATCH,
- XT_REG_IDX_TRAX_DELAY,
- XT_REG_IDX_TRAX_MEMSTART,
- XT_REG_IDX_TRAX_MEMEND,
- XT_REG_IDX_PMG,
- XT_REG_IDX_PMPC,
- XT_REG_IDX_PM0,
- XT_REG_IDX_PM1,
- XT_REG_IDX_PMCTRL0,
- XT_REG_IDX_PMCTRL1,
- XT_REG_IDX_PMSTAT0,
- XT_REG_IDX_PMSTAT1,
- XT_REG_IDX_OCD_ID,
- XT_REG_IDX_OCD_DCRCLR,
- XT_REG_IDX_OCD_DCRSET,
- XT_REG_IDX_OCD_DSR,
- XT_REG_IDX_OCD_DDR,
- XT_NUM_REGS,
- /* chip-specific user registers go after ISA-defined ones */
- XT_USR_REG_START = XT_NUM_REGS
+ XT_NUM_REGS
};
typedef uint32_t xtensa_reg_val_t;
+#define XT_NUM_A_REGS 16
+
enum xtensa_reg_type {
XT_REG_GENERAL = 0, /* General-purpose register; part of the windowed register set */
XT_REG_USER = 1, /* User register, needs RUR to read */
XT_REG_SPECIAL = 2, /* Special register, needs RSR to read */
XT_REG_DEBUG = 3, /* Register used for the debug interface. Don't mess with this. */
XT_REG_RELGEN = 4, /* Relative general address. Points to the absolute addresses plus the window
- *index */
+ * index */
XT_REG_FR = 5, /* Floating-point register */
+ XT_REG_TIE = 6, /* TIE (custom) register */
+ XT_REG_OTHER = 7, /* Other (typically legacy) register */
+ XT_REG_TYPE_NUM,
+
+ /* enum names must be one of the above types + _VAL or _MASK */
+ XT_REG_GENERAL_MASK = 0xFFC0,
+ XT_REG_GENERAL_VAL = 0x0100,
+ XT_REG_USER_MASK = 0xFF00,
+ XT_REG_USER_VAL = 0x0300,
+ XT_REG_SPECIAL_MASK = 0xFF00,
+ XT_REG_SPECIAL_VAL = 0x0200,
+ XT_REG_DEBUG_MASK = 0xFF00,
+ XT_REG_DEBUG_VAL = 0x0200,
+ XT_REG_RELGEN_MASK = 0xFFE0,
+ XT_REG_RELGEN_VAL = 0x0000,
+ XT_REG_FR_MASK = 0xFFF0,
+ XT_REG_FR_VAL = 0x0030,
+ XT_REG_TIE_MASK = 0xF000,
+ XT_REG_TIE_VAL = 0xF000, /* unused */
+ XT_REG_OTHER_MASK = 0xFFFF,
+ XT_REG_OTHER_VAL = 0xF000, /* unused */
+
+ XT_REG_INDEX_MASK = 0x00FF
};
enum xtensa_reg_flags {
XT_REGF_NOREAD = 0x01, /* Register is write-only */
- XT_REGF_COPROC0 = 0x02 /* Can't be read if coproc0 isn't enabled */
+ XT_REGF_COPROC0 = 0x02, /* Can't be read if coproc0 isn't enabled */
+ XT_REGF_MASK = 0x03
};
struct xtensa_reg_desc {
const char *name;
+ bool exist;
unsigned int reg_num; /* ISA register num (meaning depends on register type) */
+ unsigned int dbreg_num; /* Debugger-visible register num (reg type encoded) */
enum xtensa_reg_type type;
enum xtensa_reg_flags flags;
};
-struct xtensa_user_reg_desc {
- const char *name;
- /* ISA register num (meaning depends on register type) */
- unsigned int reg_num;
- enum xtensa_reg_flags flags;
- uint32_t size;
- const struct reg_arch_type *type;
-};
+#define _XT_MK_DBREGN(reg_num, reg_type) \
+ ((reg_type ## _VAL) | (reg_num))
+
+#define _XT_MK_DBREGN_MASK(reg_num, reg_mask) \
+ ((reg_mask) | (reg_num))
+
+#define XT_MK_REG_DESC(n, r, t, f) \
+ { .name = (n), .exist = false, .reg_num = (r), \
+ .dbreg_num = _XT_MK_DBREGN(r, t), .type = (t), \
+ .flags = (f) }
-extern const struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS];
+extern struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS];
#endif /* OPENOCD_TARGET_XTENSA_REGS_H */
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 9076d9b..cb4f48f 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libtransport.la
%C%_libtransport_la_SOURCES = \
%D%/transport.c \
diff --git a/src/transport/transport.c b/src/transport/transport.c
index ba1af33..d72a48b 100644
--- a/src/transport/transport.c
+++ b/src/transport/transport.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* Copyright (c) 2010 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/transport/transport.h b/src/transport/transport.h
index e04f780..00d8b07 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/*
* Copyright (c) 2010 by David Brownell
* Copyright (C) 2011 Tomasz Boleslaw CEDRO (http://www.tomek.cedro.info)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENOCD_TRANSPORT_TRANSPORT_H
diff --git a/src/xsvf/Makefile.am b/src/xsvf/Makefile.am
index 61e6fb9..08f1cc1 100644
--- a/src/xsvf/Makefile.am
+++ b/src/xsvf/Makefile.am
@@ -1,2 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
noinst_LTLIBRARIES += %D%/libxsvf.la
%C%_libxsvf_la_SOURCES = %D%/xsvf.c %D%/xsvf.h
diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c
index c4ce55a..0266c21 100644
--- a/src/xsvf/xsvf.c
+++ b/src/xsvf/xsvf.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
@@ -10,19 +12,6 @@
* *
* Copyright (C) 2009 SoftPLC Corporation. http://softplc.com *
* Dick Hollenbeck <dick@softplc.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/* The specification for SVF is available here:
diff --git a/src/xsvf/xsvf.h b/src/xsvf/xsvf.h
index aa0f4f0..04ba056 100644
--- a/src/xsvf/xsvf.h
+++ b/src/xsvf/xsvf.h
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_XSVF_XSVF_H