From 23282d72477b23d245666d4e87d60d090007c1a2 Mon Sep 17 00:00:00 2001
From: besonzore <1670739974@qq.com>
Date: Sun, 1 Oct 2017 16:50:08 +0800
Subject: [PATCH] merge the last version from
https://github.com/gnu-mcu-eclipse/openocd Revision: 8721a12 Author: Liviu
Ionescu Date: 2017-09-03 00:57:08 [#16]; remove duplicate Makefile lines
---
src/Makefile.am | 131 +-
src/flash/Makefile.am | 30 +-
src/flash/common.c | 4 +-
src/flash/common.h | 11 +-
src/flash/mflash.c | 32 +-
src/flash/mflash.h | 10 +-
src/flash/nand/Makefile.am | 79 +-
src/flash/nand/arm_io.c | 4 +-
src/flash/nand/arm_io.h | 10 +-
src/flash/nand/at91sam9.c | 4 +-
src/flash/nand/core.c | 4 +-
src/flash/nand/core.h | 12 +-
src/flash/nand/davinci.c | 4 +-
src/flash/nand/driver.c | 4 +-
src/flash/nand/driver.h | 10 +-
src/flash/nand/ecc.c | 5 +-
src/flash/nand/ecc_kw.c | 3 +
src/flash/nand/fileio.c | 14 +-
src/flash/nand/fileio.h | 12 +-
src/flash/nand/imp.h | 10 +-
src/flash/nand/lpc3180.c | 4 +-
src/flash/nand/lpc3180.h | 10 +-
src/flash/nand/lpc32xx.c | 4 +-
src/flash/nand/lpc32xx.h | 10 +-
src/flash/nand/mx3.c | 4 +-
src/flash/nand/mx3.h | 9 +-
src/flash/nand/mxc.c | 4 +-
src/flash/nand/mxc.h | 10 +-
src/flash/nand/nonce.c | 4 +-
src/flash/nand/nuc910.c | 4 +-
src/flash/nand/nuc910.h | 11 +-
src/flash/nand/orion.c | 4 +-
src/flash/nand/s3c2410.c | 4 +-
src/flash/nand/s3c2412.c | 4 +-
src/flash/nand/s3c2440.c | 4 +-
src/flash/nand/s3c2443.c | 4 +-
src/flash/nand/s3c24xx.c | 4 +-
src/flash/nand/s3c24xx.h | 10 +-
src/flash/nand/s3c24xx_regs.h | 11 +-
src/flash/nand/s3c6400.c | 4 +-
src/flash/nand/tcl.c | 18 +-
src/flash/nor/Makefile.am | 126 +-
src/flash/nor/aduc702x.c | 6 +-
src/flash/nor/aducm360.c | 4 +-
src/flash/nor/at91sam3.c | 16 +-
src/flash/nor/at91sam4.c | 934 +-
src/flash/nor/at91sam4l.c | 17 +-
src/flash/nor/at91sam7.c | 34 +-
src/flash/nor/at91samd.c | 149 +-
src/flash/nor/atsamv.c | 15 +-
src/flash/nor/avrf.c | 5 +-
src/flash/nor/cfi.c | 161 +-
src/flash/nor/cfi.h | 13 +-
src/flash/nor/core.c | 74 +-
src/flash/nor/core.h | 38 +-
src/flash/nor/driver.h | 10 +-
src/flash/nor/drivers.c | 132 +-
src/flash/nor/dsp5680xx_flash.c | 4 +-
src/flash/nor/efm32.c | 63 +-
src/flash/nor/em357.c | 10 +-
src/flash/nor/faux.c | 6 +-
src/flash/nor/fm3.c | 4 +-
src/flash/nor/imp.h | 10 +-
src/flash/nor/jtagspi.c | 16 +-
src/flash/nor/kinetis.c | 1835 ++-
src/flash/nor/lpc2000.c | 21 +-
src/flash/nor/lpc288x.c | 4 +-
src/flash/nor/lpc2900.c | 13 +-
src/flash/nor/lpcspifi.c | 55 +-
src/flash/nor/mdr.c | 114 +-
src/flash/nor/mrvlqspi.c | 9 +-
src/flash/nor/niietcm4.c | 81 +-
src/flash/nor/non_cfi.c | 5 +-
src/flash/nor/non_cfi.h | 10 +-
src/flash/nor/nrf51.c | 110 +-
src/flash/nor/numicro.c | 3 +
src/flash/nor/ocl.c | 4 +-
src/flash/nor/ocl.h | 10 +-
src/flash/nor/pic32mx.c | 105 +-
src/flash/nor/psoc4.c | 9 +-
src/flash/nor/sim3x.c | 7 +-
src/flash/nor/spi.c | 23 +-
src/flash/nor/spi.h | 9 +-
src/flash/nor/stellaris.c | 10 +-
src/flash/nor/stm32f1x.c | 8 +-
src/flash/nor/stm32f2x.c | 439 +-
src/flash/nor/stm32l4x.c | 81 +-
src/flash/nor/stm32lx.c | 351 +-
src/flash/nor/stmsmi.c | 8 +-
src/flash/nor/str7x.c | 6 +-
src/flash/nor/str9x.c | 6 +-
src/flash/nor/str9xpec.c | 4 +-
src/flash/nor/tcl.c | 150 +-
src/flash/nor/tms470.c | 4 +-
src/flash/nor/virtual.c | 5 +-
src/flash/nor/xmc4xxx.c | 139 +-
src/hello.c | 4 +-
src/hello.h | 6 +-
src/helper/Makefile.am | 83 +-
src/helper/binarybuffer.c | 80 +-
src/helper/binarybuffer.h | 14 +-
src/helper/command.c | 10 +-
src/helper/command.h | 16 +-
src/helper/configuration.c | 4 +-
src/helper/configuration.h | 10 +-
src/helper/fileio.c | 133 +-
src/helper/fileio.h | 19 +-
src/helper/ioutil.c | 115 +-
src/helper/ioutil.h | 10 +-
src/helper/ioutil_stubs.c | 4 +-
src/helper/jim-nvp.c | 5 +-
src/helper/jim-nvp.h | 8 +-
src/helper/list.h | 6 +-
src/helper/log.c | 71 +-
src/helper/log.h | 12 +-
src/helper/options.c | 211 +-
src/helper/replacements.c | 4 +-
src/helper/replacements.h | 10 +-
src/helper/system.h | 10 +-
src/helper/time_support.c | 8 +-
src/helper/time_support.h | 14 +-
src/helper/time_support_common.c | 6 +-
src/helper/types.h | 41 +-
src/helper/util.c | 4 +-
src/helper/util.h | 10 +-
src/jtag/Makefile.am | 96 +-
src/jtag/adapter.c | 4 +-
src/jtag/aice/Makefile.am | 41 +-
src/jtag/aice/aice_interface.c | 4 +-
src/jtag/aice/aice_interface.h | 11 +-
src/jtag/aice/aice_pipe.c | 10 +-
src/jtag/aice/aice_pipe.h | 11 +-
src/jtag/aice/aice_port.c | 4 +-
src/jtag/aice/aice_port.h | 13 +-
src/jtag/aice/aice_transport.c | 14 +-
src/jtag/aice/aice_transport.h | 10 +-
src/jtag/aice/aice_usb.c | 22 +-
src/jtag/aice/aice_usb.h | 11 +-
src/jtag/commands.c | 4 +-
src/jtag/commands.h | 10 +-
src/jtag/core.c | 136 +-
src/jtag/driver.h | 10 +-
src/jtag/drivers/Makefile.am | 212 +-
src/jtag/drivers/Makefile.rlink | 4 +-
src/jtag/drivers/OpenULINK/Makefile | 4 +-
src/jtag/drivers/OpenULINK/include/common.h | 4 +-
src/jtag/drivers/OpenULINK/include/delay.h | 4 +-
src/jtag/drivers/OpenULINK/include/io.h | 4 +-
src/jtag/drivers/OpenULINK/include/jtag.h | 4 +-
src/jtag/drivers/OpenULINK/include/main.h | 4 +-
src/jtag/drivers/OpenULINK/include/msgtypes.h | 4 +-
src/jtag/drivers/OpenULINK/include/protocol.h | 4 +-
.../drivers/OpenULINK/include/reg_ezusb.h | 4 +-
src/jtag/drivers/OpenULINK/include/usb.h | 4 +-
src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 | 4 +-
src/jtag/drivers/OpenULINK/src/delay.c | 4 +-
src/jtag/drivers/OpenULINK/src/jtag.c | 4 +-
src/jtag/drivers/OpenULINK/src/main.c | 4 +-
src/jtag/drivers/OpenULINK/src/protocol.c | 4 +-
src/jtag/drivers/OpenULINK/src/usb.c | 4 +-
src/jtag/drivers/amt_jtagaccel.c | 4 +-
src/jtag/drivers/arm-jtag-ew.c | 4 +-
src/jtag/drivers/at91rm9200.c | 4 +-
src/jtag/drivers/bcm2835gpio.c | 8 +-
src/jtag/drivers/bitbang.c | 4 +-
src/jtag/drivers/bitbang.h | 10 +-
src/jtag/drivers/bitq.c | 4 +-
src/jtag/drivers/bitq.h | 10 +-
src/jtag/drivers/buspirate.c | 4 +-
src/jtag/drivers/cmsis_dap_usb.c | 583 +-
src/jtag/drivers/driver.c | 4 +-
src/jtag/drivers/dummy.c | 4 +-
src/jtag/drivers/ep93xx.c | 4 +-
src/jtag/drivers/ftdi.c | 200 +-
src/jtag/drivers/gw16012.c | 4 +-
src/jtag/drivers/jlink.c | 669 +-
src/jtag/drivers/jtag_vpi.c | 6 +
src/jtag/drivers/libusb0_common.c | 9 +-
src/jtag/drivers/libusb0_common.h | 12 +-
src/jtag/drivers/libusb1_common.c | 8 +-
src/jtag/drivers/libusb1_common.h | 13 +-
src/jtag/drivers/libusb_common.h | 13 +-
src/jtag/drivers/minidriver_imp.h | 11 +-
src/jtag/drivers/mpsse.c | 105 +-
src/jtag/drivers/mpsse.h | 12 +-
src/jtag/drivers/opendous.c | 4 +-
src/jtag/drivers/openjtag.c | 428 +-
src/jtag/drivers/osbdm.c | 4 +-
src/jtag/drivers/parport.c | 4 +-
src/jtag/drivers/presto.c | 223 +-
src/jtag/drivers/remote_bitbang.c | 6 +-
src/jtag/drivers/rlink.c | 4 +-
src/jtag/drivers/rlink.h | 9 +-
src/jtag/drivers/rlink_call.m4 | 4 +-
src/jtag/drivers/rlink_dtc_cmd.h | 9 +-
src/jtag/drivers/rlink_ep1_cmd.h | 9 +-
src/jtag/drivers/rlink_init.m4 | 4 +-
src/jtag/drivers/rlink_st7.h | 9 +-
src/jtag/drivers/stlink_usb.c | 50 +-
src/jtag/drivers/sysfsgpio.c | 4 +-
src/jtag/drivers/ti_icdi_usb.c | 15 +-
src/jtag/drivers/ulink.c | 12 +-
src/jtag/drivers/usb_blaster/Makefile.am | 25 +-
.../usb_blaster/ublast2_access_libusb.c | 3 +
src/jtag/drivers/usb_blaster/ublast_access.h | 16 +-
.../drivers/usb_blaster/ublast_access_ftdi.c | 3 +
src/jtag/drivers/usb_blaster/usb_blaster.c | 12 +-
src/jtag/drivers/usb_common.c | 4 +-
src/jtag/drivers/usb_common.h | 10 +-
src/jtag/drivers/usbprog.c | 4 +-
.../drivers/versaloon/usbtoxxx/usbtogpio.c | 4 +-
.../drivers/versaloon/usbtoxxx/usbtojtagraw.c | 4 +-
.../drivers/versaloon/usbtoxxx/usbtopwr.c | 4 +-
.../drivers/versaloon/usbtoxxx/usbtoswd.c | 4 +-
.../drivers/versaloon/usbtoxxx/usbtoxxx.c | 4 +-
.../drivers/versaloon/usbtoxxx/usbtoxxx.h | 10 +-
.../versaloon/usbtoxxx/usbtoxxx_internal.h | 10 +-
src/jtag/drivers/versaloon/versaloon.c | 4 +-
src/jtag/drivers/versaloon/versaloon.h | 11 +-
.../drivers/versaloon/versaloon_include.h | 9 +-
.../drivers/versaloon/versaloon_internal.h | 10 +-
src/jtag/drivers/vsllink.c | 4 +-
src/jtag/drivers/w_jtag_sj.c | 10 +-
src/jtag/hla/Makefile.am | 34 +-
src/jtag/hla/hla_interface.c | 4 +-
src/jtag/hla/hla_interface.h | 10 +-
src/jtag/hla/hla_layout.c | 4 +-
src/jtag/hla/hla_layout.h | 10 +-
src/jtag/hla/hla_tcl.c | 14 +-
src/jtag/hla/hla_tcl.h | 10 +-
src/jtag/hla/hla_transport.c | 4 +-
src/jtag/hla/hla_transport.h | 10 +-
src/jtag/interface.c | 4 +-
src/jtag/interface.h | 4 +-
src/jtag/interfaces.c | 36 +-
src/jtag/interfaces.h | 4 +-
src/jtag/jtag.h | 12 +-
src/jtag/minidriver.h | 10 +-
src/jtag/minidriver/minidriver_imp.h | 10 +-
src/jtag/minidummy/jtag_minidriver.h | 4 +-
src/jtag/minidummy/minidummy.c | 4 +-
src/jtag/swd.h | 10 +-
src/jtag/tcl.c | 16 +-
src/jtag/tcl.h | 10 +-
src/jtag/zy1000/jtag_minidriver.h | 4 +-
src/jtag/zy1000/zy1000.c | 10 +-
src/main.c | 4 +-
src/openocd.c | 32 +-
src/openocd.h | 10 +-
src/pld/Makefile.am | 16 +-
src/pld/pld.c | 4 +-
src/pld/pld.h | 10 +-
src/pld/virtex2.c | 4 +-
src/pld/virtex2.h | 10 +-
src/pld/xilinx_bit.c | 4 +-
src/pld/xilinx_bit.h | 10 +-
src/rtos/ChibiOS.c | 27 +-
src/rtos/FreeRTOS.c | 62 +-
src/rtos/Makefile.am | 58 +-
src/rtos/ThreadX.c | 13 +-
src/rtos/eCos.c | 11 +-
src/rtos/embKernel.c | 11 +-
src/rtos/linux.c | 17 +-
src/rtos/linux_header.h | 5 +
src/rtos/mqx.c | 16 +-
src/rtos/rtos.c | 84 +-
src/rtos/rtos.h | 14 +-
src/rtos/rtos_chibios_stackings.c | 4 +-
src/rtos/rtos_chibios_stackings.h | 10 +-
src/rtos/rtos_ecos_stackings.c | 4 +-
src/rtos/rtos_ecos_stackings.h | 10 +-
src/rtos/rtos_embkernel_stackings.c | 4 +-
src/rtos/rtos_embkernel_stackings.h | 10 +-
src/rtos/rtos_mqx_stackings.c | 3 +-
src/rtos/rtos_mqx_stackings.h | 10 +-
src/rtos/rtos_standard_stackings.c | 63 +-
src/rtos/rtos_standard_stackings.h | 12 +-
src/server/Makefile.am | 32 +-
src/server/gdb_server.c | 301 +-
src/server/gdb_server.h | 15 +-
src/server/server.c | 112 +-
src/server/server.h | 10 +-
src/server/server_stubs.c | 4 +-
src/server/tcl_server.c | 6 +-
src/server/tcl_server.h | 10 +-
src/server/telnet_server.c | 38 +-
src/server/telnet_server.h | 10 +-
src/svf/Makefile.am | 10 +-
src/svf/svf.c | 8 +-
src/svf/svf.h | 10 +-
src/target/Makefile.am | 349 +-
src/target/adi_v5_jtag.c | 620 +-
src/target/adi_v5_swd.c | 97 +-
src/target/algorithm.c | 4 +-
src/target/algorithm.h | 12 +-
src/target/arm.h | 46 +-
src/target/arm11.c | 97 +-
src/target/arm11.h | 10 +-
src/target/arm11_dbgtap.c | 14 +-
src/target/arm11_dbgtap.h | 10 +-
src/target/arm720t.c | 14 +-
src/target/arm720t.h | 10 +-
src/target/arm7_9_common.c | 56 +-
src/target/arm7_9_common.h | 26 +-
src/target/arm7tdmi.c | 7 +-
src/target/arm7tdmi.h | 10 +-
src/target/arm920t.c | 18 +-
src/target/arm920t.h | 14 +-
src/target/arm926ejs.c | 20 +-
src/target/arm926ejs.h | 12 +-
src/target/arm946e.c | 8 +-
src/target/arm946e.h | 10 +-
src/target/arm966e.c | 4 +-
src/target/arm966e.h | 10 +-
src/target/arm9tdmi.c | 6 +-
src/target/arm9tdmi.h | 10 +-
src/target/arm_adi_v5.c | 905 +-
src/target/arm_adi_v5.h | 63 +-
src/target/arm_disassembler.c | 6 +-
src/target/arm_disassembler.h | 10 +-
src/target/arm_dpm.c | 97 +-
src/target/arm_dpm.h | 82 +-
src/target/arm_jtag.c | 4 +-
src/target/arm_jtag.h | 10 +-
src/target/arm_opcodes.h | 11 +-
src/target/arm_semihosting.c | 543 +-
src/target/arm_semihosting.h | 11 +-
src/target/arm_simulator.c | 4 +-
src/target/arm_simulator.h | 10 +-
src/target/armv4_5.c | 177 +-
src/target/armv4_5.h | 10 +-
src/target/armv4_5_cache.c | 4 +-
src/target/armv4_5_cache.h | 10 +-
src/target/armv4_5_mmu.c | 4 +-
src/target/armv4_5_mmu.h | 15 +-
src/target/armv7a.c | 35 +-
src/target/armv7a.h | 26 +-
src/target/armv7a_cache.c | 3 +
src/target/armv7a_cache.h | 9 +-
src/target/armv7a_cache_l2x.c | 49 +-
src/target/armv7a_cache_l2x.h | 11 +-
src/target/armv7m.c | 98 +-
src/target/armv7m.h | 22 +-
src/target/armv7m_trace.c | 3 +
src/target/armv7m_trace.h | 9 +-
src/target/avr32_ap7k.c | 18 +-
src/target/avr32_ap7k.h | 10 +-
src/target/avr32_jtag.c | 4 +-
src/target/avr32_jtag.h | 10 +-
src/target/avr32_mem.c | 4 +-
src/target/avr32_mem.h | 10 +-
src/target/avr32_regs.c | 4 +-
src/target/avr32_regs.h | 10 +-
src/target/avrt.c | 12 +-
src/target/avrt.h | 10 +-
src/target/breakpoints.c | 49 +-
src/target/breakpoints.h | 31 +-
src/target/cortex_a.c | 446 +-
src/target/cortex_a.h | 12 +-
src/target/cortex_m.c | 153 +-
src/target/cortex_m.h | 12 +-
src/target/dsp563xx.c | 26 +-
src/target/dsp563xx.h | 10 +-
src/target/dsp563xx_once.c | 4 +-
src/target/dsp563xx_once.h | 10 +-
src/target/dsp5680xx.c | 22 +-
src/target/dsp5680xx.h | 10 +-
src/target/embeddedice.c | 4 +-
src/target/embeddedice.h | 10 +-
src/target/etb.c | 4 +-
src/target/etb.h | 10 +-
src/target/etm.c | 44 +-
src/target/etm.h | 10 +-
src/target/etm_dummy.c | 4 +-
src/target/etm_dummy.h | 10 +-
src/target/fa526.c | 4 +-
src/target/feroceon.c | 15 +-
src/target/hla_target.c | 26 +-
src/target/image.c | 50 +-
src/target/image.h | 20 +-
src/target/lakemont.c | 42 +-
src/target/lakemont.h | 17 +-
src/target/mips32.c | 186 +-
src/target/mips32.h | 349 +-
src/target/mips32_dmaacc.c | 4 +-
src/target/mips32_dmaacc.h | 10 +-
src/target/mips32_pracc.c | 681 +-
src/target/mips32_pracc.h | 40 +-
src/target/mips_ejtag.c | 188 +-
src/target/mips_ejtag.h | 25 +-
src/target/mips_m4k.c | 229 +-
src/target/mips_m4k.h | 21 +-
src/target/nds32.c | 31 +-
src/target/nds32.h | 24 +-
src/target/nds32_aice.c | 8 +-
src/target/nds32_aice.h | 15 +-
src/target/nds32_cmd.c | 8 +-
src/target/nds32_cmd.h | 11 +-
src/target/nds32_disassembler.c | 4 +-
src/target/nds32_disassembler.h | 10 +-
src/target/nds32_edm.h | 11 +-
src/target/nds32_insn.h | 11 +-
src/target/nds32_reg.c | 4 +-
src/target/nds32_reg.h | 11 +-
src/target/nds32_tlb.c | 12 +-
src/target/nds32_tlb.h | 19 +-
src/target/nds32_v2.c | 30 +-
src/target/nds32_v2.h | 12 +-
src/target/nds32_v3.c | 12 +-
src/target/nds32_v3.h | 11 +-
src/target/nds32_v3_common.c | 26 +-
src/target/nds32_v3_common.h | 25 +-
src/target/nds32_v3m.c | 12 +-
src/target/nds32_v3m.h | 12 +-
src/target/oocd_trace.c | 4 +-
src/target/oocd_trace.h | 10 +-
src/target/openrisc/Makefile.am | 30 +-
src/target/openrisc/jsp_server.c | 4 +-
src/target/openrisc/jsp_server.h | 6 +-
src/target/openrisc/or1k.c | 36 +-
src/target/openrisc/or1k.h | 9 +-
src/target/openrisc/or1k_du.h | 10 +-
src/target/openrisc/or1k_du_adv.c | 3 +
src/target/openrisc/or1k_tap.h | 9 +-
src/target/openrisc/or1k_tap_mohor.c | 3 +
src/target/openrisc/or1k_tap_vjtag.c | 3 +
src/target/openrisc/or1k_tap_xilinx_bscan.c | 3 +
src/target/quark_x10xx.c | 6 +-
src/target/register.c | 4 +-
src/target/register.h | 25 +-
src/target/smp.c | 7 +-
src/target/smp.h | 8 +-
src/target/startup.tcl | 14 +-
src/target/target.c | 11012 ++++++++--------
src/target/target.h | 72 +-
src/target/target_request.c | 4 +-
src/target/target_request.h | 10 +-
src/target/target_type.h | 46 +-
src/target/testee.c | 4 +-
src/target/trace.c | 4 +-
src/target/trace.h | 10 +-
src/target/x86_32_common.c | 98 +-
src/target/x86_32_common.h | 27 +-
src/target/xscale.c | 56 +-
src/target/xscale.h | 10 +-
src/transport/Makefile.am | 15 +-
src/transport/transport.c | 3 +-
src/transport/transport.h | 9 +-
src/xsvf/Makefile.am | 10 +-
src/xsvf/xsvf.c | 4 +-
src/xsvf/xsvf.h | 10 +-
451 files changed, 17313 insertions(+), 12885 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 26e02d085..07981aa67 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,60 +1,41 @@
-include $(top_srcdir)/common.mk
+noinst_LTLIBRARIES += %D%/libopenocd.la
+bin_PROGRAMS += %D%/openocd
-SUBDIRS = \
- jtag \
- helper \
- target \
- transport \
- flash \
- svf \
- xsvf \
- pld \
- server \
- rtos
+%C%_openocd_SOURCES = \
+ %D%/main.c
-noinst_LTLIBRARIES = libopenocd.la
-bin_PROGRAMS = openocd
+%C%_libopenocd_la_SOURCES = \
+ %D%/hello.c %D%/hello.h \
+ %D%/openocd.c %D%/openocd.h
-MAINFILE = main.c
+%C%_openocd_LDADD = %D%/libopenocd.la
-openocd_SOURCES = $(MAINFILE)
-openocd_LDADD = libopenocd.la
+%C%_openocd_LDADD += $(MINGWLDADD)
if INTERNAL_JIMTCL
-openocd_LDADD += $(top_builddir)/jimtcl/libjim.a
+%C%_openocd_LDADD += $(top_builddir)/jimtcl/libjim.a
else
-openocd_LDADD += -ljim
+%C%_openocd_LDADD += -ljim
endif
-if ULINK
-openocd_LDADD += -lm
-endif
-
-libopenocd_la_SOURCES = \
- hello.c \
- openocd.c
-
-noinst_HEADERS = \
- hello.h \
- openocd.h
-
-libopenocd_la_CPPFLAGS = -DPKGBLDDATE=\"`date +%F-%R`\"
+%C%_libopenocd_la_CPPFLAGS =
# banner output includes RELSTR appended to $VERSION from the configure script
# guess-rev.sh returns either a repository version ID or "-snapshot"
if RELEASE
-libopenocd_la_CPPFLAGS += -DRELSTR=\"\"
-libopenocd_la_CPPFLAGS += -DGITVERSION=\"\"
+%C%_libopenocd_la_CPPFLAGS += -DRELSTR=\"\"
+%C%_libopenocd_la_CPPFLAGS += -DGITVERSION=\"\"
else
-libopenocd_la_CPPFLAGS += -DRELSTR=\"`$(top_srcdir)/guess-rev.sh $(top_srcdir)`\"
-libopenocd_la_CPPFLAGS += -DGITVERSION=\"`cd $(top_srcdir) && git describe`\"
+%C%_libopenocd_la_CPPFLAGS += -DRELSTR=\"`$(top_srcdir)/guess-rev.sh $(top_srcdir)`\"
+%C%_libopenocd_la_CPPFLAGS += -DGITVERSION=\"`cd $(top_srcdir) && git describe`\"
+%C%_libopenocd_la_CPPFLAGS += -DPKGBLDDATE=\"`date +%F-%R`\"
endif
# add default CPPFLAGS
-libopenocd_la_CPPFLAGS += $(AM_CPPFLAGS) $(CPPFLAGS)
+%C%_libopenocd_la_CPPFLAGS += $(AM_CPPFLAGS) $(CPPFLAGS)
# the library search path.
-libopenocd_la_LDFLAGS = $(all_libraries)
+%C%_libopenocd_la_LDFLAGS = $(all_libraries)
if IS_MINGW
MINGWLDADD = -lws2_32
@@ -62,55 +43,43 @@ else
MINGWLDADD =
endif
-libopenocd_la_LIBADD = \
- $(top_builddir)/src/xsvf/libxsvf.la \
- $(top_builddir)/src/svf/libsvf.la \
- $(top_builddir)/src/pld/libpld.la \
- $(top_builddir)/src/jtag/libjtag.la \
- $(top_builddir)/src/transport/libtransport.la \
- $(top_builddir)/src/flash/libflash.la \
- $(top_builddir)/src/target/libtarget.la \
- $(top_builddir)/src/server/libserver.la \
- $(top_builddir)/src/rtos/librtos.la \
- $(top_builddir)/src/helper/libhelper.la \
- $(LIBFTDI_LIBS) $(MINGWLDADD) \
- $(HIDAPI_LIBS) $(LIBUSB0_LIBS) $(LIBUSB1_LIBS)
-
-STARTUP_TCL_SRCS = \
- $(srcdir)/helper/startup.tcl \
- $(srcdir)/jtag/startup.tcl \
- $(srcdir)/target/startup.tcl \
- $(srcdir)/flash/startup.tcl \
- $(srcdir)/server/startup.tcl
+%C%_libopenocd_la_LIBADD = \
+ %D%/xsvf/libxsvf.la \
+ %D%/svf/libsvf.la \
+ %D%/pld/libpld.la \
+ %D%/jtag/libjtag.la \
+ %D%/transport/libtransport.la \
+ %D%/flash/libflash.la \
+ %D%/target/libtarget.la \
+ %D%/server/libserver.la \
+ %D%/rtos/librtos.la \
+ %D%/helper/libhelper.la
-EXTRA_DIST = $(STARTUP_TCL_SRCS)
+BIN2C = $(srcdir)/%D%/helper/bin2char.sh
-BUILT_SOURCES = startup_tcl.inc
+STARTUP_TCL_SRCS =
+EXTRA_DIST += $(STARTUP_TCL_SRCS)
-startup.tcl: $(STARTUP_TCL_SRCS)
- cat $^ > $@
-
-BIN2C = $(top_srcdir)/src/helper/bin2char.sh
+BUILT_SOURCES += %D%/startup_tcl.inc
# Convert .tcl to c-array
-startup_tcl.inc: startup.tcl $(BIN2C)
- $(BIN2C) < $< > $@ || { rm -f $@; false; }
+%D%/startup_tcl.inc: $(STARTUP_TCL_SRCS)
+ cat $^ | $(BIN2C) > $@ || { rm -f $@; false; }
# add generated files to make clean list
-CLEANFILES = startup.tcl startup_tcl.inc
+CLEANFILES += %D%/startup_tcl.inc
# we do not want generated file in the dist
-dist-hook:
- rm -f $(distdir)/startup_tcl.inc
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
-
-# The "quick" target builds executables & reinstalls the executables
-# Primary use: developer types to quicken the edit/compile/debug
-# cycle. by not requiring a "full build and full install". Note the
-# assumption is: You are only rebuilding the EXE.... and everything
-# else is/was previously installed.
-#
-# use at your own risk
-quick: all install-binPROGRAMS
-
+#dist-hook:
+# rm -f $(distdir)/%D%/startup_tcl.inc
+
+include %D%/helper/Makefile.am
+include %D%/jtag/Makefile.am
+include %D%/transport/Makefile.am
+include %D%/xsvf/Makefile.am
+include %D%/svf/Makefile.am
+include %D%/target/Makefile.am
+include %D%/rtos/Makefile.am
+include %D%/server/Makefile.am
+include %D%/flash/Makefile.am
+include %D%/pld/Makefile.am
diff --git a/src/flash/Makefile.am b/src/flash/Makefile.am
index ece401837..a1b46f853 100644
--- a/src/flash/Makefile.am
+++ b/src/flash/Makefile.am
@@ -1,23 +1,13 @@
-include $(top_srcdir)/common.mk
+noinst_LTLIBRARIES += %D%/libflash.la
+%C%_libflash_la_SOURCES = \
+ %D%/common.c %D%/common.h \
+ %D%/mflash.c %D%/mflash.h
-SUBDIRS = \
- nor \
- nand
+%C%_libflash_la_LIBADD = \
+ %D%/nor/libocdflashnor.la \
+ %D%/nand/libocdflashnand.la
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libflash.la
-libflash_la_SOURCES = \
- common.c \
- mflash.c
+STARTUP_TCL_SRCS += %D%/startup.tcl
-libflash_la_LIBADD = \
- $(top_builddir)/src/flash/nor/libocdflashnor.la \
- $(top_builddir)/src/flash/nand/libocdflashnand.la
-
-noinst_HEADERS = \
- common.h \
- mflash.h
-
-EXTRA_DIST = startup.tcl
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+include %D%/nor/Makefile.am
+include %D%/nand/Makefile.am
diff --git a/src/flash/common.c b/src/flash/common.c
index 878667b80..3e2551192 100644
--- a/src/flash/common.c
+++ b/src/flash/common.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/common.h b/src/flash/common.h
index 6e32c5520..4244f1360 100644
--- a/src/flash/common.h
+++ b/src/flash/common.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef FLASH_COMMON_H
-#define FLASH_COMMON_H
+#ifndef OPENOCD_FLASH_COMMON_H
+#define OPENOCD_FLASH_COMMON_H
#include
@@ -46,5 +44,6 @@ bool flash_driver_name_matches(const char *name, const char *expected);
#define ERROR_FLASH_SECTOR_NOT_ERASED (-906)
#define ERROR_FLASH_BANK_NOT_PROBED (-907)
#define ERROR_FLASH_OPER_UNSUPPORTED (-908)
+#define ERROR_FLASH_PROTECTED (-909)
-#endif /* FLASH_COMMON_H */
+#endif /* OPENOCD_FLASH_COMMON_H */
diff --git a/src/flash/mflash.c b/src/flash/mflash.c
index 6f4a988ec..b69995542 100644
--- a/src/flash/mflash.c
+++ b/src/flash/mflash.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -749,7 +747,7 @@ COMMAND_HANDLER(mg_write_cmd)
{
uint32_t address, cnt, res, i;
uint8_t *buffer;
- struct fileio fileio;
+ struct fileio *fileio;
int ret;
if (CMD_ARGC != 3)
@@ -764,12 +762,12 @@ COMMAND_HANDLER(mg_write_cmd)
size_t filesize;
buffer = malloc(MG_FILEIO_CHUNK);
if (!buffer) {
- fileio_close(&fileio);
+ fileio_close(fileio);
return ERROR_FAIL;
}
- int retval = fileio_size(&fileio, &filesize);
+ int retval = fileio_size(fileio, &filesize);
if (retval != ERROR_OK) {
- fileio_close(&fileio);
+ fileio_close(fileio);
free(buffer);
return retval;
}
@@ -782,7 +780,7 @@ COMMAND_HANDLER(mg_write_cmd)
size_t buf_cnt;
for (i = 0; i < cnt; i++) {
- ret = fileio_read(&fileio, MG_FILEIO_CHUNK, buffer, &buf_cnt);
+ ret = fileio_read(fileio, MG_FILEIO_CHUNK, buffer, &buf_cnt);
if (ret != ERROR_OK)
goto mg_write_cmd_err;
ret = mg_mflash_write(address, buffer, MG_FILEIO_CHUNK);
@@ -792,7 +790,7 @@ COMMAND_HANDLER(mg_write_cmd)
}
if (res) {
- ret = fileio_read(&fileio, res, buffer, &buf_cnt);
+ ret = fileio_read(fileio, res, buffer, &buf_cnt);
if (ret != ERROR_OK)
goto mg_write_cmd_err;
ret = mg_mflash_write(address, buffer, res);
@@ -807,13 +805,13 @@ COMMAND_HANDLER(mg_write_cmd)
}
free(buffer);
- fileio_close(&fileio);
+ fileio_close(fileio);
return ERROR_OK;
mg_write_cmd_err:
free(buffer);
- fileio_close(&fileio);
+ fileio_close(fileio);
return ret;
}
@@ -822,7 +820,7 @@ COMMAND_HANDLER(mg_dump_cmd)
{
uint32_t address, size, cnt, res, i;
uint8_t *buffer;
- struct fileio fileio;
+ struct fileio *fileio;
int ret;
if (CMD_ARGC != 4)
@@ -837,7 +835,7 @@ COMMAND_HANDLER(mg_dump_cmd)
buffer = malloc(MG_FILEIO_CHUNK);
if (!buffer) {
- fileio_close(&fileio);
+ fileio_close(fileio);
return ERROR_FAIL;
}
@@ -852,7 +850,7 @@ COMMAND_HANDLER(mg_dump_cmd)
ret = mg_mflash_read(address, buffer, MG_FILEIO_CHUNK);
if (ret != ERROR_OK)
goto mg_dump_cmd_err;
- ret = fileio_write(&fileio, MG_FILEIO_CHUNK, buffer, &size_written);
+ ret = fileio_write(fileio, MG_FILEIO_CHUNK, buffer, &size_written);
if (ret != ERROR_OK)
goto mg_dump_cmd_err;
address += MG_FILEIO_CHUNK;
@@ -862,7 +860,7 @@ COMMAND_HANDLER(mg_dump_cmd)
ret = mg_mflash_read(address, buffer, res);
if (ret != ERROR_OK)
goto mg_dump_cmd_err;
- ret = fileio_write(&fileio, res, buffer, &size_written);
+ ret = fileio_write(fileio, res, buffer, &size_written);
if (ret != ERROR_OK)
goto mg_dump_cmd_err;
}
@@ -875,13 +873,13 @@ COMMAND_HANDLER(mg_dump_cmd)
}
free(buffer);
- fileio_close(&fileio);
+ fileio_close(fileio);
return ERROR_OK;
mg_dump_cmd_err:
free(buffer);
- fileio_close(&fileio);
+ fileio_close(fileio);
return ret;
}
diff --git a/src/flash/mflash.h b/src/flash/mflash.h
index 6f46c7bde..18da40361 100644
--- a/src/flash/mflash.h
+++ b/src/flash/mflash.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _MFLASH_H
-#define _MFLASH_H
+#ifndef OPENOCD_FLASH_MFLASH_H
+#define OPENOCD_FLASH_MFLASH_H
struct command_context;
@@ -288,4 +286,4 @@ typedef enum _mg_opmode {
mg_op_mode_stg = 0 /* Only Storage */
} mg_opmode;
-#endif
+#endif /* OPENOCD_FLASH_MFLASH_H */
diff --git a/src/flash/nand/Makefile.am b/src/flash/nand/Makefile.am
index 2ddd096ae..abe90f8bb 100644
--- a/src/flash/nand/Makefile.am
+++ b/src/flash/nand/Makefile.am
@@ -1,46 +1,43 @@
-include $(top_srcdir)/common.mk
+noinst_LTLIBRARIES += %D%/libocdflashnand.la
-noinst_LTLIBRARIES = libocdflashnand.la
-
-libocdflashnand_la_SOURCES = \
- ecc.c \
- ecc_kw.c \
- core.c \
- fileio.c \
- tcl.c \
- arm_io.c \
+%C%_libocdflashnand_la_SOURCES = \
+ %D%/ecc.c \
+ %D%/ecc_kw.c \
+ %D%/core.c \
+ %D%/fileio.c \
+ %D%/tcl.c \
+ %D%/arm_io.c \
$(NAND_DRIVERS) \
- driver.c
+ %D%/driver.c \
+ $(NANDHEADERS)
NAND_DRIVERS = \
- nonce.c \
- davinci.c \
- lpc3180.c \
- lpc32xx.c \
- mxc.c \
- mx3.c \
- orion.c \
- s3c24xx.c \
- s3c2410.c \
- s3c2412.c \
- s3c2440.c \
- s3c2443.c \
- s3c6400.c \
- at91sam9.c \
- nuc910.c
-
-noinst_HEADERS = \
- arm_io.h \
- core.h \
- driver.h \
- fileio.h \
- imp.h \
- lpc3180.h \
- lpc32xx.h \
- mxc.h \
- mx3.h \
- s3c24xx.h \
- s3c24xx_regs.h \
- nuc910.h
+ %D%/nonce.c \
+ %D%/davinci.c \
+ %D%/lpc3180.c \
+ %D%/lpc32xx.c \
+ %D%/mxc.c \
+ %D%/mx3.c \
+ %D%/orion.c \
+ %D%/s3c24xx.c \
+ %D%/s3c2410.c \
+ %D%/s3c2412.c \
+ %D%/s3c2440.c \
+ %D%/s3c2443.c \
+ %D%/s3c6400.c \
+ %D%/at91sam9.c \
+ %D%/nuc910.c
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+NANDHEADERS = \
+ %D%/arm_io.h \
+ %D%/core.h \
+ %D%/driver.h \
+ %D%/fileio.h \
+ %D%/imp.h \
+ %D%/lpc3180.h \
+ %D%/lpc32xx.h \
+ %D%/mxc.h \
+ %D%/mx3.h \
+ %D%/s3c24xx.h \
+ %D%/s3c24xx_regs.h \
+ %D%/nuc910.h
diff --git a/src/flash/nand/arm_io.c b/src/flash/nand/arm_io.c
index d54958adc..e319f9585 100644
--- a/src/flash/nand/arm_io.c
+++ b/src/flash/nand/arm_io.c
@@ -15,9 +15,7 @@
* GNU 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/arm_io.h b/src/flash/nand/arm_io.h
index 0ee79a793..8bb311458 100644
--- a/src/flash/nand/arm_io.h
+++ b/src/flash/nand/arm_io.h
@@ -12,12 +12,10 @@
* GNU 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*/
-#ifndef __ARM_NANDIO_H
-#define __ARM_NANDIO_H
+#ifndef OPENOCD_FLASH_NAND_ARM_IO_H
+#define OPENOCD_FLASH_NAND_ARM_IO_H
/**
* Available operational states the arm_nand_data struct can be in.
@@ -54,4 +52,4 @@ struct arm_nand_data {
int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size);
int arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size);
-#endif /* __ARM_NANDIO_H */
+#endif /* OPENOCD_FLASH_NAND_ARM_IO_H */
diff --git a/src/flash/nand/at91sam9.c b/src/flash/nand/at91sam9.c
index 3f4e5e277..0af12b20c 100644
--- a/src/flash/nand/at91sam9.c
+++ b/src/flash/nand/at91sam9.c
@@ -13,9 +13,7 @@
* GNU 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c
index 815c7661f..7428d2253 100644
--- a/src/flash/nand/core.c
+++ b/src/flash/nand/core.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h
index 308859bd4..5bf9fb3d1 100644
--- a/src/flash/nand/core.h
+++ b/src/flash/nand/core.h
@@ -18,13 +18,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef FLASH_NAND_CORE_H
-#define FLASH_NAND_CORE_H
+#ifndef OPENOCD_FLASH_NAND_CORE_H
+#define OPENOCD_FLASH_NAND_CORE_H
#include
@@ -68,7 +66,7 @@ struct nand_device {
int address_cycles;
int page_size;
int erase_size;
- int use_raw;
+ bool use_raw;
int num_blocks;
struct nand_block *blocks;
struct nand_device *next;
@@ -231,4 +229,4 @@ COMMAND_HELPER(nand_command_get_device, unsigned name_index,
#define ERROR_NAND_ERROR_CORRECTION_FAILED (-1105)
#define ERROR_NAND_NO_BUFFER (-1106)
-#endif /* FLASH_NAND_CORE_H */
+#endif /* OPENOCD_FLASH_NAND_CORE_H */
diff --git a/src/flash/nand/davinci.c b/src/flash/nand/davinci.c
index c88046d6b..17e6f680d 100644
--- a/src/flash/nand/davinci.c
+++ b/src/flash/nand/davinci.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/driver.c b/src/flash/nand/driver.c
index 49e13c00a..f7665603f 100644
--- a/src/flash/nand/driver.c
+++ b/src/flash/nand/driver.c
@@ -15,9 +15,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/driver.h b/src/flash/nand/driver.h
index 62bae06ec..2182a7727 100644
--- a/src/flash/nand/driver.h
+++ b/src/flash/nand/driver.h
@@ -15,13 +15,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef FLASH_NAND_DRIVER_H
-#define FLASH_NAND_DRIVER_H
+#ifndef OPENOCD_FLASH_NAND_DRIVER_H
+#define OPENOCD_FLASH_NAND_DRIVER_H
struct nand_device;
@@ -102,4 +100,4 @@ typedef int (*nand_driver_walker_t)(struct nand_flash_controller *c, void *);
*/
int nand_driver_walk(nand_driver_walker_t f, void *x);
-#endif /* FLASH_NAND_DRIVER_H */
+#endif /* OPENOCD_FLASH_NAND_DRIVER_H */
diff --git a/src/flash/nand/ecc.c b/src/flash/nand/ecc.c
index fba7b1c60..25b2eb10e 100644
--- a/src/flash/nand/ecc.c
+++ b/src/flash/nand/ecc.c
@@ -21,9 +21,8 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this file; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*
* As a special exception, if other files instantiate templates or use
* macros or inline functions from these files, or you compile these
diff --git a/src/flash/nand/ecc_kw.c b/src/flash/nand/ecc_kw.c
index 1c3cc70ab..fb3481d00 100644
--- a/src/flash/nand/ecc_kw.c
+++ b/src/flash/nand/ecc_kw.c
@@ -14,6 +14,9 @@
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/fileio.c b/src/flash/nand/fileio.c
index d84ef4f94..64c32c0a8 100644
--- a/src/flash/nand/fileio.c
+++ b/src/flash/nand/fileio.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -99,7 +97,7 @@ int nand_fileio_start(struct command_context *cmd_ctx,
int nand_fileio_cleanup(struct nand_fileio_state *state)
{
if (state->file_opened)
- fileio_close(&state->fileio);
+ fileio_close(state->fileio);
if (state->oob) {
free(state->oob);
@@ -134,7 +132,7 @@ COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state,
if (NULL == nand->device) {
command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]);
- return ERROR_OK;
+ return ERROR_NAND_DEVICE_NOT_PROBED;
}
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], state->address);
@@ -169,7 +167,7 @@ COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state,
if (!need_size) {
size_t filesize;
- retval = fileio_size(&state->fileio, &filesize);
+ retval = fileio_size(state->fileio, &filesize);
if (retval != ERROR_OK)
return retval;
state->size = filesize;
@@ -190,7 +188,7 @@ int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s)
size_t one_read;
if (NULL != s->page) {
- fileio_read(&s->fileio, s->page_size, s->page, &one_read);
+ fileio_read(s->fileio, s->page_size, s->page, &one_read);
if (one_read < s->page_size)
memset(s->page + one_read, 0xff, s->page_size - one_read);
total_read += one_read;
@@ -219,7 +217,7 @@ int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s)
ecc += 10;
}
} else if (NULL != s->oob) {
- fileio_read(&s->fileio, s->oob_size, s->oob, &one_read);
+ fileio_read(s->fileio, s->oob_size, s->oob, &one_read);
if (one_read < s->oob_size)
memset(s->oob + one_read, 0xff, s->oob_size - one_read);
total_read += one_read;
diff --git a/src/flash/nand/fileio.h b/src/flash/nand/fileio.h
index c92c644fb..af6c7666e 100644
--- a/src/flash/nand/fileio.h
+++ b/src/flash/nand/fileio.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef FLASH_NAND_FILEIO_H
-#define FLASH_NAND_FILEIO_H
+#ifndef OPENOCD_FLASH_NAND_FILEIO_H
+#define OPENOCD_FLASH_NAND_FILEIO_H
#include
#include
@@ -37,7 +35,7 @@ struct nand_fileio_state {
const int *eccpos;
bool file_opened;
- struct fileio fileio;
+ struct fileio *fileio;
struct duration bench;
};
@@ -55,4 +53,4 @@ COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state,
int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s);
-#endif /* FLASH_NAND_FILEIO_H */
+#endif /* OPENOCD_FLASH_NAND_FILEIO_H */
diff --git a/src/flash/nand/imp.h b/src/flash/nand/imp.h
index dde17cb8d..c8a4ed9c5 100644
--- a/src/flash/nand/imp.h
+++ b/src/flash/nand/imp.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef FLASH_NAND_IMP_H
-#define FLASH_NAND_IMP_H
+#ifndef OPENOCD_FLASH_NAND_IMP_H
+#define OPENOCD_FLASH_NAND_IMP_H
#include "core.h"
#include "driver.h"
@@ -37,4 +35,4 @@ int nand_probe(struct nand_device *nand);
int nand_erase(struct nand_device *nand, int first_block, int last_block);
int nand_build_bbt(struct nand_device *nand, int first, int last);
-#endif /* FLASH_NAND_IMP_H */
+#endif /* OPENOCD_FLASH_NAND_IMP_H */
diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c
index ff02ffaa6..d15fdce38 100644
--- a/src/flash/nand/lpc3180.c
+++ b/src/flash/nand/lpc3180.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/lpc3180.h b/src/flash/nand/lpc3180.h
index 4d162fc8c..c02ee5b27 100644
--- a/src/flash/nand/lpc3180.h
+++ b/src/flash/nand/lpc3180.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef LPC3180_NAND_CONTROLLER_H
-#define LPC3180_NAND_CONTROLLER_H
+#ifndef OPENOCD_FLASH_NAND_LPC3180_H
+#define OPENOCD_FLASH_NAND_LPC3180_H
enum lpc3180_selected_controller {
LPC3180_NO_CONTROLLER,
@@ -36,4 +34,4 @@ struct lpc3180_nand_controller {
uint32_t sw_wp_upper_bound;
};
-#endif /*LPC3180_NAND_CONTROLLER_H */
+#endif /* OPENOCD_FLASH_NAND_LPC3180_H */
diff --git a/src/flash/nand/lpc32xx.c b/src/flash/nand/lpc32xx.c
index c310f9040..1ed16dfd0 100644
--- a/src/flash/nand/lpc32xx.c
+++ b/src/flash/nand/lpc32xx.c
@@ -21,9 +21,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/lpc32xx.h b/src/flash/nand/lpc32xx.h
index 2b1c1a89e..90b20b247 100644
--- a/src/flash/nand/lpc32xx.h
+++ b/src/flash/nand/lpc32xx.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef LPC32xx_NAND_CONTROLLER_H
-#define LPC32xx_NAND_CONTROLLER_H
+#ifndef OPENOCD_FLASH_NAND_LPC32XX_H
+#define OPENOCD_FLASH_NAND_LPC32XX_H
enum lpc32xx_selected_controller {
LPC32xx_NO_CONTROLLER,
@@ -35,4 +33,4 @@ struct lpc32xx_nand_controller {
uint32_t sw_wp_upper_bound;
};
-#endif /*LPC32xx_NAND_CONTROLLER_H */
+#endif /* OPENOCD_FLASH_NAND_LPC32XX_H */
diff --git a/src/flash/nand/mx3.c b/src/flash/nand/mx3.c
index 51fa680fd..b61e47535 100644
--- a/src/flash/nand/mx3.c
+++ b/src/flash/nand/mx3.c
@@ -15,9 +15,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/mx3.h b/src/flash/nand/mx3.h
index 60ec2938c..00664d866 100644
--- a/src/flash/nand/mx3.h
+++ b/src/flash/nand/mx3.h
@@ -14,11 +14,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_FLASH_NAND_MX3_H
+#define OPENOCD_FLASH_NAND_MX3_H
+
/*
* Freescale iMX3* OpenOCD NAND Flash controller support.
*
@@ -107,3 +108,5 @@ struct mx3_nf_controller {
enum mx_nf_finalize_action fin;
struct mx3_nf_flags flags;
};
+
+#endif /* OPENOCD_FLASH_NAND_MX3_H */
diff --git a/src/flash/nand/mxc.c b/src/flash/nand/mxc.c
index b91460ef2..5e59b9a6c 100644
--- a/src/flash/nand/mxc.c
+++ b/src/flash/nand/mxc.c
@@ -20,9 +20,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/mxc.h b/src/flash/nand/mxc.h
index 866e0e323..a1887288b 100644
--- a/src/flash/nand/mxc.h
+++ b/src/flash/nand/mxc.h
@@ -1,4 +1,3 @@
-
/***************************************************************************
* Copyright (C) 2009 by Alexei Babich *
* Rezonans plc., Chelyabinsk, Russia *
@@ -18,11 +17,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_FLASH_NAND_MXC_H
+#define OPENOCD_FLASH_NAND_MXC_H
+
/*
* Freescale iMX OpenOCD NAND Flash controller support.
* based on Freescale iMX2* and iMX3* OpenOCD NAND Flash controller support.
@@ -164,3 +164,5 @@ struct mxc_nf_controller {
enum mxc_nf_finalize_action fin;
struct mxc_nf_flags flags;
};
+
+#endif /* OPENOCD_FLASH_NAND_MXC_H */
diff --git a/src/flash/nand/nonce.c b/src/flash/nand/nonce.c
index 6b3dbad86..6fda2618e 100644
--- a/src/flash/nand/nonce.c
+++ b/src/flash/nand/nonce.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/nuc910.c b/src/flash/nand/nuc910.c
index 832eeae41..1a2dd5968 100644
--- a/src/flash/nand/nuc910.c
+++ b/src/flash/nand/nuc910.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/nuc910.h b/src/flash/nand/nuc910.h
index e0e458f3e..8877cf633 100644
--- a/src/flash/nand/nuc910.h
+++ b/src/flash/nand/nuc910.h
@@ -13,17 +13,15 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
* NAND controller interface for Nuvoton NUC910
*/
-#ifndef NUC910_H
-#define NUC910_H
+#ifndef OPENOCD_FLASH_NAND_NUC910_H
+#define OPENOCD_FLASH_NAND_NUC910_H
#define NUC910_FMICSR 0xB000D000
#define NUC910_SMCSR 0xB000D0A0
@@ -56,5 +54,4 @@
/* ECC4 Correction Status (ECC4ST) */
-#endif /* NUC910_H */
-
+#endif /* OPENOCD_FLASH_NAND_NUC910_H */
diff --git a/src/flash/nand/orion.c b/src/flash/nand/orion.c
index 71f847bf4..69814eca3 100644
--- a/src/flash/nand/orion.c
+++ b/src/flash/nand/orion.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c2410.c b/src/flash/nand/s3c2410.c
index 2aff7a898..57b51b48c 100644
--- a/src/flash/nand/s3c2410.c
+++ b/src/flash/nand/s3c2410.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c2412.c b/src/flash/nand/s3c2412.c
index 6cbdc6c05..002378a16 100644
--- a/src/flash/nand/s3c2412.c
+++ b/src/flash/nand/s3c2412.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c2440.c b/src/flash/nand/s3c2440.c
index b794fabae..44670e6f2 100644
--- a/src/flash/nand/s3c2440.c
+++ b/src/flash/nand/s3c2440.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c2443.c b/src/flash/nand/s3c2443.c
index 8cd3213f2..ffd3864bf 100644
--- a/src/flash/nand/s3c2443.c
+++ b/src/flash/nand/s3c2443.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c24xx.c b/src/flash/nand/s3c24xx.c
index b4c15ce49..ae3f13737 100644
--- a/src/flash/nand/s3c24xx.c
+++ b/src/flash/nand/s3c24xx.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/flash/nand/s3c24xx.h b/src/flash/nand/s3c24xx.h
index c69de2eef..5c7782dab 100644
--- a/src/flash/nand/s3c24xx.h
+++ b/src/flash/nand/s3c24xx.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef S3C24xx_NAND_H
-#define S3C24xx_NAND_H
+#ifndef OPENOCD_FLASH_NAND_S3C24XX_H
+#define OPENOCD_FLASH_NAND_S3C24XX_H
/*
* S3C24XX Series OpenOCD NAND Flash controller support.
@@ -77,4 +75,4 @@ int s3c2440_read_block_data(struct nand_device *nand,
int s3c2440_write_block_data(struct nand_device *nand,
uint8_t *data, int data_size);
-#endif /* S3C24xx_NAND_H */
+#endif /* OPENOCD_FLASH_NAND_S3C24XX_H */
diff --git a/src/flash/nand/s3c24xx_regs.h b/src/flash/nand/s3c24xx_regs.h
index fc0f96f50..88bc66567 100644
--- a/src/flash/nand/s3c24xx_regs.h
+++ b/src/flash/nand/s3c24xx_regs.h
@@ -13,17 +13,15 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
* S3C2410 NAND register definitions
*/
-#ifndef __ASM_ARM_REGS_NAND
-#define __ASM_ARM_REGS_NAND
+#ifndef OPENOCD_FLASH_NAND_S3C24XX_REGS_H
+#define OPENOCD_FLASH_NAND_S3C24XX_REGS_H
#define S3C2410_NFREG(x) (x)
@@ -128,5 +126,4 @@
#define S3C2412_NFECCERR_MULTIBIT (2)
#define S3C2412_NFECCERR_ECCAREA (3)
-#endif /* __ASM_ARM_REGS_NAND */
-
+#endif /* OPENOCD_FLASH_NAND_S3C24XX_REGS_H */
diff --git a/src/flash/nand/s3c6400.c b/src/flash/nand/s3c6400.c
index abbfb2513..7058133bc 100644
--- a/src/flash/nand/s3c6400.c
+++ b/src/flash/nand/s3c6400.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nand/tcl.c b/src/flash/nand/tcl.c
index 750c1f005..d9738c55b 100644
--- a/src/flash/nand/tcl.c
+++ b/src/flash/nand/tcl.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -256,7 +254,8 @@ COMMAND_HANDLER(handle_nand_write_command)
int bytes_read = nand_fileio_read(nand, &s);
if (bytes_read <= 0) {
command_print(CMD_CTX, "error while reading file");
- return nand_fileio_cleanup(&s);
+ nand_fileio_cleanup(&s);
+ return ERROR_FAIL;
}
s.size -= bytes_read;
@@ -266,7 +265,8 @@ COMMAND_HANDLER(handle_nand_write_command)
command_print(CMD_CTX, "failed writing file %s "
"to NAND flash %s at offset 0x%8.8" PRIx32,
CMD_ARGV[1], CMD_ARGV[0], s.address);
- return nand_fileio_cleanup(&s);
+ nand_fileio_cleanup(&s);
+ return retval;
}
s.address += s.page_size;
}
@@ -360,16 +360,16 @@ COMMAND_HANDLER(handle_nand_dump_command)
}
if (NULL != s.page)
- fileio_write(&s.fileio, s.page_size, s.page, &size_written);
+ fileio_write(s.fileio, s.page_size, s.page, &size_written);
if (NULL != s.oob)
- fileio_write(&s.fileio, s.oob_size, s.oob, &size_written);
+ fileio_write(s.fileio, s.oob_size, s.oob, &size_written);
s.size -= nand->page_size;
s.address += nand->page_size;
}
- retval = fileio_size(&s.fileio, &filesize);
+ retval = fileio_size(s.fileio, &filesize);
if (retval != ERROR_OK)
return retval;
@@ -547,7 +547,7 @@ static COMMAND_HELPER(create_nand_device, const char *bank_name,
c->bus_width = 0;
c->address_cycles = 0;
c->page_size = 0;
- c->use_raw = 0;
+ c->use_raw = false;
c->next = NULL;
retval = CALL_COMMAND_HANDLER(controller->nand_device_command, c);
diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index 834e4d47e..c647cbb60 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -1,66 +1,68 @@
-include $(top_srcdir)/common.mk
-
-noinst_LTLIBRARIES = libocdflashnor.la
-libocdflashnor_la_SOURCES = \
- core.c \
- tcl.c \
+noinst_LTLIBRARIES += %D%/libocdflashnor.la
+%C%_libocdflashnor_la_SOURCES = \
+ %D%/core.c \
+ %D%/tcl.c \
$(NOR_DRIVERS) \
- drivers.c
+ %D%/drivers.c \
+ $(NORHEADERS)
NOR_DRIVERS = \
- aduc702x.c \
- aducm360.c \
- at91sam4.c \
- at91sam4l.c \
- at91samd.c \
- at91sam3.c \
- at91sam7.c \
- atsamv.c \
- avrf.c \
- cfi.c \
- efm32.c \
- em357.c \
- faux.c \
- jtagspi.c \
- lpc2000.c \
- lpc288x.c \
- lpc2900.c \
- lpcspifi.c \
- mdr.c \
- non_cfi.c \
- ocl.c \
- pic32mx.c \
- spi.c \
- stmsmi.c \
- stellaris.c \
- stm32f1x.c \
- stm32f2x.c \
- stm32lx.c \
- stm32l4x.c \
- str7x.c \
- str9x.c \
- str9xpec.c \
- tms470.c \
- virtual.c \
- fm3.c \
- dsp5680xx_flash.c \
- kinetis.c \
- numicro.c \
- nrf51.c \
- mrvlqspi.c \
- psoc4.c \
- sim3x.c \
- xmc4xxx.c \
- niietcm4.c
-
-
-noinst_HEADERS = \
- core.h \
- cfi.h \
- driver.h \
- imp.h \
- non_cfi.h \
- ocl.h \
- spi.h
+ %D%/aduc702x.c \
+ %D%/aducm360.c \
+ %D%/ambiqmicro.c \
+ %D%/at91sam4.c \
+ %D%/at91sam4l.c \
+ %D%/at91samd.c \
+ %D%/at91sam3.c \
+ %D%/at91sam7.c \
+ %D%/ath79.c \
+ %D%/atsamv.c \
+ %D%/avrf.c \
+ %D%/cfi.c \
+ %D%/dsp5680xx_flash.c \
+ %D%/efm32.c \
+ %D%/em357.c \
+ %D%/faux.c \
+ %D%/fespi.c \
+ %D%/fm3.c \
+ %D%/fm4.c \
+ %D%/jtagspi.c \
+ %D%/kinetis.c \
+ %D%/kinetis_ke.c \
+ %D%/lpc2000.c \
+ %D%/lpc288x.c \
+ %D%/lpc2900.c \
+ %D%/lpcspifi.c \
+ %D%/mdr.c \
+ %D%/mrvlqspi.c \
+ %D%/niietcm4.c \
+ %D%/non_cfi.c \
+ %D%/nrf51.c \
+ %D%/numicro.c \
+ %D%/ocl.c \
+ %D%/pic32mx.c \
+ %D%/psoc4.c \
+ %D%/sim3x.c \
+ %D%/spi.c \
+ %D%/stmsmi.c \
+ %D%/stellaris.c \
+ %D%/stm32f1x.c \
+ %D%/stm32f2x.c \
+ %D%/stm32lx.c \
+ %D%/stm32l4x.c \
+ %D%/str7x.c \
+ %D%/str9x.c \
+ %D%/str9xpec.c \
+ %D%/tms470.c \
+ %D%/virtual.c \
+ %D%/xmc1xxx.c \
+ %D%/xmc4xxx.c
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+NORHEADERS = \
+ %D%/core.h \
+ %D%/cfi.h \
+ %D%/driver.h \
+ %D%/imp.h \
+ %D%/non_cfi.h \
+ %D%/ocl.h \
+ %D%/spi.h
diff --git a/src/flash/nor/aduc702x.c b/src/flash/nor/aduc702x.c
index 88522458d..34cc362eb 100644
--- a/src/flash/nor/aduc702x.c
+++ b/src/flash/nor/aduc702x.c
@@ -14,9 +14,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -373,7 +371,7 @@ static int aduc702x_check_flash_completion(struct target *target, unsigned int t
{
uint8_t v = 4;
- long long endtime = timeval_ms() + timeout_ms;
+ int64_t endtime = timeval_ms() + timeout_ms;
while (1) {
target_read_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEESTA, &v);
if ((v & 4) == 0)
diff --git a/src/flash/nor/aducm360.c b/src/flash/nor/aducm360.c
index 3e446f539..8681a25af 100644
--- a/src/flash/nor/aducm360.c
+++ b/src/flash/nor/aducm360.c
@@ -12,6 +12,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
/***************************************************************************
@@ -549,7 +551,7 @@ static int aducm360_check_flash_completion(struct target *target, unsigned int t
{
uint32_t v = 1;
- long long endtime = timeval_ms() + timeout_ms;
+ int64_t endtime = timeval_ms() + timeout_ms;
while (1) {
target_read_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEESTA, &v);
if ((v & 0x00000001) == 0)
diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c
index 9d119bbf5..1536378df 100644
--- a/src/flash/nor/at91sam3.c
+++ b/src/flash/nor/at91sam3.c
@@ -8,19 +8,17 @@
* 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 *
+ * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the *
- * GNU General public License for more details. *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
****************************************************************************/
/* Some of the the lower level code was based on code supplied by
@@ -2177,7 +2175,7 @@ static int EFC_PerformCommand(struct sam3_bank_private *pPrivate,
int r;
uint32_t v;
- long long ms_now, ms_end;
+ int64_t ms_now, ms_end;
/* default */
if (status)
@@ -2482,7 +2480,7 @@ static const char *const eproc_names[] = {
_unknown, /* 0 */
"arm946es", /* 1 */
"arm7tdmi", /* 2 */
- "cortex-m3", /* 3 */
+ "Cortex-M3", /* 3 */
"arm920t", /* 4 */
"arm926ejs", /* 5 */
_unknown, /* 6 */
diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c
index c40d085a9..ff75b4188 100644
--- a/src/flash/nor/at91sam4.c
+++ b/src/flash/nor/at91sam4.c
@@ -9,19 +9,17 @@
* (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 *
+ * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the *
- * GNU General public License for more details. *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
****************************************************************************/
/* Some of the the lower level code was based on code supplied by
@@ -67,8 +65,9 @@
#define REG_NAME_WIDTH (12)
-/* at91sam4s/at91sam4e series (has always one flash bank)*/
+/* at91sam4s/at91sam4e/at91sam4c series (has always one flash bank)*/
#define FLASH_BANK_BASE_S 0x00400000
+#define FLASH_BANK_BASE_C 0x01000000
/* at91sam4sd series (two one flash banks), first bank address */
#define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S
@@ -77,6 +76,10 @@
/* at91sam4sd32x, second bank address */
#define FLASH_BANK1_BASE_2048K_SD (FLASH_BANK0_BASE_SD+(2048*1024/2))
+/* at91sam4c32x, first and second bank address */
+#define FLASH_BANK0_BASE_C32 FLASH_BANK_BASE_C
+#define FLASH_BANK1_BASE_C32 (FLASH_BANK_BASE_C+(2048*1024/2))
+
#define AT91C_EFC_FCMD_GETD (0x0) /* (EFC) Get Flash Descriptor */
#define AT91C_EFC_FCMD_WP (0x1) /* (EFC) Write Page */
#define AT91C_EFC_FCMD_WPL (0x2) /* (EFC) Write Page and Lock */
@@ -260,12 +263,93 @@ static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx)
/* these are used to *initialize* the "pChip->details" structure. */
static const struct sam4_chip_details all_sam4_details[] = {
-
- /* Start at91sam4e* series */
- /*atsam4e16e - LQFP144/LFBGA144*/
+ /* Start at91sam4c* series */
+ /* at91sam4c32e - LQFP144 */
{
- .chipid_cidr = 0xA3CC0CE0,
- .name = "at91sam4e16e",
+ .chipid_cidr = 0xA66D0EE0,
+ .name = "at91sam4c32e",
+ .total_flash_size = 2024 * 1024,
+ .total_sram_size = 256 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_C32,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_C32,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+ /* at91sam4c32c - LQFP100 */
+ {
+ .chipid_cidr = 0xA64D0EE0,
+ .name = "at91sam4c32c",
+ .total_flash_size = 2024 * 1024,
+ .total_sram_size = 256 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_C32,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_C32,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+ /* at91sam4c16c - LQFP100 */
+ {
+ .chipid_cidr = 0xA64C0CE0,
+ .name = "at91sam4c16c",
.total_flash_size = 1024 * 1024,
.total_sram_size = 128 * 1024,
.n_gpnvms = 2,
@@ -277,9 +361,9 @@ static const struct sam4_chip_details all_sam4_details[] = {
.pChip = NULL,
.pBank = NULL,
.bank_number = 0,
- .base_address = FLASH_BANK_BASE_S,
+ .base_address = FLASH_BANK_BASE_C,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
.size_bytes = 1024 * 1024,
.nsectors = 128,
@@ -295,13 +379,11 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
-
- /* Start at91sam4s* series */
- /*atsam4s16c - LQFP100/BGA100*/
+ /* at91sam4c8c - LQFP100 */
{
- .chipid_cidr = 0x28AC0CE0,
- .name = "at91sam4s16c",
- .total_flash_size = 1024 * 1024,
+ .chipid_cidr = 0xA64C0AE0,
+ .name = "at91sam4c8c",
+ .total_flash_size = 512 * 1024,
.total_sram_size = 128 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
@@ -312,12 +394,12 @@ static const struct sam4_chip_details all_sam4_details[] = {
.pChip = NULL,
.pBank = NULL,
.bank_number = 0,
- .base_address = FLASH_BANK_BASE_S,
+ .base_address = FLASH_BANK_BASE_C,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
- .size_bytes = 1024 * 1024,
- .nsectors = 128,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
.sector_size = 8192,
.page_size = 512,
},
@@ -330,11 +412,11 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s16b - LQFP64/QFN64*/
+ /* at91sam4c4c (rev B) - LQFP100 */
{
- .chipid_cidr = 0x289C0CE0,
- .name = "at91sam4s16b",
- .total_flash_size = 1024 * 1024,
+ .chipid_cidr = 0xA64C0CE5,
+ .name = "at91sam4c4c",
+ .total_flash_size = 256 * 1024,
.total_sram_size = 128 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
@@ -345,12 +427,12 @@ static const struct sam4_chip_details all_sam4_details[] = {
.pChip = NULL,
.pBank = NULL,
.bank_number = 0,
- .base_address = FLASH_BANK_BASE_S,
+ .base_address = FLASH_BANK_BASE_C,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
- .size_bytes = 1024 * 1024,
- .nsectors = 128,
+ .size_bytes = 256 * 1024,
+ .nsectors = 32,
.sector_size = 8192,
.page_size = 512,
},
@@ -363,12 +445,14 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4sa16b - LQFP64/QFN64*/
+
+ /* Start at91sam4e* series */
+ /*atsam4e16e - LQFP144/LFBGA144*/
{
- .chipid_cidr = 0x28970CE0,
- .name = "at91sam4sa16b",
+ .chipid_cidr = 0xA3CC0CE0,
+ .name = "at91sam4e16e",
.total_flash_size = 1024 * 1024,
- .total_sram_size = 160 * 1024,
+ .total_sram_size = 128 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -396,12 +480,14 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s16a - LQFP48/QFN48*/
+
+ /* Start at91sam4n* series */
+ /*atsam4n8a - LQFP48/QFN48*/
{
- .chipid_cidr = 0x288C0CE0,
- .name = "at91sam4s16a",
- .total_flash_size = 1024 * 1024,
- .total_sram_size = 128 * 1024,
+ .chipid_cidr = 0x293B0AE0,
+ .name = "at91sam4n8a",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 64 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -415,8 +501,8 @@ static const struct sam4_chip_details all_sam4_details[] = {
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.present = 1,
- .size_bytes = 1024 * 1024,
- .nsectors = 128,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
.sector_size = 8192,
.page_size = 512,
},
@@ -429,12 +515,12 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s8c - LQFP100/BGA100*/
+ /*atsam4n8b - LQFP64/QFN64*/
{
- .chipid_cidr = 0x28AC0AE0,
- .name = "at91sam4s8c",
+ .chipid_cidr = 0x294B0AE0,
+ .name = "at91sam4n8b",
.total_flash_size = 512 * 1024,
- .total_sram_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -462,12 +548,12 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s8b - LQFP64/BGA64*/
+ /*atsam4n8c - LQFP100/TFBGA100/VFBGA100*/
{
- .chipid_cidr = 0x289C0AE0,
- .name = "at91sam4s8b",
+ .chipid_cidr = 0x295B0AE0,
+ .name = "at91sam4n8c",
.total_flash_size = 512 * 1024,
- .total_sram_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -495,12 +581,12 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s8a - LQFP48/BGA48*/
+ /*atsam4n16b - LQFP64/QFN64*/
{
- .chipid_cidr = 0x288C0AE0,
- .name = "at91sam4s8a",
- .total_flash_size = 512 * 1024,
- .total_sram_size = 128 * 1024,
+ .chipid_cidr = 0x29460CE0,
+ .name = "at91sam4n16b",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 80 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -514,8 +600,8 @@ static const struct sam4_chip_details all_sam4_details[] = {
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.present = 1,
- .size_bytes = 512 * 1024,
- .nsectors = 64,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
.sector_size = 8192,
.page_size = 512,
},
@@ -528,13 +614,12 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
-
- /*atsam4s4a - LQFP48/BGA48*/
+ /*atsam4n16c - LQFP100/TFBGA100/VFBGA100*/
{
- .chipid_cidr = 0x288b09e0,
- .name = "at91sam4s4a",
- .total_flash_size = 256 * 1024,
- .total_sram_size = 64 * 1024,
+ .chipid_cidr = 0x29560CE0,
+ .name = "at91sam4n16c",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 80 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -548,8 +633,8 @@ static const struct sam4_chip_details all_sam4_details[] = {
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.present = 1,
- .size_bytes = 256 * 1024,
- .nsectors = 32,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
.sector_size = 8192,
.page_size = 512,
},
@@ -563,69 +648,550 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
- /*at91sam4sd32c*/
+ /* Start at91sam4s* series */
+ /*atsam4s16c - LQFP100/BGA100*/
{
- .chipid_cidr = 0x29a70ee0,
- .name = "at91sam4sd32c",
- .total_flash_size = 2048 * 1024,
- .total_sram_size = 160 * 1024,
- .n_gpnvms = 3,
- .n_banks = 2,
-
-/* .bank[0] = { */
+ .chipid_cidr = 0x28AC0CE0,
+ .name = "at91sam4s16c",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
{
- {
- .probed = 0,
- .pChip = NULL,
- .pBank = NULL,
- .bank_number = 0,
- .base_address = FLASH_BANK0_BASE_SD,
- .controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
- .present = 1,
- .size_bytes = 1024 * 1024,
- .nsectors = 128,
- .sector_size = 8192,
- .page_size = 512,
- },
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
-/* .bank[1] = { */
- {
- .probed = 0,
- .pChip = NULL,
- .pBank = NULL,
- .bank_number = 1,
- .base_address = FLASH_BANK1_BASE_2048K_SD,
- .controller_address = 0x400e0c00,
- .flash_wait_states = 6, /* workaround silicon bug */
- .present = 1,
- .size_bytes = 1024 * 1024,
- .nsectors = 128,
- .sector_size = 8192,
- .page_size = 512,
- },
+ },
},
},
+ /*atsam4s16b - LQFP64/QFN64/WLCSP64*/
+ {
+ .chipid_cidr = 0x289C0CE0,
+ .name = "at91sam4s16b",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
- /*at91sam4sd16c*/
+ },
+ },
+ },
+ /*atsam4sa16b - LQFP64/QFN64*/
{
- .chipid_cidr = 0x29a70ce0,
- .name = "at91sam4sd16c",
+ .chipid_cidr = 0x28970CE0,
+ .name = "at91sam4sa16b",
.total_flash_size = 1024 * 1024,
.total_sram_size = 160 * 1024,
- .n_gpnvms = 3,
- .n_banks = 2,
-
-/* .bank[0] = { */
+ .n_gpnvms = 2,
+ .n_banks = 1,
{
- {
- .probed = 0,
- .pChip = NULL,
- .pBank = NULL,
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4s16a - LQFP48/QFN48*/
+ {
+ .chipid_cidr = 0x288C0CE0,
+ .name = "at91sam4s16a",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4s8c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x28AC0AE0,
+ .name = "at91sam4s8c",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4s8b - LQFP64/QFN64/WLCSP64*/
+ {
+ .chipid_cidr = 0x289C0AE0,
+ .name = "at91sam4s8b",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4s8a - LQFP48/BGA48*/
+ {
+ .chipid_cidr = 0x288C0AE0,
+ .name = "at91sam4s8a",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /*atsam4s4c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x28ab09e0,
+ .name = "at91sam4s4c",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 32,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /*atsam4s4b - LQFP64/QFN64/WLCSP64*/
+ {
+ .chipid_cidr = 0x289b09e0,
+ .name = "at91sam4s4b",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 32,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /*atsam4s4a - LQFP48/QFN48*/
+ {
+ .chipid_cidr = 0x288b09e0,
+ .name = "at91sam4s4a",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 32,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /*atsam4s2c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x28ab07e0,
+ .name = "at91sam4s2c",
+ .total_flash_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 16,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /*atsam4s2b - LQPF64/QFN64/WLCSP64*/
+ {
+ .chipid_cidr = 0x289b07e0,
+ .name = "at91sam4s2b",
+ .total_flash_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 16,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /*atsam4s2a - LQFP48/QFN48*/
+ {
+ .chipid_cidr = 0x288b07e0,
+ .name = "at91sam4s2a",
+ .total_flash_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 16,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /*at91sam4sd32c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x29a70ee0,
+ .name = "at91sam4sd32c",
+ .total_flash_size = 2048 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
.bank_number = 0,
.base_address = FLASH_BANK0_BASE_SD,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_2048K_SD,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+
+ /*at91sam4sd32b - LQFP64/BGA64*/
+ {
+ .chipid_cidr = 0x29970ee0,
+ .name = "at91sam4sd32b",
+ .total_flash_size = 2048 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_2048K_SD,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+
+ /*at91sam4sd16c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x29a70ce0,
+ .name = "at91sam4sd16c",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@@ -641,7 +1207,51 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 1,
.base_address = FLASH_BANK1_BASE_1024K_SD,
.controller_address = 0x400e0c00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+
+ /*at91sam4sd16b - LQFP64/BGA64*/
+ {
+ .chipid_cidr = 0x29970ce0,
+ .name = "at91sam4sd16b",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_1024K_SD,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@@ -730,6 +1340,74 @@ static const struct sam4_chip_details all_sam4_details[] = {
}
},
+ /* atsamg55g19 */
+ {
+ .chipid_cidr = 0x24470ae0,
+ .name = "atsamg55g19",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+
+ {
+/* .bank[0] = */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+ },
+ }
+ },
+
+ /* atsamg55j19 */
+ {
+ .chipid_cidr = 0x24570ae0,
+ .name = "atsamg55j19",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+
+ {
+/* .bank[0] = */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+ },
+ }
+ },
+
/* terminate */
{
.chipid_cidr = 0,
@@ -888,7 +1566,7 @@ static int EFC_PerformCommand(struct sam4_bank_private *pPrivate,
int r;
uint32_t v;
- long long ms_now, ms_end;
+ int64_t ms_now, ms_end;
/* default */
if (status)
@@ -1237,14 +1915,14 @@ static uint32_t sam4_reg_fieldname(struct sam4_chip *pChip,
static const char _unknown[] = "unknown";
static const char *const eproc_names[] = {
- _unknown, /* 0 */
+ "Cortex-M7", /* 0 */
"arm946es", /* 1 */
"arm7tdmi", /* 2 */
- "cortex-m3", /* 3 */
+ "Cortex-M3", /* 3 */
"arm920t", /* 4 */
"arm926ejs", /* 5 */
- "cortex-a5", /* 6 */
- "cortex-m4", /* 7 */
+ "Cortex-A5", /* 6 */
+ "Cortex-M4", /* 7 */
_unknown, /* 8 */
_unknown, /* 9 */
_unknown, /* 10 */
@@ -1265,7 +1943,7 @@ static const char *const nvpsize[] = {
"64K bytes", /* 5 */
_unknown, /* 6 */
"128K bytes", /* 7 */
- _unknown, /* 8 */
+ "160K bytes", /* 8 */
"256K bytes", /* 9 */
"512K bytes", /* 10 */
_unknown, /* 11 */
@@ -1307,12 +1985,16 @@ static const struct archnames { unsigned value; const char *name; } archnames[]
{ 0x42, "AT91x42 Series" },
{ 0x43, "SAMG51 Series"
},
+ { 0x44, "SAMG55 Series (49-pin WLCSP)" },
+ { 0x45, "SAMG55 Series (64-pin)" },
{ 0x47, "SAMG53 Series"
},
{ 0x55, "AT91x55 Series" },
{ 0x60, "AT91SAM7Axx Series" },
{ 0x61, "AT91SAM7AQxx Series" },
{ 0x63, "AT91x63 Series" },
+ { 0x64, "SAM4CxxC (100-pin version)" },
+ { 0x66, "SAM4CxxE (144-pin version)" },
{ 0x70, "AT91SAM7Sxx Series" },
{ 0x71, "AT91SAM7XCxx Series" },
{ 0x72, "AT91SAM7SExx Series" },
@@ -1810,15 +2492,17 @@ FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command)
/* at91sam4s series only has bank 0*/
/* at91sam4sd series has the same address for bank 0 (FLASH_BANK0_BASE_SD)*/
case FLASH_BANK_BASE_S:
+ case FLASH_BANK_BASE_C:
bank->driver_priv = &(pChip->details.bank[0]);
bank->bank_number = 0;
pChip->details.bank[0].pChip = pChip;
pChip->details.bank[0].pBank = bank;
break;
- /* Bank 1 of at91sam4sd series */
+ /* Bank 1 of at91sam4sd/at91sam4c32 series */
case FLASH_BANK1_BASE_1024K_SD:
case FLASH_BANK1_BASE_2048K_SD:
+ case FLASH_BANK1_BASE_C32:
bank->driver_priv = &(pChip->details.bank[1]);
bank->bank_number = 1;
pChip->details.bank[1].pChip = pChip;
diff --git a/src/flash/nor/at91sam4l.c b/src/flash/nor/at91sam4l.c
index fa7cff38c..0a605d5d7 100644
--- a/src/flash/nor/at91sam4l.c
+++ b/src/flash/nor/at91sam4l.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -647,10 +645,15 @@ static int sam4l_write(struct flash_bank *bank, const uint8_t *buffer,
COMMAND_HANDLER(sam4l_handle_reset_deassert)
{
struct target *target = get_current_target(CMD_CTX);
- struct armv7m_common *armv7m = target_to_armv7m(target);
int retval = ERROR_OK;
enum reset_types jtag_reset_config = jtag_get_reset_config();
+ /* If the target has been unresponsive before, try to re-establish
+ * communication now - CPU is held in reset by DSU, DAP is working */
+ if (!target_was_examined(target))
+ target_examine_one(target);
+ target_poll(target);
+
/* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()
* so we just release reset held by SMAP
*
@@ -659,14 +662,14 @@ COMMAND_HANDLER(sam4l_handle_reset_deassert)
* After vectreset SMAP release is not needed however makes no harm
*/
if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {
- retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
+ retval = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
if (retval == ERROR_OK)
- retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
+ retval = target_write_u32(target, DCB_DEMCR,
TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
/* do not return on error here, releasing SMAP reset is more important */
}
- int retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, SMAP_SCR, SMAP_SCR_HCR);
+ int retval2 = target_write_u32(target, SMAP_SCR, SMAP_SCR_HCR);
if (retval2 != ERROR_OK)
return retval2;
diff --git a/src/flash/nor/at91sam7.c b/src/flash/nor/at91sam7.c
index c7334ca53..03f771c87 100644
--- a/src/flash/nor/at91sam7.c
+++ b/src/flash/nor/at91sam7.c
@@ -5,19 +5,17 @@
* 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 *
+ * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the *
- * GNU General public License for more details. *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
****************************************************************************/
/***************************************************************************
@@ -373,10 +371,9 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
if (at91sam7_info->cidr != 0) {
/* flash already configured, update clock and check for protected sectors */
- struct flash_bank *fb = bank;
- struct flash_bank *t_bank = bank;
-
- while (t_bank) {
+ for (struct flash_bank *t_bank = bank; t_bank; t_bank = t_bank->next) {
+ if (t_bank->target != target)
+ continue;
/* re-calculate master clock frequency */
at91sam7_read_clock_info(t_bank);
@@ -385,9 +382,6 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
/* check protect state */
at91sam7_protect_check(t_bank);
-
- t_bank = fb->next;
- fb = t_bank;
}
return ERROR_OK;
@@ -402,9 +396,10 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
if (at91sam7_info->flash_autodetection == 0) {
/* banks and sectors are already created, based on data from input file */
- struct flash_bank *fb = bank;
- struct flash_bank *t_bank = bank;
- while (t_bank) {
+ for (struct flash_bank *t_bank = bank; t_bank; t_bank = t_bank->next) {
+ if (t_bank->target != target)
+ continue;
+
at91sam7_info = t_bank->driver_priv;
at91sam7_info->cidr = cidr;
@@ -425,9 +420,6 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
/* check protect state */
at91sam7_protect_check(t_bank);
-
- t_bank = fb->next;
- fb = t_bank;
}
return ERROR_OK;
@@ -669,7 +661,7 @@ static int at91sam7_erase_check(struct flash_bank *bank)
retval = target_blank_check_memory(target,
bank->base + bank->sectors[nSector].offset,
bank->sectors[nSector].size,
- &blank);
+ &blank, bank->erased_value);
if (retval != ERROR_OK) {
fast_check = 0;
break;
diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c
index 2730f71b2..f018e893d 100644
--- a/src/flash/nor/at91samd.c
+++ b/src/flash/nor/at91samd.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -38,6 +36,7 @@
#define SAMD_DSU_STATUSA 1 /* DSU status register */
#define SAMD_DSU_DID 0x18 /* Device ID register */
+#define SAMD_DSU_CTRL_EXT 0x100 /* CTRL register, external access */
#define SAMD_NVMCTRL_CTRLA 0x00 /* NVM control A register */
#define SAMD_NVMCTRL_CTRLB 0x04 /* NVM control B register */
@@ -73,8 +72,10 @@
#define SAMD_FAMILY_C 0x02
#define SAMD_SERIES_20 0x00
#define SAMD_SERIES_21 0x01
+#define SAMD_SERIES_22 0x02
#define SAMD_SERIES_10 0x02
#define SAMD_SERIES_11 0x03
+#define SAMD_SERIES_09 0x04
/* Device ID macros */
#define SAMD_GET_PROCESSOR(id) (id >> 28)
@@ -89,6 +90,13 @@ struct samd_part {
uint32_t ram_kb;
};
+/* Known SAMD09 parts. DID reset values missing in RM, see
+ * https://github.com/avrxml/asf/blob/master/sam0/utils/cmsis/samd09/include/ */
+static const struct samd_part samd09_parts[] = {
+ { 0x0, "SAMD09D14A", 16, 4 },
+ { 0x7, "SAMD09C13A", 8, 4 },
+};
+
/* Known SAMD10 parts */
static const struct samd_part samd10_parts[] = {
{ 0x0, "SAMD10D14AMU", 16, 4 },
@@ -151,6 +159,13 @@ static const struct samd_part samd21_parts[] = {
{ 0xC, "SAMD21E16A", 64, 8 },
{ 0xD, "SAMD21E15A", 32, 4 },
{ 0xE, "SAMD21E14A", 16, 2 },
+ /* Below are B Variants (Table 3-7 from rev I of datasheet) */
+ { 0x20, "SAMD21J16B", 64, 8 },
+ { 0x21, "SAMD21J15B", 32, 4 },
+ { 0x23, "SAMD21G16B", 64, 8 },
+ { 0x24, "SAMD21G15B", 32, 4 },
+ { 0x26, "SAMD21E16B", 64, 8 },
+ { 0x27, "SAMD21E15B", 32, 4 },
};
/* Known SAMR21 parts. */
@@ -187,6 +202,19 @@ static const struct samd_part saml21_parts[] = {
{ 0x1C, "SAML21E15B", 32, 4 },
};
+/* Known SAML22 parts. */
+static const struct samd_part saml22_parts[] = {
+ { 0x00, "SAML22N18A", 256, 32 },
+ { 0x01, "SAML22N17A", 128, 16 },
+ { 0x02, "SAML22N16A", 64, 8 },
+ { 0x05, "SAML22J18A", 256, 32 },
+ { 0x06, "SAML22J17A", 128, 16 },
+ { 0x07, "SAML22J16A", 64, 8 },
+ { 0x0A, "SAML22G18A", 256, 32 },
+ { 0x0B, "SAML22G17A", 128, 16 },
+ { 0x0C, "SAML22G16A", 64, 8 },
+};
+
/* Known SAMC20 parts. */
static const struct samd_part samc20_parts[] = {
{ 0x00, "SAMC20J18A", 256, 32 },
@@ -238,12 +266,16 @@ static const struct samd_family samd_families[] = {
samd21_parts, ARRAY_SIZE(samd21_parts) },
{ SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_21,
samr21_parts, ARRAY_SIZE(samr21_parts) },
+ { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_09,
+ samd09_parts, ARRAY_SIZE(samd09_parts) },
{ SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_10,
samd10_parts, ARRAY_SIZE(samd10_parts) },
{ SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_11,
samd11_parts, ARRAY_SIZE(samd11_parts) },
{ SAMD_PROCESSOR_M0, SAMD_FAMILY_L, SAMD_SERIES_21,
saml21_parts, ARRAY_SIZE(saml21_parts) },
+ { SAMD_PROCESSOR_M0, SAMD_FAMILY_L, SAMD_SERIES_22,
+ saml22_parts, ARRAY_SIZE(saml22_parts) },
{ SAMD_PROCESSOR_M0, SAMD_FAMILY_C, SAMD_SERIES_20,
samc20_parts, ARRAY_SIZE(samc20_parts) },
{ SAMD_PROCESSOR_M0, SAMD_FAMILY_C, SAMD_SERIES_21,
@@ -342,7 +374,7 @@ static int samd_probe(struct flash_bank *bank)
part = samd_find_part(id);
if (part == NULL) {
- LOG_ERROR("Couldn't find part correspoding to DID %08" PRIx32, id);
+ LOG_ERROR("Couldn't find part corresponding to DID %08" PRIx32, id);
return ERROR_FAIL;
}
@@ -392,39 +424,43 @@ static int samd_probe(struct flash_bank *bank)
return ERROR_OK;
}
-static bool samd_check_error(struct target *target)
+static int samd_check_error(struct target *target)
{
- int ret;
- bool error;
+ int ret, ret2;
uint16_t status;
ret = target_read_u16(target,
SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, &status);
if (ret != ERROR_OK) {
LOG_ERROR("Can't read NVM status");
- return true;
+ return ret;
}
- if (status & 0x001C) {
- if (status & (1 << 4)) /* NVME */
- LOG_ERROR("SAMD: NVM Error");
- if (status & (1 << 3)) /* LOCKE */
- LOG_ERROR("SAMD: NVM lock error");
- if (status & (1 << 2)) /* PROGE */
- LOG_ERROR("SAMD: NVM programming error");
+ if ((status & 0x001C) == 0)
+ return ERROR_OK;
- error = true;
- } else {
- error = false;
+ if (status & (1 << 4)) { /* NVME */
+ LOG_ERROR("SAMD: NVM Error");
+ ret = ERROR_FLASH_OPERATION_FAILED;
+ }
+
+ if (status & (1 << 3)) { /* LOCKE */
+ LOG_ERROR("SAMD: NVM lock error");
+ ret = ERROR_FLASH_PROTECTED;
+ }
+
+ if (status & (1 << 2)) { /* PROGE */
+ LOG_ERROR("SAMD: NVM programming error");
+ ret = ERROR_FLASH_OPER_UNSUPPORTED;
}
/* Clear the error conditions by writing a one to them */
- ret = target_write_u16(target,
+ ret2 = target_write_u16(target,
SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, status);
- if (ret != ERROR_OK)
+ if (ret2 != ERROR_OK)
LOG_ERROR("Can't clear NVM error conditions");
- return error;
+ return ret;
}
static int samd_issue_nvmctrl_command(struct target *target, uint16_t cmd)
@@ -443,10 +479,7 @@ static int samd_issue_nvmctrl_command(struct target *target, uint16_t cmd)
return res;
/* Check to see if the NVM command resulted in an error condition. */
- if (samd_check_error(target))
- return ERROR_FAIL;
-
- return ERROR_OK;
+ return samd_check_error(target);
}
static int samd_erase_row(struct target *target, uint32_t address)
@@ -500,12 +533,19 @@ static int samd_modify_user_row(struct target *target, uint32_t value,
uint8_t startb, uint8_t endb)
{
int res;
+ uint32_t nvm_ctrlb;
+ bool manual_wp = true;
if (is_user_row_reserved_bit(startb) || is_user_row_reserved_bit(endb)) {
LOG_ERROR("Can't modify bits in the requested range");
return ERROR_FAIL;
}
+ /* Check if we need to do manual page write commands */
+ res = target_read_u32(target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB, &nvm_ctrlb);
+ if (res == ERROR_OK)
+ manual_wp = (nvm_ctrlb & SAMD_NVM_CTRLB_MANW) != 0;
+
/* Retrieve the MCU's page size, in bytes. This is also the size of the
* entire User Row. */
uint32_t page_size;
@@ -528,8 +568,8 @@ static int samd_modify_user_row(struct target *target, uint32_t value,
if (!buf)
return ERROR_FAIL;
- /* Read the user row (comprising one page) by half-words. */
- res = target_read_memory(target, SAMD_USER_ROW, 2, page_size / 2, buf);
+ /* Read the user row (comprising one page) by words. */
+ res = target_read_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);
if (res != ERROR_OK)
goto out_user_row;
@@ -548,20 +588,18 @@ static int samd_modify_user_row(struct target *target, uint32_t value,
/* Modify */
buf_set_u32(buf, startb, endb - startb + 1, value);
- /* Write the page buffer back out to the target. A Flash write will be
- * triggered automatically. */
+ /* Write the page buffer back out to the target. */
res = target_write_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);
if (res != ERROR_OK)
goto out_user_row;
- if (samd_check_error(target)) {
- res = ERROR_FAIL;
- goto out_user_row;
+ if (manual_wp) {
+ /* Trigger flash write */
+ res = samd_issue_nvmctrl_command(target, SAMD_NVM_CMD_WAP);
+ } else {
+ res = samd_check_error(target);
}
- /* Success */
- res = ERROR_OK;
-
out_user_row:
free(buf);
@@ -601,7 +639,7 @@ static int samd_protect(struct flash_bank *bank, int set, int first, int last)
/* We've now applied our changes, however they will be undone by the next
* reset unless we also apply them to the LOCK bits in the User Page. The
- * LOCK bits start at bit 48, correspoding to Sector 0 and end with bit 63,
+ * LOCK bits start at bit 48, corresponding to Sector 0 and end with bit 63,
* corresponding to Sector 15. A '1' means unlocked and a '0' means
* locked. See Table 9-3 in the SAMD20 datasheet for more details. */
@@ -753,18 +791,15 @@ static int samd_write(struct flash_bank *bank, const uint8_t *buffer,
* then issue CMD_WP always */
if (manual_wp || pg_offset + 4 * nw < chip->page_size) {
res = samd_issue_nvmctrl_command(bank->target, SAMD_NVM_CMD_WP);
- if (res != ERROR_OK) {
- LOG_ERROR("%s: %d", __func__, __LINE__);
- goto free_pb;
- }
- }
+ } else {
+ /* Access through AHB is stalled while flash is being programmed */
+ usleep(200);
- /* Access through AHB is stalled while flash is being programmed */
- usleep(200);
+ res = samd_check_error(bank->target);
+ }
- if (samd_check_error(bank->target)) {
+ if (res != ERROR_OK) {
LOG_ERROR("%s: write failed at address 0x%08" PRIx32, __func__, address);
- res = ERROR_FAIL;
goto free_pb;
}
@@ -825,18 +860,23 @@ COMMAND_HANDLER(samd_handle_info_command)
COMMAND_HANDLER(samd_handle_chip_erase_command)
{
struct target *target = get_current_target(CMD_CTX);
+ int res = ERROR_FAIL;
if (target) {
/* Enable access to the DSU by disabling the write protect bit */
target_write_u32(target, SAMD_PAC1, (1<<1));
+ /* intentionally without error checking - not accessible on secured chip */
+
/* Tell the DSU to perform a full chip erase. It takes about 240ms to
* perform the erase. */
- target_write_u8(target, SAMD_DSU, (1<<4));
-
- command_print(CMD_CTX, "chip erased");
+ res = target_write_u8(target, SAMD_DSU + SAMD_DSU_CTRL_EXT, (1<<4));
+ if (res == ERROR_OK)
+ command_print(CMD_CTX, "chip erase started");
+ else
+ command_print(CMD_CTX, "write to DSU CTRL failed");
}
- return ERROR_OK;
+ return res;
}
COMMAND_HANDLER(samd_handle_set_security_command)
@@ -987,10 +1027,15 @@ COMMAND_HANDLER(samd_handle_bootloader_command)
COMMAND_HANDLER(samd_handle_reset_deassert)
{
struct target *target = get_current_target(CMD_CTX);
- struct armv7m_common *armv7m = target_to_armv7m(target);
int retval = ERROR_OK;
enum reset_types jtag_reset_config = jtag_get_reset_config();
+ /* If the target has been unresponsive before, try to re-establish
+ * communication now - CPU is held in reset by DSU, DAP is working */
+ if (!target_was_examined(target))
+ target_examine_one(target);
+ target_poll(target);
+
/* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()
* so we just release reset held by DSU
*
@@ -999,9 +1044,9 @@ COMMAND_HANDLER(samd_handle_reset_deassert)
* After vectreset DSU release is not needed however makes no harm
*/
if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {
- retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
+ retval = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
if (retval == ERROR_OK)
- retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR,
+ retval = target_write_u32(target, DCB_DEMCR,
TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
/* do not return on error here, releasing DSU reset is more important */
}
diff --git a/src/flash/nor/atsamv.c b/src/flash/nor/atsamv.c
index 08f8bb8ba..73f023896 100644
--- a/src/flash/nor/atsamv.c
+++ b/src/flash/nor/atsamv.c
@@ -12,15 +12,17 @@
* (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 *
+ * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the *
- * GNU General public License for more details. *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
* *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
/* Some of the the lower level code was based on code supplied by
@@ -145,7 +147,7 @@ static int samv_efc_perform_command(struct target *target,
{
int r;
uint32_t v;
- long long ms_now, ms_end;
+ int64_t ms_now, ms_end;
if (status)
*status = 0;
@@ -355,12 +357,15 @@ static int samv_probe(struct flash_bank *bank)
uint8_t eproc = (device_id >> 5) & 0x7;
if (eproc != 0) {
- LOG_ERROR("unexpected eproc code: %d was expecting 0 (cortex-m7)", eproc);
+ LOG_ERROR("unexpected eproc code: %d was expecting 0 (Cortex-M7)", eproc);
return ERROR_FAIL;
}
uint8_t nvm_size_code = (device_id >> 8) & 0xf;
switch (nvm_size_code) {
+ case 10:
+ bank->size = 512 * 1024;
+ break;
case 12:
bank->size = 1024 * 1024;
break;
diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c
index 1984c9ef1..11cc3b2d3 100644
--- a/src/flash/nor/avrf.c
+++ b/src/flash/nor/avrf.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -68,6 +66,7 @@ static const struct avrf_type avft_chips_info[] = {
* eeprom_page_size, eeprom_page_num
*/
{"atmega128", 0x9702, 256, 512, 8, 512},
+ {"atmega128rfa1", 0xa701, 128, 512, 8, 512},
{"at90can128", 0x9781, 256, 512, 8, 512},
{"at90usb128", 0x9782, 256, 512, 8, 512},
{"atmega164p", 0x940a, 128, 128, 4, 128},
diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c
index 90d7d83dd..ac0db8271 100644
--- a/src/flash/nor/cfi.c
+++ b/src/flash/nor/cfi.c
@@ -17,9 +17,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -136,6 +134,7 @@ static inline uint32_t flash_address(struct flash_bank *bank, int sector, uint32
static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf)
{
int i;
+ struct cfi_flash_bank *cfi_info = bank->driver_priv;
/* clear whole buffer, to ensure bits that exceed the bus_width
* are set to zero
@@ -143,7 +142,7 @@ static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf)
for (i = 0; i < CFI_MAX_BUS_WIDTH; i++)
cmd_buf[i] = 0;
- if (bank->target->endianness == TARGET_LITTLE_ENDIAN) {
+ if (cfi_info->endianness == TARGET_LITTLE_ENDIAN) {
for (i = bank->bus_width; i > 0; i--)
*cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
} else {
@@ -167,6 +166,7 @@ static int cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t addre
static int cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset, uint8_t *val)
{
struct target *target = bank->target;
+ struct cfi_flash_bank *cfi_info = bank->driver_priv;
uint8_t data[CFI_MAX_BUS_WIDTH];
int retval;
@@ -175,7 +175,7 @@ static int cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset, ui
if (retval != ERROR_OK)
return retval;
- if (bank->target->endianness == TARGET_LITTLE_ENDIAN)
+ if (cfi_info->endianness == TARGET_LITTLE_ENDIAN)
*val = data[0];
else
*val = data[bank->bus_width - 1];
@@ -190,6 +190,7 @@ static int cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset, ui
static int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint8_t *val)
{
struct target *target = bank->target;
+ struct cfi_flash_bank *cfi_info = bank->driver_priv;
uint8_t data[CFI_MAX_BUS_WIDTH];
int i;
@@ -199,7 +200,7 @@ static int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint
if (retval != ERROR_OK)
return retval;
- if (bank->target->endianness == TARGET_LITTLE_ENDIAN) {
+ if (cfi_info->endianness == TARGET_LITTLE_ENDIAN) {
for (i = 0; i < bank->bus_width / bank->chip_width; i++)
data[0] |= data[i];
@@ -236,7 +237,7 @@ static int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, u
return retval;
}
- if (bank->target->endianness == TARGET_LITTLE_ENDIAN)
+ if (cfi_info->endianness == TARGET_LITTLE_ENDIAN)
*val = data[0] | data[bank->bus_width] << 8;
else
*val = data[bank->bus_width - 1] | data[(2 * bank->bus_width) - 1] << 8;
@@ -266,7 +267,7 @@ static int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, u
return retval;
}
- if (bank->target->endianness == TARGET_LITTLE_ENDIAN)
+ if (cfi_info->endianness == TARGET_LITTLE_ENDIAN)
*val = data[0] | data[bank->bus_width] << 8 |
data[bank->bus_width * 2] << 16 | data[bank->bus_width * 3] << 24;
else
@@ -803,6 +804,7 @@ static int cfi_intel_info(struct flash_bank *bank, char *buf, int buf_size)
FLASH_BANK_COMMAND_HANDLER(cfi_flash_bank_command)
{
struct cfi_flash_bank *cfi_info;
+ int bus_swap = 0;
if (CMD_ARGC < 6)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -832,14 +834,26 @@ FLASH_BANK_COMMAND_HANDLER(cfi_flash_bank_command)
cfi_info->x16_as_x8 = 0;
cfi_info->jedec_probe = 0;
cfi_info->not_cfi = 0;
+ cfi_info->data_swap = 0;
for (unsigned i = 6; i < CMD_ARGC; i++) {
if (strcmp(CMD_ARGV[i], "x16_as_x8") == 0)
cfi_info->x16_as_x8 = 1;
+ else if (strcmp(CMD_ARGV[i], "data_swap") == 0)
+ cfi_info->data_swap = 1;
+ else if (strcmp(CMD_ARGV[i], "bus_swap") == 0)
+ bus_swap = 1;
else if (strcmp(CMD_ARGV[i], "jedec_probe") == 0)
cfi_info->jedec_probe = 1;
}
+ if (bus_swap)
+ cfi_info->endianness =
+ bank->target->endianness == TARGET_LITTLE_ENDIAN ?
+ TARGET_BIG_ENDIAN : TARGET_LITTLE_ENDIAN;
+ else
+ cfi_info->endianness = bank->target->endianness;
+
/* bank wasn't probed yet */
cfi_info->qry[0] = 0xff;
@@ -1262,7 +1276,6 @@ static int cfi_intel_write_block(struct flash_bank *bank, const uint8_t *buffer,
LOG_WARNING("No working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- ;
/* write algorithm code to working area */
retval = target_write_buffer(target, write_algorithm->address,
@@ -1284,7 +1297,6 @@ static int cfi_intel_write_block(struct flash_bank *bank, const uint8_t *buffer,
goto cleanup;
}
}
- ;
/* setup algo registers */
init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
@@ -1300,7 +1312,7 @@ static int cfi_intel_write_block(struct flash_bank *bank, const uint8_t *buffer,
busy_pattern_val = cfi_command_val(bank, 0x80);
error_pattern_val = cfi_command_val(bank, 0x7e);
- LOG_DEBUG("Using target buffer at 0x%08" PRIx32 " and of size 0x%04" PRIx32,
+ LOG_DEBUG("Using target buffer at " TARGET_ADDR_FMT " and of size 0x%04" PRIx32,
source->address, buffer_size);
/* Programming main loop */
@@ -1412,50 +1424,50 @@ static int cfi_spansion_write_block_mips(struct flash_bank *bank, const uint8_t
static const uint32_t mips_word_16_code[] = {
/* start: */
- MIPS32_LHU(9, 0, 4), /* lhu $t1, ($a0) ; out = &saddr */
- MIPS32_ADDI(4, 4, 2), /* addi $a0, $a0, 2 ; saddr += 2 */
- MIPS32_SH(13, 0, 12), /* sh $t5, ($t4) ; *fl_unl_addr1 = fl_unl_cmd1 */
- MIPS32_SH(15, 0, 14), /* sh $t7, ($t6) ; *fl_unl_addr2 = fl_unl_cmd2 */
- MIPS32_SH(7, 0, 12), /* sh $a3, ($t4) ; *fl_unl_addr1 = fl_write_cmd */
- MIPS32_SH(9, 0, 5), /* sh $t1, ($a1) ; *daddr = out */
+ MIPS32_LHU(0, 9, 0, 4), /* lhu $t1, ($a0) ; out = &saddr */
+ MIPS32_ADDI(0, 4, 4, 2), /* addi $a0, $a0, 2 ; saddr += 2 */
+ MIPS32_SH(0, 13, 0, 12), /* sh $t5, ($t4) ; *fl_unl_addr1 = fl_unl_cmd1 */
+ MIPS32_SH(0, 15, 0, 14), /* sh $t7, ($t6) ; *fl_unl_addr2 = fl_unl_cmd2 */
+ MIPS32_SH(0, 7, 0, 12), /* sh $a3, ($t4) ; *fl_unl_addr1 = fl_write_cmd */
+ MIPS32_SH(0, 9, 0, 5), /* sh $t1, ($a1) ; *daddr = out */
MIPS32_NOP, /* nop */
/* busy: */
- MIPS32_LHU(10, 0, 5), /* lhu $t2, ($a1) ; temp1 = *daddr */
- MIPS32_XOR(11, 9, 10), /* xor $t3, $a0, $t2 ; temp2 = out ^ temp1; */
- MIPS32_AND(11, 8, 11), /* and $t3, $t0, $t3 ; temp2 = temp2 & DQ7mask */
- MIPS32_BNE(11, 8, 13), /* bne $t3, $t0, cont ; if (temp2 != DQ7mask) goto cont */
- MIPS32_NOP, /* nop */
-
- MIPS32_SRL(10, 8, 2), /* srl $t2,$t0,2 ; temp1 = DQ7mask >> 2 */
- MIPS32_AND(11, 10, 11), /* and $t3, $t2, $t3 ; temp2 = temp2 & temp1 */
- MIPS32_BNE(11, 10, NEG16(8)), /* bne $t3, $t2, busy ; if (temp2 != temp1) goto busy */
- MIPS32_NOP, /* nop */
-
- MIPS32_LHU(10, 0, 5), /* lhu $t2, ($a1) ; temp1 = *daddr */
- MIPS32_XOR(11, 9, 10), /* xor $t3, $a0, $t2 ; temp2 = out ^ temp1; */
- MIPS32_AND(11, 8, 11), /* and $t3, $t0, $t3 ; temp2 = temp2 & DQ7mask */
- MIPS32_BNE(11, 8, 4), /* bne $t3, $t0, cont ; if (temp2 != DQ7mask) goto cont */
+ MIPS32_LHU(0, 10, 0, 5), /* lhu $t2, ($a1) ; temp1 = *daddr */
+ MIPS32_XOR(0, 11, 9, 10), /* xor $t3, $a0, $t2 ; temp2 = out ^ temp1; */
+ MIPS32_AND(0, 11, 8, 11), /* and $t3, $t0, $t3 ; temp2 = temp2 & DQ7mask */
+ MIPS32_BNE(0, 11, 8, 13), /* bne $t3, $t0, cont ; if (temp2 != DQ7mask) goto cont */
+ MIPS32_NOP, /* nop */
+
+ MIPS32_SRL(0, 10, 8, 2), /* srl $t2,$t0,2 ; temp1 = DQ7mask >> 2 */
+ MIPS32_AND(0, 11, 10, 11), /* and $t3, $t2, $t3 ; temp2 = temp2 & temp1 */
+ MIPS32_BNE(0, 11, 10, NEG16(8)), /* bne $t3, $t2, busy ; if (temp2 != temp1) goto busy */
+ MIPS32_NOP, /* nop */
+
+ MIPS32_LHU(0, 10, 0, 5), /* lhu $t2, ($a1) ; temp1 = *daddr */
+ MIPS32_XOR(0, 11, 9, 10), /* xor $t3, $a0, $t2 ; temp2 = out ^ temp1; */
+ MIPS32_AND(0, 11, 8, 11), /* and $t3, $t0, $t3 ; temp2 = temp2 & DQ7mask */
+ MIPS32_BNE(0, 11, 8, 4), /* bne $t3, $t0, cont ; if (temp2 != DQ7mask) goto cont */
MIPS32_NOP, /* nop */
- MIPS32_XOR(9, 9, 9), /* xor $t1, $t1, $t1 ; out = 0 */
- MIPS32_BEQ(9, 0, 11), /* beq $t1, $zero, done ; if (out == 0) goto done */
+ MIPS32_XOR(0, 9, 9, 9), /* xor $t1, $t1, $t1 ; out = 0 */
+ MIPS32_BEQ(0, 9, 0, 11), /* beq $t1, $zero, done ; if (out == 0) goto done */
MIPS32_NOP, /* nop */
/* cont: */
- MIPS32_ADDI(6, 6, NEG16(1)), /* addi, $a2, $a2, -1 ; numwrites-- */
- MIPS32_BNE(6, 0, 5), /* bne $a2, $zero, cont2 ; if (numwrite != 0) goto cont2 */
+ MIPS32_ADDI(0, 6, 6, NEG16(1)), /* addi, $a2, $a2, -1 ; numwrites-- */
+ MIPS32_BNE(0, 6, 0, 5), /* bne $a2, $zero, cont2 ; if (numwrite != 0) goto cont2 */
MIPS32_NOP, /* nop */
- MIPS32_LUI(9, 0), /* lui $t1, 0 */
- MIPS32_ORI(9, 9, 0x80), /* ori $t1, $t1, 0x80 ; out = 0x80 */
+ MIPS32_LUI(0, 9, 0), /* lui $t1, 0 */
+ MIPS32_ORI(0, 9, 9, 0x80), /* ori $t1, $t1, 0x80 ; out = 0x80 */
- MIPS32_B(4), /* b done ; goto done */
+ MIPS32_B(0, 4), /* b done ; goto done */
MIPS32_NOP, /* nop */
/* cont2: */
- MIPS32_ADDI(5, 5, 2), /* addi $a0, $a0, 2 ; daddr += 2 */
- MIPS32_B(NEG16(33)), /* b start ; goto start */
+ MIPS32_ADDI(0, 5, 5, 2), /* addi $a0, $a0, 2 ; daddr += 2 */
+ MIPS32_B(0, NEG16(33)), /* b start ; goto start */
MIPS32_NOP, /* nop */
/* done: */
- MIPS32_SDBBP, /* sdbbp ; break(); */
+ MIPS32_SDBBP(0), /* sdbbp ; break(); */
};
mips32_info.common_magic = MIPS32_COMMON_MAGIC;
@@ -1527,18 +1539,17 @@ static int cfi_spansion_write_block_mips(struct flash_bank *bank, const uint8_t
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
}
- ;
- init_reg_param(®_params[0], "a0", 32, PARAM_OUT);
- init_reg_param(®_params[1], "a1", 32, PARAM_OUT);
- init_reg_param(®_params[2], "a2", 32, PARAM_OUT);
- init_reg_param(®_params[3], "a3", 32, PARAM_OUT);
- init_reg_param(®_params[4], "t0", 32, PARAM_OUT);
- init_reg_param(®_params[5], "t1", 32, PARAM_IN);
- init_reg_param(®_params[6], "t4", 32, PARAM_OUT);
- init_reg_param(®_params[7], "t5", 32, PARAM_OUT);
- init_reg_param(®_params[8], "t6", 32, PARAM_OUT);
- init_reg_param(®_params[9], "t7", 32, PARAM_OUT);
+ init_reg_param(®_params[0], "r4", 32, PARAM_OUT);
+ init_reg_param(®_params[1], "r5", 32, PARAM_OUT);
+ init_reg_param(®_params[2], "r6", 32, PARAM_OUT);
+ init_reg_param(®_params[3], "r7", 32, PARAM_OUT);
+ init_reg_param(®_params[4], "r8", 32, PARAM_OUT);
+ init_reg_param(®_params[5], "r9", 32, PARAM_IN);
+ init_reg_param(®_params[6], "r12", 32, PARAM_OUT);
+ init_reg_param(®_params[7], "r13", 32, PARAM_OUT);
+ init_reg_param(®_params[8], "r14", 32, PARAM_OUT);
+ init_reg_param(®_params[9], "r15", 32, PARAM_OUT);
while (count > 0) {
uint32_t thisrun_count = (count > buffer_size) ? buffer_size : count;
@@ -1907,7 +1918,6 @@ static int cfi_spansion_write_block(struct flash_bank *bank, const uint8_t *buff
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
}
- ;
init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
@@ -1989,7 +1999,9 @@ static int cfi_intel_write_word(struct flash_bank *bank, uint8_t *word, uint32_t
uint8_t status;
retval = cfi_intel_wait_status_busy(bank, cfi_info->word_write_timeout, &status);
- if (retval != 0x80) {
+ if (retval != ERROR_OK)
+ return retval;
+ if (status != 0x80) {
retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0));
if (retval != ERROR_OK)
return retval;
@@ -2322,6 +2334,8 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of
int blk_count; /* number of bus_width bytes for block copy */
uint8_t current_word[CFI_MAX_BUS_WIDTH * 4]; /* word (bus_width size) currently being
*programmed */
+ uint8_t *swapped_buffer = NULL;
+ const uint8_t *real_buffer = NULL;
int i;
int retval;
@@ -2348,8 +2362,14 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of
return retval;
/* replace only bytes that must be written */
- for (i = align; (i < bank->bus_width) && (count > 0); i++, count--)
- current_word[i] = *buffer++;
+ for (i = align;
+ (i < bank->bus_width) && (count > 0);
+ i++, count--)
+ if (cfi_info->data_swap)
+ /* data bytes are swapped (reverse endianness) */
+ current_word[bank->bus_width - i] = *buffer++;
+ else
+ current_word[i] = *buffer++;
retval = cfi_write_word(bank, current_word, write_p);
if (retval != ERROR_OK)
@@ -2357,6 +2377,22 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of
write_p += bank->bus_width;
}
+ if (cfi_info->data_swap && count) {
+ swapped_buffer = malloc(count & ~(bank->bus_width - 1));
+ switch (bank->bus_width) {
+ case 2:
+ buf_bswap16(swapped_buffer, buffer,
+ count & ~(bank->bus_width - 1));
+ break;
+ case 4:
+ buf_bswap32(swapped_buffer, buffer,
+ count & ~(bank->bus_width - 1));
+ break;
+ }
+ real_buffer = buffer;
+ buffer = swapped_buffer;
+ }
+
/* handle blocks of bus_size aligned bytes */
blk_count = count & ~(bank->bus_width - 1); /* round down, leave tail bytes */
switch (cfi_info->pri_id) {
@@ -2426,6 +2462,11 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of
return retval;
}
+ if (swapped_buffer) {
+ buffer = real_buffer + (buffer - swapped_buffer);
+ free(swapped_buffer);
+ }
+
/* return to read array mode, so we can read from flash again for padding */
retval = cfi_reset(bank);
if (retval != ERROR_OK)
@@ -2442,7 +2483,11 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of
/* replace only bytes that must be written */
for (i = 0; (i < bank->bus_width) && (count > 0); i++, count--)
- current_word[i] = *buffer++;
+ if (cfi_info->data_swap)
+ /* data bytes are swapped (reverse endianness) */
+ current_word[bank->bus_width - i] = *buffer++;
+ else
+ current_word[i] = *buffer++;
retval = cfi_write_word(bank, current_word, write_p);
if (retval != ERROR_OK)
diff --git a/src/flash/nor/cfi.h b/src/flash/nor/cfi.h
index d92fcc0b1..ed858a9de 100644
--- a/src/flash/nor/cfi.h
+++ b/src/flash/nor/cfi.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef CFI_H
-#define CFI_H
+#ifndef OPENOCD_FLASH_NOR_CFI_H
+#define OPENOCD_FLASH_NOR_CFI_H
#define CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7 0xE0 /* DQ5..DQ7 */
#define CFI_STATUS_POLL_MASK_DQ6_DQ7 0xC0 /* DQ6..DQ7 */
@@ -30,6 +28,9 @@ struct cfi_flash_bank {
int not_cfi;
int probed;
+ enum target_endianness endianness;
+ int data_swap;
+
uint16_t manufacturer;
uint16_t device_id;
@@ -159,4 +160,4 @@ struct cfi_fixup {
#define CFI_MFR_ANY 0xffff
#define CFI_ID_ANY 0xffff
-#endif /* CFI_H */
+#endif /* OPENOCD_FLASH_NOR_CFI_H */
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
index 4410d5c6a..ab69a328b 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -52,10 +50,17 @@ int flash_driver_erase(struct flash_bank *bank, int first, int last)
int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
{
int retval;
+ int num_blocks;
+
+ if (bank->num_prot_blocks)
+ num_blocks = bank->num_prot_blocks;
+ else
+ num_blocks = bank->num_sectors;
+
/* callers may not supply illegal parameters ... */
- if (first < 0 || first > last || last >= bank->num_sectors) {
- LOG_ERROR("illegal sector range");
+ if (first < 0 || first > last || last >= num_blocks) {
+ LOG_ERROR("illegal protection block range");
return ERROR_FAIL;
}
@@ -71,11 +76,11 @@ int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
* the target could have reset, power cycled, been hot plugged,
* the application could have run, etc.
*
- * Drivers only receive valid sector range.
+ * Drivers only receive valid protection block range.
*/
retval = bank->driver->protect(bank, set, first, last);
if (retval != ERROR_OK)
- LOG_ERROR("failed setting protection for areas %d to %d", first, last);
+ LOG_ERROR("failed setting protection for blocks %d to %d", first, last);
return retval;
}
@@ -290,7 +295,7 @@ static int default_flash_mem_blank_check(struct flash_bank *bank)
goto done;
for (nBytes = 0; nBytes < chunk; nBytes++) {
- if (buffer[nBytes] != 0xFF) {
+ if (buffer[nBytes] != bank->erased_value) {
bank->sectors[i].is_erased = 0;
break;
}
@@ -321,12 +326,12 @@ int default_flash_blank_check(struct flash_bank *bank)
uint32_t address = bank->base + bank->sectors[i].offset;
uint32_t size = bank->sectors[i].size;
- retval = target_blank_check_memory(target, address, size, &blank);
+ retval = target_blank_check_memory(target, address, size, &blank, bank->erased_value);
if (retval != ERROR_OK) {
fast_check = 0;
break;
}
- if (blank == 0xFF)
+ if (blank == bank->erased_value)
bank->sectors[i].is_erased = 1;
else
bank->sectors[i].is_erased = 0;
@@ -345,8 +350,9 @@ int default_flash_blank_check(struct flash_bank *bank)
* and address. Maps an address range to a set of sectors, and issues
* the callback() on that set ... e.g. to erase or unprotect its members.
*
- * (Note a current bad assumption: that protection operates on the same
- * size sectors as erase operations use.)
+ * Parameter iterate_protect_blocks switches iteration of protect block
+ * instead of erase sectors. If there is no protect blocks array, sectors
+ * are used in iteration, so compatibility for old flash drivers is retained.
*
* The "pad_reason" parameter is a kind of boolean: when it's NULL, the
* range must fit those sectors exactly. This is clearly safe; it can't
@@ -357,13 +363,16 @@ int default_flash_blank_check(struct flash_bank *bank)
*/
static int flash_iterate_address_range_inner(struct target *target,
char *pad_reason, uint32_t addr, uint32_t length,
+ bool iterate_protect_blocks,
int (*callback)(struct flash_bank *bank, int first, int last))
{
struct flash_bank *c;
+ struct flash_sector *block_array;
uint32_t last_addr = addr + length; /* first address AFTER end */
int first = -1;
int last = -1;
int i;
+ int num_blocks;
int retval = get_flash_bank_by_addr(target, addr, true, &c);
if (retval != ERROR_OK)
@@ -390,13 +399,21 @@ static int flash_iterate_address_range_inner(struct target *target,
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
}
- /** @todo: handle erasures that cross into adjacent banks */
-
addr -= c->base;
last_addr -= c->base;
- for (i = 0; i < c->num_sectors; i++) {
- struct flash_sector *f = c->sectors + i;
+ if (iterate_protect_blocks && c->prot_blocks && c->num_prot_blocks) {
+ block_array = c->prot_blocks;
+ num_blocks = c->num_prot_blocks;
+ } else {
+ block_array = c->sectors;
+ num_blocks = c->num_sectors;
+ iterate_protect_blocks = false;
+ }
+
+
+ for (i = 0; i < num_blocks; i++) {
+ struct flash_sector *f = &block_array[i];
uint32_t end = f->offset + f->size;
/* start only on a sector boundary */
@@ -474,6 +491,7 @@ static int flash_iterate_address_range_inner(struct target *target,
*/
static int flash_iterate_address_range(struct target *target,
char *pad_reason, uint32_t addr, uint32_t length,
+ bool iterate_protect_blocks,
int (*callback)(struct flash_bank *bank, int first, int last))
{
struct flash_bank *c;
@@ -493,6 +511,7 @@ static int flash_iterate_address_range(struct target *target,
}
retval = flash_iterate_address_range_inner(target,
pad_reason, addr, cur_length,
+ iterate_protect_blocks,
callback);
if (retval != ERROR_OK)
break;
@@ -508,7 +527,7 @@ int flash_erase_address_range(struct target *target,
bool pad, uint32_t addr, uint32_t length)
{
return flash_iterate_address_range(target, pad ? "erase" : NULL,
- addr, length, &flash_driver_erase);
+ addr, length, false, &flash_driver_erase);
}
static int flash_driver_unprotect(struct flash_bank *bank, int first, int last)
@@ -523,7 +542,7 @@ int flash_unlock_address_range(struct target *target, uint32_t addr, uint32_t le
* and doesn't restore it.
*/
return flash_iterate_address_range(target, "unprotect",
- addr, length, &flash_driver_unprotect);
+ addr, length, true, &flash_driver_unprotect);
}
static int compare_section(const void *a, const void *b)
@@ -764,3 +783,22 @@ int flash_write(struct target *target, struct image *image,
{
return flash_write_unlock(target, image, written, erase, false);
}
+
+struct flash_sector *alloc_block_array(uint32_t offset, uint32_t size, int num_blocks)
+{
+ int i;
+
+ struct flash_sector *array = calloc(num_blocks, sizeof(struct flash_sector));
+ if (array == NULL)
+ return NULL;
+
+ for (i = 0; i < num_blocks; i++) {
+ array[i].offset = offset;
+ array[i].size = size;
+ array[i].is_erased = -1;
+ array[i].is_protected = -1;
+ offset += size;
+ }
+
+ return array;
+}
diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h
index 726dd957e..338363e2a 100644
--- a/src/flash/nor/core.h
+++ b/src/flash/nor/core.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef FLASH_NOR_CORE_H
-#define FLASH_NOR_CORE_H
+#ifndef OPENOCD_FLASH_NOR_CORE_H
+#define OPENOCD_FLASH_NOR_CORE_H
#include
@@ -48,6 +46,8 @@ struct flash_sector {
/**
* Indication of erasure status: 0 = not erased, 1 = erased,
* other = unknown. Set by @c flash_driver_s::erase_check.
+ *
+ * Flag is not used in protection block
*/
int is_erased;
/**
@@ -58,6 +58,9 @@ struct flash_sector {
* This information must be considered stale immediately.
* A million things could make it stale: power cycle,
* reset of target, code running on target, etc.
+ *
+ * If a flash_bank uses an extra array of protection blocks,
+ * protection flag is not valid in sector array
*/
int is_protected;
};
@@ -87,6 +90,9 @@ struct flash_bank {
int chip_width; /**< Width of the chip in bytes (1,2,4 bytes) */
int bus_width; /**< Maximum bus width, in bytes (1,2,4 bytes) */
+ /** Erased value. Defaults to 0xFF. */
+ uint8_t erased_value;
+
/** Default padded value used, normally this matches the flash
* erased value. Defaults to 0xFF. */
uint8_t default_padded_value;
@@ -97,9 +103,19 @@ struct flash_bank {
* some non-zero value during "probe()" or "auto_probe()".
*/
int num_sectors;
- /** Array of sectors, allocated and initilized by the flash driver */
+ /** Array of sectors, allocated and initialized by the flash driver */
struct flash_sector *sectors;
+ /**
+ * The number of protection blocks in this bank. This value
+ * is set intially to 0 and sectors are used as protection blocks.
+ * Driver probe can set protection blocks array to work with
+ * protection granularity different than sector size.
+ */
+ int num_prot_blocks;
+ /** Array of protection blocks, allocated and initilized by the flash driver */
+ struct flash_sector *prot_blocks;
+
struct flash_bank *next; /**< The next flash bank on this chip */
};
@@ -207,5 +223,13 @@ struct flash_bank *get_flash_bank_by_num_noprobe(int num);
*/
int get_flash_bank_by_addr(struct target *target, uint32_t addr, bool check,
struct flash_bank **result_bank);
+/**
+ * Allocate and fill an array of sectors or protection blocks.
+ * @param offset Offset of first block.
+ * @param size Size of each block.
+ * @param num_blocks Number of blocks in array.
+ * @returns A struct flash_sector pointer or NULL when allocation failed.
+ */
+struct flash_sector *alloc_block_array(uint32_t offset, uint32_t size, int num_blocks);
-#endif /* FLASH_NOR_CORE_H */
+#endif /* OPENOCD_FLASH_NOR_CORE_H */
diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h
index 8f2e1cc23..0ae4d8e20 100644
--- a/src/flash/nor/driver.h
+++ b/src/flash/nor/driver.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef FLASH_NOR_DRIVER_H
-#define FLASH_NOR_DRIVER_H
+#ifndef OPENOCD_FLASH_NOR_DRIVER_H
+#define OPENOCD_FLASH_NOR_DRIVER_H
struct flash_bank;
@@ -223,4 +221,4 @@ struct flash_driver {
*/
struct flash_driver *flash_driver_find_by_name(const char *name);
-#endif /* FLASH_NOR_DRIVER_H */
+#endif /* OPENOCD_FLASH_NOR_DRIVER_H */
diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c
index 48d584ee3..9702e591f 100644
--- a/src/flash/nor/drivers.c
+++ b/src/flash/nor/drivers.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -22,96 +20,112 @@
#endif
#include "imp.h"
-extern struct flash_driver lpc2000_flash;
-extern struct flash_driver lpc288x_flash;
-extern struct flash_driver lpc2900_flash;
-extern struct flash_driver lpcspifi_flash;
-extern struct flash_driver cfi_flash;
+extern struct flash_driver aduc702x_flash;
+extern struct flash_driver aducm360_flash;
+extern struct flash_driver ambiqmicro_flash;
extern struct flash_driver at91sam3_flash;
extern struct flash_driver at91sam4_flash;
extern struct flash_driver at91sam4l_flash;
-extern struct flash_driver at91samd_flash;
extern struct flash_driver at91sam7_flash;
+extern struct flash_driver at91samd_flash;
+extern struct flash_driver ath79_flash;
extern struct flash_driver atsamv_flash;
-extern struct flash_driver str7x_flash;
-extern struct flash_driver str9x_flash;
-extern struct flash_driver aduc702x_flash;
-extern struct flash_driver aducm360_flash;
-extern struct flash_driver stellaris_flash;
-extern struct flash_driver str9xpec_flash;
-extern struct flash_driver stm32f1x_flash;
-extern struct flash_driver stm32f2x_flash;
-extern struct flash_driver stm32lx_flash;
-extern struct flash_driver stm32l4x_flash;
-extern struct flash_driver tms470_flash;
-extern struct flash_driver ocl_flash;
-extern struct flash_driver pic32mx_flash;
extern struct flash_driver avr_flash;
-extern struct flash_driver faux_flash;
-extern struct flash_driver virtual_flash;
-extern struct flash_driver stmsmi_flash;
-extern struct flash_driver em357_flash;
+extern struct flash_driver cfi_flash;
extern struct flash_driver dsp5680xx_flash;
+extern struct flash_driver efm32_flash;
+extern struct flash_driver em357_flash;
+extern struct flash_driver faux_flash;
extern struct flash_driver fm3_flash;
+extern struct flash_driver fm4_flash;
+#if BUILD_RISCV == 1
+extern struct flash_driver fespi_flash;
+#endif
+extern struct flash_driver jtagspi_flash;
extern struct flash_driver kinetis_flash;
-extern struct flash_driver efm32_flash;
+extern struct flash_driver kinetis_ke_flash;
+extern struct flash_driver lpc2000_flash;
+extern struct flash_driver lpc288x_flash;
+extern struct flash_driver lpc2900_flash;
+extern struct flash_driver lpcspifi_flash;
extern struct flash_driver mdr_flash;
-extern struct flash_driver numicro_flash;
-extern struct flash_driver nrf51_flash;
extern struct flash_driver mrvlqspi_flash;
+extern struct flash_driver niietcm4_flash;
+extern struct flash_driver nrf51_flash;
+extern struct flash_driver numicro_flash;
+extern struct flash_driver ocl_flash;
+extern struct flash_driver pic32mx_flash;
extern struct flash_driver psoc4_flash;
extern struct flash_driver sim3x_flash;
-extern struct flash_driver jtagspi_flash;
+extern struct flash_driver stellaris_flash;
+extern struct flash_driver stm32f1x_flash;
+extern struct flash_driver stm32f2x_flash;
+extern struct flash_driver stm32lx_flash;
+extern struct flash_driver stm32l4x_flash;
+extern struct flash_driver stmsmi_flash;
+extern struct flash_driver str7x_flash;
+extern struct flash_driver str9x_flash;
+extern struct flash_driver str9xpec_flash;
+extern struct flash_driver tms470_flash;
+extern struct flash_driver virtual_flash;
+extern struct flash_driver xmc1xxx_flash;
extern struct flash_driver xmc4xxx_flash;
-extern struct flash_driver niietcm4_flash;
/**
* The list of built-in flash drivers.
* @todo Make this dynamically extendable with loadable modules.
*/
static struct flash_driver *flash_drivers[] = {
- &lpc2000_flash,
- &lpc288x_flash,
- &lpc2900_flash,
- &lpcspifi_flash,
- &cfi_flash,
- &at91sam7_flash,
+ &aduc702x_flash,
+ &aducm360_flash,
+ &ambiqmicro_flash,
&at91sam3_flash,
&at91sam4_flash,
&at91sam4l_flash,
+ &at91sam7_flash,
&at91samd_flash,
+ &ath79_flash,
&atsamv_flash,
- &str7x_flash,
- &str9x_flash,
- &aduc702x_flash,
- &aducm360_flash,
- &stellaris_flash,
- &str9xpec_flash,
- &stm32f1x_flash,
- &stm32f2x_flash,
- &stm32lx_flash,
- &stm32l4x_flash,
- &tms470_flash,
- &ocl_flash,
- &pic32mx_flash,
&avr_flash,
- &faux_flash,
- &virtual_flash,
- &stmsmi_flash,
+ &cfi_flash,
+ &dsp5680xx_flash,
+ &efm32_flash,
&em357_flash,
+ &faux_flash,
&fm3_flash,
- &dsp5680xx_flash,
+ &fm4_flash,
+#if BUILD_RISCV == 1
+ &fespi_flash,
+#endif
+ &jtagspi_flash,
&kinetis_flash,
- &efm32_flash,
+ &kinetis_ke_flash,
+ &lpc2000_flash,
+ &lpc288x_flash,
+ &lpc2900_flash,
+ &lpcspifi_flash,
&mdr_flash,
- &numicro_flash,
- &nrf51_flash,
&mrvlqspi_flash,
+ &niietcm4_flash,
+ &nrf51_flash,
+ &numicro_flash,
+ &ocl_flash,
+ &pic32mx_flash,
&psoc4_flash,
&sim3x_flash,
- &jtagspi_flash,
+ &stellaris_flash,
+ &stm32f1x_flash,
+ &stm32f2x_flash,
+ &stm32lx_flash,
+ &stm32l4x_flash,
+ &stmsmi_flash,
+ &str7x_flash,
+ &str9x_flash,
+ &str9xpec_flash,
+ &tms470_flash,
+ &virtual_flash,
+ &xmc1xxx_flash,
&xmc4xxx_flash,
- &niietcm4_flash,
NULL,
};
diff --git a/src/flash/nor/dsp5680xx_flash.c b/src/flash/nor/dsp5680xx_flash.c
index 693ff487e..38649ff04 100644
--- a/src/flash/nor/dsp5680xx_flash.c
+++ b/src/flash/nor/dsp5680xx_flash.c
@@ -18,9 +18,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/**
diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c
index d268bea46..81c1a379c 100644
--- a/src/flash/nor/efm32.c
+++ b/src/flash/nor/efm32.c
@@ -25,9 +25,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -146,11 +144,11 @@ static int efm32x_read_info(struct flash_bank *bank,
return ret;
if (((cpuid >> 4) & 0xfff) == 0xc23) {
- /* Cortex M3 device */
+ /* Cortex-M3 device */
} else if (((cpuid >> 4) & 0xfff) == 0xc24) {
- /* Cortex M4 device(WONDER GECKO) */
+ /* Cortex-M4 device (WONDER GECKO) */
} else if (((cpuid >> 4) & 0xfff) == 0xc60) {
- /* Cortex M0plus device */
+ /* Cortex-M0+ device */
} else {
LOG_ERROR("Target is not Cortex-Mx Device");
return ERROR_FAIL;
@@ -458,10 +456,10 @@ static int efm32x_read_lock_data(struct flash_bank *bank)
uint32_t *ptr = NULL;
int ret = 0;
- assert(!(bank->num_sectors & 0x1f));
+ assert(bank->num_sectors > 0);
- data_size = bank->num_sectors / 8; /* number of data bytes */
- data_size /= 4; /* ...and data dwords */
+ /* calculate the number of 32-bit words to read (one lock bit per sector) */
+ data_size = (bank->num_sectors + 31) / 32;
ptr = efm32x_info->lb_page;
@@ -668,7 +666,7 @@ static int efm32x_write_block(struct flash_bank *bank, const uint8_t *buf,
&write_algorithm) != ERROR_OK) {
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
ret = target_write_buffer(target, write_algorithm->address,
sizeof(efm32x_flash_write_code), efm32x_flash_write_code);
@@ -687,7 +685,7 @@ static int efm32x_write_block(struct flash_bank *bank, const uint8_t *buf,
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- };
+ }
init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* count (word-32bit) */
@@ -997,7 +995,50 @@ static int get_efm32x_info(struct flash_bank *bank, char *buf, int buf_size)
return efm32x_decode_info(&info, buf, buf_size);
}
+COMMAND_HANDLER(efm32x_handle_debuglock_command)
+{
+ struct target *target = NULL;
+
+ if (CMD_ARGC < 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct flash_bank *bank;
+ int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
+
+ target = bank->target;
+
+ if (target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ uint32_t *ptr;
+ ptr = efm32x_info->lb_page + 127;
+ *ptr = 0;
+
+ retval = efm32x_write_lock_data(bank);
+ if (ERROR_OK != retval) {
+ LOG_ERROR("Failed to write LB page");
+ return retval;
+ }
+
+ command_print(CMD_CTX, "efm32x debug interface locked, reset the device to apply");
+
+ return ERROR_OK;
+}
+
static const struct command_registration efm32x_exec_command_handlers[] = {
+ {
+ .name = "debuglock",
+ .handler = efm32x_handle_debuglock_command,
+ .mode = COMMAND_EXEC,
+ .usage = "bank_id",
+ .help = "Lock the debug interface of the device.",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/flash/nor/em357.c b/src/flash/nor/em357.c
index 70a5431ac..a11743b55 100644
--- a/src/flash/nor/em357.c
+++ b/src/flash/nor/em357.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -502,7 +500,6 @@ static int em357_write_block(struct flash_bank *bank, const uint8_t *buffer,
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- ;
retval = target_write_buffer(target, write_algorithm->address,
sizeof(em357_flash_write_code), em357_flash_write_code);
@@ -705,6 +702,11 @@ static int em357_probe(struct flash_bank *bank)
num_pages = 128;
page_size = 2048;
break;
+ case 0x80000:
+ /* 512k -- 256 2k pages */
+ num_pages = 256;
+ page_size = 2048;
+ break;
default:
LOG_WARNING("No size specified for em357 flash driver, assuming 192k!");
num_pages = 96;
diff --git a/src/flash/nor/faux.c b/src/flash/nor/faux.c
index 1fd1da216..203eb6fff 100644
--- a/src/flash/nor/faux.c
+++ b/src/flash/nor/faux.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -50,7 +48,7 @@ FLASH_BANK_COMMAND_HANDLER(faux_flash_bank_command)
return ERROR_FAIL;
}
info->memory = malloc(bank->size);
- if (info == NULL) {
+ if (info->memory == NULL) {
free(info);
LOG_ERROR("no memory for flash bank info");
return ERROR_FAIL;
diff --git a/src/flash/nor/fm3.c b/src/flash/nor/fm3.c
index d3d143f60..6269a6536 100644
--- a/src/flash/nor/fm3.c
+++ b/src/flash/nor/fm3.c
@@ -17,9 +17,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/imp.h b/src/flash/nor/imp.h
index 31d098408..87475a39c 100644
--- a/src/flash/nor/imp.h
+++ b/src/flash/nor/imp.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef FLASH_NOR_IMP_H
-#define FLASH_NOR_IMP_H
+#ifndef OPENOCD_FLASH_NOR_IMP_H
+#define OPENOCD_FLASH_NOR_IMP_H
/* this is an internal header */
#include "core.h"
@@ -48,4 +46,4 @@ int flash_driver_read(struct flash_bank *bank,
int flash_write_unlock(struct target *target, struct image *image,
uint32_t *written, int erase, bool unlock);
-#endif /* FLASH_NOR_IMP_H */
+#endif /* OPENOCD_FLASH_NOR_IMP_H */
diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c
index 1e623a71b..a995fc756 100644
--- a/src/flash/nor/jtagspi.c
+++ b/src/flash/nor/jtagspi.c
@@ -11,6 +11,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -208,14 +210,14 @@ static void jtagspi_read_status(struct flash_bank *bank, uint32_t *status)
static int jtagspi_wait(struct flash_bank *bank, int timeout_ms)
{
uint32_t status;
- long long t0 = timeval_ms();
- long long dt;
+ int64_t t0 = timeval_ms();
+ int64_t dt;
do {
dt = timeval_ms() - t0;
jtagspi_read_status(bank, &status);
if ((status & SPIFLASH_BSY_BIT) == 0) {
- LOG_DEBUG("waited %lld ms", dt);
+ LOG_DEBUG("waited %" PRId64 " ms", dt);
return ERROR_OK;
}
alive_sleep(1);
@@ -242,14 +244,14 @@ static int jtagspi_bulk_erase(struct flash_bank *bank)
{
struct jtagspi_flash_bank *info = bank->driver_priv;
int retval;
- long long t0 = timeval_ms();
+ int64_t t0 = timeval_ms();
retval = jtagspi_write_enable(bank);
if (retval != ERROR_OK)
return retval;
jtagspi_cmd(bank, info->dev->chip_erase_cmd, NULL, NULL, 0);
retval = jtagspi_wait(bank, bank->num_sectors*JTAGSPI_MAX_TIMEOUT);
- LOG_INFO("took %lld ms", timeval_ms() - t0);
+ LOG_INFO("took %" PRId64 " ms", timeval_ms() - t0);
return retval;
}
@@ -257,14 +259,14 @@ static int jtagspi_sector_erase(struct flash_bank *bank, int sector)
{
struct jtagspi_flash_bank *info = bank->driver_priv;
int retval;
- long long t0 = timeval_ms();
+ int64_t t0 = timeval_ms();
retval = jtagspi_write_enable(bank);
if (retval != ERROR_OK)
return retval;
jtagspi_cmd(bank, info->dev->erase_cmd, &bank->sectors[sector].offset, NULL, 0);
retval = jtagspi_wait(bank, JTAGSPI_MAX_TIMEOUT);
- LOG_INFO("sector %d took %lld ms", sector, timeval_ms() - t0);
+ LOG_INFO("sector %d took %" PRId64 " ms", sector, timeval_ms() - t0);
return retval;
}
diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c
index d618cfdd2..7e9bbdef4 100644
--- a/src/flash/nor/kinetis.c
+++ b/src/flash/nor/kinetis.c
@@ -11,6 +11,9 @@
* Copyright (C) 2013 Nemui Trinomius *
* nemuisan_kawausogasuki@live.jp *
* *
+ * 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 *
@@ -22,9 +25,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -34,6 +35,7 @@
#include "jtag/interface.h"
#include "imp.h"
#include
+#include
#include
#include
#include
@@ -78,16 +80,34 @@
*/
/* Addressess */
+#define FCF_ADDRESS 0x00000400
+#define FCF_FPROT 0x8
+#define FCF_FSEC 0xc
+#define FCF_FOPT 0xd
+#define FCF_FDPROT 0xf
+#define FCF_SIZE 0x10
+
#define FLEXRAM 0x14000000
+
+#define FMC_PFB01CR 0x4001f004
#define FTFx_FSTAT 0x40020000
#define FTFx_FCNFG 0x40020001
#define FTFx_FCCOB3 0x40020004
#define FTFx_FPROT3 0x40020010
+#define FTFx_FDPROT 0x40020017
#define SIM_SDID 0x40048024
#define SIM_SOPT1 0x40047000
#define SIM_FCFG1 0x4004804c
#define SIM_FCFG2 0x40048050
#define WDOG_STCTRH 0x40052000
+#define SMC_PMCTRL 0x4007E001
+#define SMC_PMSTAT 0x4007E003
+#define MCM_PLACR 0xF000300C
+
+/* Values */
+#define PM_STAT_RUN 0x01
+#define PM_STAT_VLPR 0x04
+#define PM_CTRL_RUNM_RUN 0x00
/* Commands */
#define FTFx_CMD_BLOCKSTAT 0x00
@@ -95,8 +115,9 @@
#define FTFx_CMD_LWORDPROG 0x06
#define FTFx_CMD_SECTERASE 0x09
#define FTFx_CMD_SECTWRITE 0x0b
-#define FTFx_CMD_SETFLEXRAM 0x81
#define FTFx_CMD_MASSERASE 0x44
+#define FTFx_CMD_PGMPART 0x80
+#define FTFx_CMD_SETFLEXRAM 0x81
/* The older Kinetis K series uses the following SDID layout :
* Bit 31-16 : 0
@@ -186,12 +207,16 @@
#define KINETIS_SDID_FAMILYID_K4X 0x40000000
#define KINETIS_SDID_FAMILYID_K6X 0x60000000
#define KINETIS_SDID_FAMILYID_K7X 0x70000000
+#define KINETIS_SDID_FAMILYID_K8X 0x80000000
struct kinetis_flash_bank {
- unsigned bank_ordinal;
+ bool probed;
uint32_t sector_size;
uint32_t max_flash_prog_size;
uint32_t protection_size;
+ uint32_t prog_base; /* base address for FTFx operations */
+ /* same as bank->base for pflash, differs for FlexNVM */
+ uint32_t protection_block; /* number of first protection block in this bank */
uint32_t sim_sdid;
uint32_t sim_fcfg1;
@@ -208,9 +233,13 @@ struct kinetis_flash_bank {
FS_PROGRAM_SECTOR = 1,
FS_PROGRAM_LONGWORD = 2,
FS_PROGRAM_PHRASE = 4, /* Unsupported */
+ FS_INVALIDATE_CACHE_K = 8,
+ FS_INVALIDATE_CACHE_L = 0x10,
} flash_support;
};
+#define MDM_AP 1
+
#define MDM_REG_STAT 0x00
#define MDM_REG_CTRL 0x04
#define MDM_REG_ID 0xfc
@@ -229,23 +258,34 @@ struct kinetis_flash_bank {
#define MDM_STAT_CORE_SLEEPDEEP (1<<17)
#define MDM_STAT_CORESLEEPING (1<<18)
-#define MEM_CTRL_FMEIP (1<<0)
-#define MEM_CTRL_DBG_DIS (1<<1)
-#define MEM_CTRL_DBG_REQ (1<<2)
-#define MEM_CTRL_SYS_RES_REQ (1<<3)
-#define MEM_CTRL_CORE_HOLD_RES (1<<4)
-#define MEM_CTRL_VLLSX_DBG_REQ (1<<5)
-#define MEM_CTRL_VLLSX_DBG_ACK (1<<6)
-#define MEM_CTRL_VLLSX_STAT_ACK (1<<7)
+#define MDM_CTRL_FMEIP (1<<0)
+#define MDM_CTRL_DBG_DIS (1<<1)
+#define MDM_CTRL_DBG_REQ (1<<2)
+#define MDM_CTRL_SYS_RES_REQ (1<<3)
+#define MDM_CTRL_CORE_HOLD_RES (1<<4)
+#define MDM_CTRL_VLLSX_DBG_REQ (1<<5)
+#define MDM_CTRL_VLLSX_DBG_ACK (1<<6)
+#define MDM_CTRL_VLLSX_STAT_ACK (1<<7)
+
+#define MDM_ACCESS_TIMEOUT 500 /* msec */
+
+
+static bool allow_fcf_writes;
+static uint8_t fcf_fopt = 0xff;
+
+
+struct flash_driver kinetis_flash;
+static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,
+ uint32_t offset, uint32_t count);
+static int kinetis_auto_probe(struct flash_bank *bank);
-#define MDM_ACCESS_TIMEOUT 3000 /* iterations */
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, 1), reg, value);
+ retval = dap_queue_ap_write(dap_ap(dap, MDM_AP), reg, value);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a write request");
return retval;
@@ -265,7 +305,7 @@ static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32
{
int retval;
- retval = dap_queue_ap_read(dap_ap(dap, 1), reg, result);
+ retval = dap_queue_ap_read(dap_ap(dap, MDM_AP), reg, result);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a read request");
return retval;
@@ -281,11 +321,12 @@ static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32
return ERROR_OK;
}
-static int kinetis_mdm_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value)
+static int kinetis_mdm_poll_register(struct adiv5_dap *dap, unsigned reg,
+ uint32_t mask, uint32_t value, uint32_t timeout_ms)
{
uint32_t val;
int retval;
- int timeout = MDM_ACCESS_TIMEOUT;
+ int64_t ms_timeout = timeval_ms() + timeout_ms;
do {
retval = kinetis_mdm_read_register(dap, reg, &val);
@@ -293,17 +334,121 @@ static int kinetis_mdm_poll_register(struct adiv5_dap *dap, unsigned reg, uint32
return retval;
alive_sleep(1);
- } while (timeout--);
+ } while (timeval_ms() < ms_timeout);
LOG_DEBUG("MDM: polling timed out");
return ERROR_FAIL;
}
+/*
+ * This command can be used to break a watchdog reset loop when
+ * connecting to an unsecured target. Unlike other commands, halt will
+ * automatically retry as it does not know how far into the boot process
+ * it is when the command is called.
+ */
+COMMAND_HANDLER(kinetis_mdm_halt)
+{
+ 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;
+ int retval;
+ int tries = 0;
+ uint32_t stat;
+ int64_t ms_timeout = timeval_ms() + MDM_ACCESS_TIMEOUT;
+
+ if (!dap) {
+ LOG_ERROR("Cannot perform halt with a high-level adapter");
+ return ERROR_FAIL;
+ }
+
+ while (true) {
+ tries++;
+
+ kinetis_mdm_write_register(dap, MDM_REG_CTRL, MDM_CTRL_CORE_HOLD_RES);
+
+ alive_sleep(1);
+
+ retval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &stat);
+ if (retval != ERROR_OK) {
+ LOG_DEBUG("MDM: failed to read MDM_REG_STAT");
+ continue;
+ }
+
+ /* Repeat setting MDM_CTRL_CORE_HOLD_RES until system is out of
+ * reset with flash ready and without security
+ */
+ if ((stat & (MDM_STAT_FREADY | MDM_STAT_SYSSEC | MDM_STAT_SYSRES))
+ == (MDM_STAT_FREADY | MDM_STAT_SYSRES))
+ break;
+
+ if (timeval_ms() >= ms_timeout) {
+ LOG_ERROR("MDM: halt timed out");
+ return ERROR_FAIL;
+ }
+ }
+
+ LOG_DEBUG("MDM: halt succeded after %d attempts.", tries);
+
+ target_poll(target);
+ /* enable polling in case kinetis_check_flash_security_status disabled it */
+ jtag_poll_set_enabled(true);
+
+ alive_sleep(100);
+
+ target->reset_halt = true;
+ target->type->assert_reset(target);
+
+ retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, 0);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("MDM: failed to clear MDM_REG_CTRL");
+ return retval;
+ }
+
+ target->type->deassert_reset(target);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(kinetis_mdm_reset)
+{
+ 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;
+ int retval;
+
+ if (!dap) {
+ LOG_ERROR("Cannot perform reset with a high-level adapter");
+ return ERROR_FAIL;
+ }
+
+ retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, MDM_CTRL_SYS_RES_REQ);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("MDM: failed to write MDM_REG_CTRL");
+ return retval;
+ }
+
+ retval = kinetis_mdm_poll_register(dap, MDM_REG_STAT, MDM_STAT_SYSRES, 0, 500);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("MDM: failed to assert reset");
+ return retval;
+ }
+
+ retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, 0);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("MDM: failed to clear MDM_REG_CTRL");
+ return retval;
+ }
+
+ return ERROR_OK;
+}
+
/*
* This function implements the procedure to mass erase the flash via
* SWD/JTAG on Kinetis K and L series of devices as it is described in
* AN4835 "Production Flash Programming Best Practices for Kinetis K-
- * and L-series MCUs" Section 4.2.1
+ * and L-series MCUs" Section 4.2.1. To prevent a watchdog reset loop,
+ * the core remains halted after this function completes as suggested
+ * by the application note.
*/
COMMAND_HANDLER(kinetis_mdm_mass_erase)
{
@@ -326,70 +471,123 @@ COMMAND_HANDLER(kinetis_mdm_mass_erase)
* establishing communication...
*/
- /* assert SRST */
- if (jtag_get_reset_config() & RESET_HAS_SRST)
+ /* assert SRST if configured */
+ bool has_srst = jtag_get_reset_config() & RESET_HAS_SRST;
+ if (has_srst)
adapter_assert_reset();
- else
- LOG_WARNING("Attempting mass erase without hardware reset. This is not reliable; "
- "it's recommended you connect SRST and use ``reset_config srst_only''.");
- retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, MEM_CTRL_SYS_RES_REQ);
- if (retval != ERROR_OK)
- return retval;
+ retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, MDM_CTRL_SYS_RES_REQ);
+ if (retval != ERROR_OK && !has_srst) {
+ LOG_ERROR("MDM: failed to assert reset");
+ goto deassert_reset_and_exit;
+ }
/*
- * ... Read the MDM-AP status register until the Flash Ready bit sets...
+ * ... Read the MDM-AP status register repeatedly and wait for
+ * stable conditions suitable for mass erase:
+ * - mass erase is enabled
+ * - flash is ready
+ * - reset is finished
+ *
+ * Mass erase is started as soon as all conditions are met in 32
+ * subsequent status reads.
+ *
+ * In case of not stable conditions (RESET/WDOG loop in secured device)
+ * the user is asked for manual pressing of RESET button
+ * as a last resort.
*/
- retval = kinetis_mdm_poll_register(dap, MDM_REG_STAT,
- MDM_STAT_FREADY | MDM_STAT_SYSRES,
- MDM_STAT_FREADY);
- if (retval != ERROR_OK) {
- LOG_ERROR("MDM : flash ready timeout");
- return retval;
- }
+ int cnt_mass_erase_disabled = 0;
+ int cnt_ready = 0;
+ int64_t ms_start = timeval_ms();
+ bool man_reset_requested = false;
+
+ do {
+ uint32_t stat = 0;
+ int64_t ms_elapsed = timeval_ms() - ms_start;
+
+ if (!man_reset_requested && ms_elapsed > 100) {
+ LOG_INFO("MDM: Press RESET button now if possible.");
+ man_reset_requested = true;
+ }
+
+ if (ms_elapsed > 3000) {
+ LOG_ERROR("MDM: waiting for mass erase conditions timed out.");
+ LOG_INFO("Mass erase of a secured MCU is not possible without hardware reset.");
+ LOG_INFO("Connect SRST, use 'reset_config srst_only' and retry.");
+ goto deassert_reset_and_exit;
+ }
+ retval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &stat);
+ if (retval != ERROR_OK) {
+ cnt_ready = 0;
+ continue;
+ }
+
+ if (!(stat & MDM_STAT_FMEEN)) {
+ cnt_ready = 0;
+ cnt_mass_erase_disabled++;
+ if (cnt_mass_erase_disabled > 10) {
+ LOG_ERROR("MDM: mass erase is disabled");
+ goto deassert_reset_and_exit;
+ }
+ continue;
+ }
+
+ if ((stat & (MDM_STAT_FREADY | MDM_STAT_SYSRES)) == MDM_STAT_FREADY)
+ cnt_ready++;
+ else
+ cnt_ready = 0;
+
+ } while (cnt_ready < 32);
/*
* ... Write the MDM-AP control register to set the Flash Mass
* Erase in Progress bit. This will start the mass erase
* process...
*/
- retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL,
- MEM_CTRL_SYS_RES_REQ | MEM_CTRL_FMEIP);
- if (retval != ERROR_OK)
- return retval;
-
- /* As a sanity check make sure that device started mass erase procedure */
- retval = kinetis_mdm_poll_register(dap, MDM_REG_STAT,
- MDM_STAT_FMEACK, MDM_STAT_FMEACK);
- if (retval != ERROR_OK)
- return retval;
+ retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, MDM_CTRL_SYS_RES_REQ | MDM_CTRL_FMEIP);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("MDM: failed to start mass erase");
+ goto deassert_reset_and_exit;
+ }
/*
* ... Read the MDM-AP control register until the Flash Mass
* Erase in Progress bit clears...
+ * Data sheed defines erase time <3.6 sec/512kB flash block.
+ * The biggest device has 4 pflash blocks => timeout 16 sec.
*/
- retval = kinetis_mdm_poll_register(dap, MDM_REG_CTRL,
- MEM_CTRL_FMEIP,
- 0);
- if (retval != ERROR_OK)
- return retval;
+ retval = kinetis_mdm_poll_register(dap, MDM_REG_CTRL, MDM_CTRL_FMEIP, 0, 16000);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("MDM: mass erase timeout");
+ goto deassert_reset_and_exit;
+ }
+
+ target_poll(target);
+ /* enable polling in case kinetis_check_flash_security_status disabled it */
+ jtag_poll_set_enabled(true);
+
+ alive_sleep(100);
+
+ target->reset_halt = true;
+ target->type->assert_reset(target);
/*
* ... Negate the RESET signal or clear the System Reset Request
- * bit in the MDM-AP control register...
+ * bit in the MDM-AP control register.
*/
retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, 0);
if (retval != ERROR_OK)
- return retval;
+ LOG_ERROR("MDM: failed to clear MDM_REG_CTRL");
- if (jtag_get_reset_config() & RESET_HAS_SRST) {
- /* halt MCU otherwise it loops in hard fault - WDOG reset cycle */
- target->reset_halt = true;
- target->type->assert_reset(target);
- target->type->deassert_reset(target);
- }
+ target->type->deassert_reset(target);
- return ERROR_OK;
+ return retval;
+
+deassert_reset_and_exit:
+ kinetis_mdm_write_register(dap, MDM_REG_CTRL, 0);
+ if (has_srst)
+ adapter_deassert_reset();
+ return retval;
}
static const uint32_t kinetis_known_mdm_ids[] = {
@@ -414,6 +612,9 @@ COMMAND_HANDLER(kinetis_check_flash_security_status)
return ERROR_OK;
}
+ if (!dap->ops)
+ return ERROR_OK; /* too early to check, in JTAG mode ops may not be initialised */
+
uint32_t val;
int retval;
@@ -424,9 +625,12 @@ COMMAND_HANDLER(kinetis_check_flash_security_status)
retval = kinetis_mdm_read_register(dap, MDM_REG_ID, &val);
if (retval != ERROR_OK) {
LOG_ERROR("MDM: failed to read ID register");
- goto fail;
+ return ERROR_OK;
}
+ if (val == 0)
+ return ERROR_OK; /* dap not yet initialised */
+
bool found = false;
for (size_t i = 0; i < ARRAY_SIZE(kinetis_known_mdm_ids); i++) {
if (val == kinetis_known_mdm_ids[i]) {
@@ -438,17 +642,6 @@ COMMAND_HANDLER(kinetis_check_flash_security_status)
if (!found)
LOG_WARNING("MDM: unknown ID %08" PRIX32, val);
- /*
- * ... Read the MDM-AP status register until the Flash Ready bit sets...
- */
- retval = kinetis_mdm_poll_register(dap, MDM_REG_STAT,
- MDM_STAT_FREADY,
- MDM_STAT_FREADY);
- if (retval != ERROR_OK) {
- LOG_ERROR("MDM: flash ready timeout");
- goto fail;
- }
-
/*
* ... Read the System Security bit to determine if security is enabled.
* If System Security = 0, then proceed. If System Security = 1, then
@@ -459,33 +652,40 @@ COMMAND_HANDLER(kinetis_check_flash_security_status)
retval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &val);
if (retval != ERROR_OK) {
LOG_ERROR("MDM: failed to read MDM_REG_STAT");
- goto fail;
+ return ERROR_OK;
}
- if ((val & (MDM_STAT_SYSSEC | MDM_STAT_CORE_HALTED)) == MDM_STAT_SYSSEC) {
- LOG_WARNING("MDM: Secured MCU state detected however it may be a false alarm");
- LOG_WARNING("MDM: Halting target to detect secured state reliably");
+ /*
+ * System Security bit is also active for short time during reset.
+ * If a MCU has blank flash and runs in RESET/WDOG loop,
+ * System Security bit is active most of time!
+ * We should observe Flash Ready bit and read status several times
+ * to avoid false detection of secured MCU
+ */
+ int secured_score = 0, flash_not_ready_score = 0;
- retval = target_halt(target);
- if (retval == ERROR_OK)
- retval = target_wait_state(target, TARGET_HALTED, 100);
+ if ((val & (MDM_STAT_SYSSEC | MDM_STAT_FREADY)) != MDM_STAT_FREADY) {
+ uint32_t stats[32];
+ int i;
- if (retval != ERROR_OK) {
- LOG_WARNING("MDM: Target not halted, trying reset halt");
- target->reset_halt = true;
- target->type->assert_reset(target);
- target->type->deassert_reset(target);
+ for (i = 0; i < 32; i++) {
+ stats[i] = MDM_STAT_FREADY;
+ dap_queue_ap_read(dap_ap(dap, MDM_AP), MDM_REG_STAT, &stats[i]);
}
-
- /* re-read status */
- retval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &val);
+ retval = dap_run(dap);
if (retval != ERROR_OK) {
- LOG_ERROR("MDM: failed to read MDM_REG_STAT");
- goto fail;
+ LOG_DEBUG("MDM: dap_run failed when validating secured state");
+ return ERROR_OK;
+ }
+ for (i = 0; i < 32; i++) {
+ if (stats[i] & MDM_STAT_SYSSEC)
+ secured_score++;
+ if (!(stats[i] & MDM_STAT_FREADY))
+ flash_not_ready_score++;
}
}
- if (val & MDM_STAT_SYSSEC) {
+ if (flash_not_ready_score <= 8 && secured_score > 24) {
jtag_poll_set_enabled(false);
LOG_WARNING("*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********");
@@ -497,17 +697,22 @@ COMMAND_HANDLER(kinetis_check_flash_security_status)
LOG_WARNING("**** command, power cycle the MCU and restart OpenOCD. ****");
LOG_WARNING("**** ****");
LOG_WARNING("*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********");
+
+ } else if (flash_not_ready_score > 24) {
+ jtag_poll_set_enabled(false);
+ LOG_WARNING("**** Your Kinetis MCU is probably locked-up in RESET/WDOG loop. ****");
+ LOG_WARNING("**** Common reason is a blank flash (at least a reset vector). ****");
+ LOG_WARNING("**** Issue 'kinetis mdm halt' command or if SRST is connected ****");
+ LOG_WARNING("**** and configured, use 'reset halt' ****");
+ LOG_WARNING("**** If MCU cannot be halted, it is likely secured and running ****");
+ LOG_WARNING("**** in RESET/WDOG loop. Issue 'kinetis mdm mass_erase' ****");
+
} else {
LOG_INFO("MDM: Chip is unsecured. Continuing.");
jtag_poll_set_enabled(true);
}
return ERROR_OK;
-
-fail:
- LOG_ERROR("MDM: Failed to check security status of the MCU. Cannot proceed further");
- jtag_poll_set_enabled(false);
- return retval;
}
FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
@@ -537,30 +742,11 @@ int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
int retval;
static const uint8_t kinetis_unlock_wdog_code[] = {
- /* WDOG_UNLOCK = 0xC520 */
- 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */
- 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */
- 0x4c, 0xf2, 0x20, 0x52, /* movw r2, #50464 ; 0xc520 */
- 0xda, 0x81, /* strh r2, [r3, #14] */
-
- /* WDOG_UNLOCK = 0xD928 */
- 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */
- 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */
- 0x4d, 0xf6, 0x28, 0x12, /* movw r2, #55592 ; 0xd928 */
- 0xda, 0x81, /* strh r2, [r3, #14] */
-
- /* WDOG_SCR = 0x1d2 */
- 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */
- 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */
- 0x4f, 0xf4, 0xe9, 0x72, /* mov.w r2, #466 ; 0x1d2 */
- 0x1a, 0x80, /* strh r2, [r3, #0] */
-
- /* END */
- 0x00, 0xBE, /* bkpt #0 */
+#include "../../../contrib/loaders/watchdog/armv7m_kinetis_wdog.inc"
};
/* Decide whether the connected device needs watchdog disabling.
- * Disable for all Kx devices, i.e., return if it is a KLx */
+ * Disable for all Kx and KVx devices, return if it is a KLx */
if ((sim_sdid & KINETIS_SDID_SERIESID_MASK) == KINETIS_SDID_SERIESID_KL)
return ERROR_OK;
@@ -632,67 +818,57 @@ COMMAND_HANDLER(kinetis_disable_wdog_handler)
}
+static int kinetis_ftfx_decode_error(uint8_t fstat)
+{
+ if (fstat & 0x20) {
+ LOG_ERROR("Flash operation failed, illegal command");
+ return ERROR_FLASH_OPER_UNSUPPORTED;
+
+ } else if (fstat & 0x10)
+ LOG_ERROR("Flash operation failed, protection violated");
+
+ else if (fstat & 0x40)
+ LOG_ERROR("Flash operation failed, read collision");
+
+ else if (fstat & 0x80)
+ return ERROR_OK;
+
+ else
+ LOG_ERROR("Flash operation timed out");
+
+ return ERROR_FLASH_OPERATION_FAILED;
+}
+
+
+static int kinetis_ftfx_prepare(struct target *target)
+{
+ int result, i;
+ uint8_t fstat;
+
+ /* wait until busy */
+ for (i = 0; i < 50; i++) {
+ result = target_read_u8(target, FTFx_FSTAT, &fstat);
+ if (result != ERROR_OK)
+ return result;
+
+ if (fstat & 0x80)
+ break;
+ }
+
+ if ((fstat & 0x80) == 0) {
+ LOG_ERROR("Flash controller is busy");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ if (fstat != 0x80) {
+ /* reset error flags */
+ result = target_write_u8(target, FTFx_FSTAT, 0x70);
+ }
+ return result;
+}
+
/* Kinetis Program-LongWord Microcodes */
static const uint8_t kinetis_flash_write_code[] = {
- /* Params:
- * r0 - workarea buffer
- * r1 - target address
- * r2 - wordcount
- * Clobbered:
- * r4 - tmp
- * r5 - tmp
- * r6 - tmp
- * r7 - tmp
- */
-
- /* .L1: */
- /* for(register uint32_t i=0;ibase + offset;
- struct reg_param reg_params[3];
+ struct kinetis_flash_bank *kinfo = bank->driver_priv;
+ uint32_t address = kinfo->prog_base + offset;
+ uint32_t end_address;
+ struct reg_param reg_params[5];
struct armv7m_algorithm armv7m_info;
- int retval = ERROR_OK;
-
- /* Params:
- * r0 - workarea buffer
- * r1 - target address
- * r2 - wordcount
- * Clobbered:
- * r4 - tmp
- * r5 - tmp
- * r6 - tmp
- * r7 - tmp
- */
+ int retval;
+ uint8_t fstat;
/* Increase buffer_size if needed */
if (buffer_size < (target->working_area_size/2))
buffer_size = (target->working_area_size/2);
- LOG_INFO("Kinetis: FLASH Write ...");
-
- /* check code alignment */
- if (offset & 0x1) {
- LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
- return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
- }
-
/* allocate working area with flash programming code */
if (target_alloc_working_area(target, sizeof(kinetis_flash_write_code),
&write_algorithm) != ERROR_OK) {
@@ -758,35 +918,39 @@ static int kinetis_write_block(struct flash_bank *bank, const uint8_t *buffer,
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
armv7m_info.core_mode = ARM_MODE_THREAD;
- init_reg_param(®_params[0], "r0", 32, PARAM_OUT); /* *pLW (*buffer) */
- init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* faddr */
- init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* number of words to program */
+ init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* address */
+ init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* word count */
+ init_reg_param(®_params[2], "r2", 32, PARAM_OUT);
+ init_reg_param(®_params[3], "r3", 32, PARAM_OUT);
+ init_reg_param(®_params[4], "r4", 32, PARAM_OUT);
- /* write code buffer and use Flash programming code within kinetis */
- /* Set breakpoint to 0 with time-out of 1000 ms */
- while (wcount > 0) {
- uint32_t thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount;
+ buf_set_u32(reg_params[0].value, 0, 32, address);
+ buf_set_u32(reg_params[1].value, 0, 32, wcount);
+ buf_set_u32(reg_params[2].value, 0, 32, source->address);
+ buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
+ buf_set_u32(reg_params[4].value, 0, 32, FTFx_FSTAT);
- retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer);
- if (retval != ERROR_OK)
- break;
+ retval = target_run_flash_async_algorithm(target, buffer, wcount, 4,
+ 0, NULL,
+ 5, reg_params,
+ source->address, source->size,
+ write_algorithm->address, 0,
+ &armv7m_info);
- buf_set_u32(reg_params[0].value, 0, 32, source->address);
- buf_set_u32(reg_params[1].value, 0, 32, address);
- buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
+ if (retval == ERROR_FLASH_OPERATION_FAILED) {
+ end_address = buf_get_u32(reg_params[0].value, 0, 32);
- retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
- write_algorithm->address, 0, 100000, &armv7m_info);
- if (retval != ERROR_OK) {
- LOG_ERROR("Error executing kinetis Flash programming algorithm");
- retval = ERROR_FLASH_OPERATION_FAILED;
- break;
- }
+ LOG_ERROR("Error writing flash at %08" PRIx32, end_address);
- buffer += thisrun_count * 4;
- address += thisrun_count * 4;
- wcount -= thisrun_count;
- }
+ retval = target_read_u8(target, FTFx_FSTAT, &fstat);
+ if (retval == ERROR_OK) {
+ retval = kinetis_ftfx_decode_error(fstat);
+
+ /* reset error flags */
+ target_write_u8(target, FTFx_FSTAT, 0x70);
+ }
+ } else if (retval != ERROR_OK)
+ LOG_ERROR("Error executing kinetis Flash programming algorithm");
target_free_working_area(target, source);
target_free_working_area(target, write_algorithm);
@@ -794,74 +958,137 @@ static int kinetis_write_block(struct flash_bank *bank, const uint8_t *buffer,
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
destroy_reg_param(®_params[2]);
+ destroy_reg_param(®_params[3]);
+ destroy_reg_param(®_params[4]);
return retval;
}
static int kinetis_protect(struct flash_bank *bank, int set, int first, int last)
{
- LOG_WARNING("kinetis_protect not supported yet");
- /* FIXME: TODO */
+ int i;
- if (bank->target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
+ if (allow_fcf_writes) {
+ LOG_ERROR("Protection setting is possible with 'kinetis fcf_source protection' only!");
+ return ERROR_FAIL;
+ }
+
+ if (!bank->prot_blocks || bank->num_prot_blocks == 0) {
+ LOG_ERROR("No protection possible for current bank!");
+ return ERROR_FLASH_BANK_INVALID;
}
- return ERROR_FLASH_BANK_INVALID;
+ for (i = first; i < bank->num_prot_blocks && i <= last; i++)
+ bank->prot_blocks[i].is_protected = set;
+
+ LOG_INFO("Protection bits will be written at the next FCF sector erase or write.");
+ LOG_INFO("Do not issue 'flash info' command until protection is written,");
+ LOG_INFO("doing so would re-read protection status from MCU.");
+
+ return ERROR_OK;
}
static int kinetis_protect_check(struct flash_bank *bank)
{
struct kinetis_flash_bank *kinfo = bank->driver_priv;
-
- if (bank->target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
+ int result;
+ int i, b;
+ uint32_t fprot;
if (kinfo->flash_class == FC_PFLASH) {
- int result;
- uint8_t buffer[4];
- uint32_t fprot, psec;
- int i, b;
/* read protection register */
- result = target_read_memory(bank->target, FTFx_FPROT3, 1, 4, buffer);
+ result = target_read_u32(bank->target, FTFx_FPROT3, &fprot);
+ if (result != ERROR_OK)
+ return result;
+
+ /* Every bit protects 1/32 of the full flash (not necessarily just this bank) */
+
+ } else if (kinfo->flash_class == FC_FLEX_NVM) {
+ uint8_t fdprot;
+ /* read protection register */
+ result = target_read_u8(bank->target, FTFx_FDPROT, &fdprot);
if (result != ERROR_OK)
return result;
- fprot = target_buffer_get_u32(bank->target, buffer);
+ fprot = fdprot;
- /*
- * Every bit protects 1/32 of the full flash (not necessarily
- * just this bank), but we enforce the bank ordinals for
- * PFlash to start at zero.
- */
- b = kinfo->bank_ordinal * (bank->size / kinfo->protection_size);
- for (psec = 0, i = 0; i < bank->num_sectors; i++) {
- if ((fprot >> b) & 1)
- bank->sectors[i].is_protected = 0;
- else
- bank->sectors[i].is_protected = 1;
+ } else {
+ LOG_ERROR("Protection checks for FlexRAM not supported");
+ return ERROR_FLASH_BANK_INVALID;
+ }
+
+ b = kinfo->protection_block;
+ for (i = 0; i < bank->num_prot_blocks; i++) {
+ if ((fprot >> b) & 1)
+ bank->prot_blocks[i].is_protected = 0;
+ else
+ bank->prot_blocks[i].is_protected = 1;
+
+ b++;
+ }
+
+ return ERROR_OK;
+}
+
+
+static int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf)
+{
+ uint32_t fprot = 0xffffffff;
+ uint8_t fsec = 0xfe; /* set MCU unsecure */
+ uint8_t fdprot = 0xff;
+ int i;
+ uint32_t pflash_bit;
+ uint8_t dflash_bit;
+ struct flash_bank *bank_iter;
+ struct kinetis_flash_bank *kinfo;
+
+ memset(fcf, 0xff, FCF_SIZE);
+
+ pflash_bit = 1;
+ dflash_bit = 1;
+
+ /* iterate over all kinetis banks */
+ /* current bank is bank 0, it contains FCF */
+ for (bank_iter = bank; bank_iter; bank_iter = bank_iter->next) {
+ if (bank_iter->driver != &kinetis_flash
+ || bank_iter->target != bank->target)
+ continue;
+
+ kinetis_auto_probe(bank_iter);
+
+ kinfo = bank->driver_priv;
+ if (!kinfo)
+ continue;
+
+ if (kinfo->flash_class == FC_PFLASH) {
+ for (i = 0; i < bank_iter->num_prot_blocks; i++) {
+ if (bank_iter->prot_blocks[i].is_protected == 1)
+ fprot &= ~pflash_bit;
+
+ pflash_bit <<= 1;
+ }
- psec += bank->sectors[i].size;
+ } else if (kinfo->flash_class == FC_FLEX_NVM) {
+ for (i = 0; i < bank_iter->num_prot_blocks; i++) {
+ if (bank_iter->prot_blocks[i].is_protected == 1)
+ fdprot &= ~dflash_bit;
- if (psec >= kinfo->protection_size) {
- psec = 0;
- b++;
+ dflash_bit <<= 1;
}
+
}
- } else {
- LOG_ERROR("Protection checks for FlexNVM not yet supported");
- return ERROR_FLASH_BANK_INVALID;
}
+ target_buffer_set_u32(bank->target, fcf + FCF_FPROT, fprot);
+ fcf[FCF_FSEC] = fsec;
+ fcf[FCF_FOPT] = fcf_fopt;
+ fcf[FCF_FDPROT] = fdprot;
return ERROR_OK;
}
-static int kinetis_ftfx_command(struct flash_bank *bank, uint8_t fcmd, uint32_t faddr,
+static int kinetis_ftfx_command(struct target *target, uint8_t fcmd, uint32_t faddr,
uint8_t fccob4, uint8_t fccob5, uint8_t fccob6, uint8_t fccob7,
uint8_t fccob8, uint8_t fccob9, uint8_t fccoba, uint8_t fccobb,
uint8_t *ftfx_fstat)
@@ -869,98 +1096,116 @@ static int kinetis_ftfx_command(struct flash_bank *bank, uint8_t fcmd, uint32_t
uint8_t command[12] = {faddr & 0xff, (faddr >> 8) & 0xff, (faddr >> 16) & 0xff, fcmd,
fccob7, fccob6, fccob5, fccob4,
fccobb, fccoba, fccob9, fccob8};
- int result, i;
- uint8_t buffer;
-
- /* wait for done */
- for (i = 0; i < 50; i++) {
- result =
- target_read_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
-
- if (result != ERROR_OK)
- return result;
-
- if (buffer & 0x80)
- break;
-
- buffer = 0x00;
- }
-
- if (buffer != 0x80) {
- /* reset error flags */
- buffer = 0x30;
- result =
- target_write_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
- if (result != ERROR_OK)
- return result;
- }
-
- result = target_write_memory(bank->target, FTFx_FCCOB3, 4, 3, command);
+ int result;
+ uint8_t fstat;
+ int64_t ms_timeout = timeval_ms() + 250;
+ result = target_write_memory(target, FTFx_FCCOB3, 4, 3, command);
if (result != ERROR_OK)
return result;
/* start command */
- buffer = 0x80;
- result = target_write_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
+ result = target_write_u8(target, FTFx_FSTAT, 0x80);
if (result != ERROR_OK)
return result;
/* wait for done */
- for (i = 0; i < 240; i++) { /* Need longtime for "Mass Erase" Command Nemui Changed */
- result =
- target_read_memory(bank->target, FTFx_FSTAT, 1, 1, ftfx_fstat);
+ do {
+ result = target_read_u8(target, FTFx_FSTAT, &fstat);
if (result != ERROR_OK)
return result;
- if (*ftfx_fstat & 0x80)
+ if (fstat & 0x80)
break;
- }
- if ((*ftfx_fstat & 0xf0) != 0x80) {
- LOG_ERROR
- ("ftfx command failed FSTAT: %02X FCCOB: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X",
- *ftfx_fstat, command[3], command[2], command[1], command[0],
+ } while (timeval_ms() < ms_timeout);
+
+ if (ftfx_fstat)
+ *ftfx_fstat = fstat;
+
+ if ((fstat & 0xf0) != 0x80) {
+ LOG_DEBUG("ftfx command failed FSTAT: %02X FCCOB: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X",
+ fstat, command[3], command[2], command[1], command[0],
command[7], command[6], command[5], command[4],
command[11], command[10], command[9], command[8]);
- return ERROR_FLASH_OPERATION_FAILED;
+
+ return kinetis_ftfx_decode_error(fstat);
}
return ERROR_OK;
}
-COMMAND_HANDLER(kinetis_securing_test)
-{
- int result;
- uint8_t ftfx_fstat;
- struct target *target = get_current_target(CMD_CTX);
- struct flash_bank *bank = NULL;
-
- result = get_flash_bank_by_addr(target, 0x00000000, true, &bank);
- if (result != ERROR_OK)
- return result;
- assert(bank != NULL);
+static int kinetis_check_run_mode(struct target *target)
+{
+ int result, i;
+ uint8_t pmctrl, pmstat;
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
- return kinetis_ftfx_command(bank, FTFx_CMD_SECTERASE, bank->base + 0x00000400,
- 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
-}
+ result = target_read_u8(target, SMC_PMSTAT, &pmstat);
+ if (result != ERROR_OK)
+ return result;
-static int kinetis_erase(struct flash_bank *bank, int first, int last)
-{
- int result, i;
+ if (pmstat == PM_STAT_RUN)
+ return ERROR_OK;
- if (bank->target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
+ if (pmstat == PM_STAT_VLPR) {
+ /* It is safe to switch from VLPR to RUN mode without changing clock */
+ LOG_INFO("Switching from VLPR to RUN mode.");
+ pmctrl = PM_CTRL_RUNM_RUN;
+ result = target_write_u8(target, SMC_PMCTRL, pmctrl);
+ if (result != ERROR_OK)
+ return result;
+
+ for (i = 100; i; i--) {
+ result = target_read_u8(target, SMC_PMSTAT, &pmstat);
+ if (result != ERROR_OK)
+ return result;
+
+ if (pmstat == PM_STAT_RUN)
+ return ERROR_OK;
+ }
}
+ LOG_ERROR("Flash operation not possible in current run mode: SMC_PMSTAT: 0x%x", pmstat);
+ LOG_ERROR("Issue a 'reset init' command.");
+ return ERROR_TARGET_NOT_HALTED;
+}
+
+
+static void kinetis_invalidate_flash_cache(struct flash_bank *bank)
+{
+ struct kinetis_flash_bank *kinfo = bank->driver_priv;
+
+ if (kinfo->flash_support & FS_INVALIDATE_CACHE_K)
+ target_write_u8(bank->target, FMC_PFB01CR + 2, 0xf0);
+
+ else if (kinfo->flash_support & FS_INVALIDATE_CACHE_L)
+ target_write_u8(bank->target, MCM_PLACR + 1, 0x04);
+
+ return;
+}
+
+
+static int kinetis_erase(struct flash_bank *bank, int first, int last)
+{
+ int result, i;
+ struct kinetis_flash_bank *kinfo = bank->driver_priv;
+
+ result = kinetis_check_run_mode(bank->target);
+ if (result != ERROR_OK)
+ return result;
+
+ /* reset error flags */
+ result = kinetis_ftfx_prepare(bank->target);
+ if (result != ERROR_OK)
+ return result;
+
if ((first > bank->num_sectors) || (last > bank->num_sectors))
return ERROR_FLASH_OPERATION_FAILED;
@@ -970,10 +1215,9 @@ static int kinetis_erase(struct flash_bank *bank, int first, int last)
* block. Should be quicker.
*/
for (i = first; i <= last; i++) {
- uint8_t ftfx_fstat;
/* set command and sector address */
- result = kinetis_ftfx_command(bank, FTFx_CMD_SECTERASE, bank->base + bank->sectors[i].offset,
- 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
+ result = kinetis_ftfx_command(bank->target, FTFx_CMD_SECTERASE, kinfo->prog_base + bank->sectors[i].offset,
+ 0, 0, 0, 0, 0, 0, 0, 0, NULL);
if (result != ERROR_OK) {
LOG_WARNING("erase sector %d failed", i);
@@ -981,147 +1225,177 @@ static int kinetis_erase(struct flash_bank *bank, int first, int last)
}
bank->sectors[i].is_erased = 1;
- }
- if (first == 0) {
- LOG_WARNING
- ("flash configuration field erased, please reset the device");
+ if (bank->base == 0
+ && bank->sectors[i].offset <= FCF_ADDRESS
+ && bank->sectors[i].offset + bank->sectors[i].size > FCF_ADDRESS + FCF_SIZE) {
+ if (allow_fcf_writes) {
+ LOG_WARNING("Flash Configuration Field erased, DO NOT reset or power off the device");
+ LOG_WARNING("until correct FCF is programmed or MCU gets security lock.");
+ } else {
+ uint8_t fcf_buffer[FCF_SIZE];
+
+ kinetis_fill_fcf(bank, fcf_buffer);
+ result = kinetis_write_inner(bank, fcf_buffer, FCF_ADDRESS, FCF_SIZE);
+ if (result != ERROR_OK)
+ LOG_WARNING("Flash Configuration Field write failed");
+ bank->sectors[i].is_erased = 0;
+ }
+ }
}
+ kinetis_invalidate_flash_cache(bank);
+
return ERROR_OK;
}
-static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
- uint32_t offset, uint32_t count)
+static int kinetis_make_ram_ready(struct target *target)
{
- unsigned int i, result, fallback = 0;
- uint8_t buf[8];
- uint32_t wc;
- struct kinetis_flash_bank *kinfo = bank->driver_priv;
- uint8_t *new_buffer = NULL;
+ int result;
+ uint8_t ftfx_fcnfg;
- if (bank->target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
+ /* check if ram ready */
+ result = target_read_u8(target, FTFx_FCNFG, &ftfx_fcnfg);
+ if (result != ERROR_OK)
+ return result;
- if (!(kinfo->flash_support & FS_PROGRAM_SECTOR)) {
- /* fallback to longword write */
- fallback = 1;
- LOG_WARNING("This device supports Program Longword execution only.");
- LOG_DEBUG("flash write into PFLASH @08%" PRIX32, offset);
+ if (ftfx_fcnfg & (1 << 1))
+ return ERROR_OK; /* ram ready */
- } else if (kinfo->flash_class == FC_FLEX_NVM) {
+ /* make flex ram available */
+ result = kinetis_ftfx_command(target, FTFx_CMD_SETFLEXRAM, 0x00ff0000,
+ 0, 0, 0, 0, 0, 0, 0, 0, NULL);
+ if (result != ERROR_OK)
+ return ERROR_FLASH_OPERATION_FAILED;
+
+ /* check again */
+ result = target_read_u8(target, FTFx_FCNFG, &ftfx_fcnfg);
+ if (result != ERROR_OK)
+ return result;
+
+ if (ftfx_fcnfg & (1 << 1))
+ return ERROR_OK; /* ram ready */
+
+ return ERROR_FLASH_OPERATION_FAILED;
+}
+
+
+static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer,
+ uint32_t offset, uint32_t count)
+{
+ int result = ERROR_OK;
+ struct kinetis_flash_bank *kinfo = bank->driver_priv;
+ uint8_t *buffer_aligned = NULL;
+ /*
+ * Kinetis uses different terms for the granularity of
+ * sector writes, e.g. "phrase" or "128 bits". We use
+ * the generic term "chunk". The largest possible
+ * Kinetis "chunk" is 16 bytes (128 bits).
+ */
+ uint32_t prog_section_chunk_bytes = kinfo->sector_size >> 8;
+ uint32_t prog_size_bytes = kinfo->max_flash_prog_size;
+
+ while (count > 0) {
+ uint32_t size = prog_size_bytes - offset % prog_size_bytes;
+ uint32_t align_begin = offset % prog_section_chunk_bytes;
+ uint32_t align_end;
+ uint32_t size_aligned;
+ uint16_t chunk_count;
uint8_t ftfx_fstat;
- LOG_DEBUG("flash write into FlexNVM @%08" PRIX32, offset);
+ if (size > count)
+ size = count;
- /* make flex ram available */
- result = kinetis_ftfx_command(bank, FTFx_CMD_SETFLEXRAM, 0x00ff0000, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
+ align_end = (align_begin + size) % prog_section_chunk_bytes;
+ if (align_end)
+ align_end = prog_section_chunk_bytes - align_end;
- if (result != ERROR_OK)
- return ERROR_FLASH_OPERATION_FAILED;
+ size_aligned = align_begin + size + align_end;
+ chunk_count = size_aligned / prog_section_chunk_bytes;
- /* check if ram ready */
- result = target_read_memory(bank->target, FTFx_FCNFG, 1, 1, buf);
+ if (size != size_aligned) {
+ /* aligned section: the first, the last or the only */
+ if (!buffer_aligned)
+ buffer_aligned = malloc(prog_size_bytes);
- if (result != ERROR_OK)
- return result;
+ memset(buffer_aligned, 0xff, size_aligned);
+ memcpy(buffer_aligned + align_begin, buffer, size);
- if (!(buf[0] & (1 << 1))) {
- /* fallback to longword write */
- fallback = 1;
+ result = target_write_memory(bank->target, FLEXRAM,
+ 4, size_aligned / 4, buffer_aligned);
- LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)", buf[0]);
- }
- } else {
- LOG_DEBUG("flash write into PFLASH @08%" PRIX32, offset);
- }
+ LOG_DEBUG("section @ %08" PRIx32 " aligned begin %" PRIu32 ", end %" PRIu32,
+ bank->base + offset, align_begin, align_end);
+ } else
+ result = target_write_memory(bank->target, FLEXRAM,
+ 4, size_aligned / 4, buffer);
+ LOG_DEBUG("write section @ %08" PRIx32 " with length %" PRIu32 " bytes",
+ bank->base + offset, size);
- /* program section command */
- if (fallback == 0) {
- /*
- * Kinetis uses different terms for the granularity of
- * sector writes, e.g. "phrase" or "128 bits". We use
- * the generic term "chunk". The largest possible
- * Kinetis "chunk" is 16 bytes (128 bits).
- */
- unsigned prog_section_chunk_bytes = kinfo->sector_size >> 8;
- unsigned prog_size_bytes = kinfo->max_flash_prog_size;
- for (i = 0; i < count; i += prog_size_bytes) {
- uint8_t residual_buffer[16];
- uint8_t ftfx_fstat;
- uint32_t section_count = prog_size_bytes / prog_section_chunk_bytes;
- uint32_t residual_wc = 0;
-
- /*
- * Assume the word count covers an entire
- * sector.
- */
- wc = prog_size_bytes / 4;
-
- /*
- * If bytes to be programmed are less than the
- * full sector, then determine the number of
- * full-words to program, and put together the
- * residual buffer so that a full "section"
- * may always be programmed.
- */
- if ((count - i) < prog_size_bytes) {
- /* number of bytes to program beyond full section */
- unsigned residual_bc = (count-i) % prog_section_chunk_bytes;
-
- /* number of complete words to copy directly from buffer */
- wc = (count - i - residual_bc) / 4;
-
- /* number of total sections to write, including residual */
- section_count = DIV_ROUND_UP((count-i), prog_section_chunk_bytes);
-
- /* any residual bytes delivers a whole residual section */
- residual_wc = (residual_bc ? prog_section_chunk_bytes : 0)/4;
-
- /* clear residual buffer then populate residual bytes */
- (void) memset(residual_buffer, 0xff, prog_section_chunk_bytes);
- (void) memcpy(residual_buffer, &buffer[i+4*wc], residual_bc);
- }
+ if (result != ERROR_OK) {
+ LOG_ERROR("target_write_memory failed");
+ break;
+ }
- LOG_DEBUG("write section @ %08" PRIX32 " with length %" PRIu32 " bytes",
- offset + i, (uint32_t)wc*4);
+ /* execute section-write command */
+ result = kinetis_ftfx_command(bank->target, FTFx_CMD_SECTWRITE,
+ kinfo->prog_base + offset - align_begin,
+ chunk_count>>8, chunk_count, 0, 0,
+ 0, 0, 0, 0, &ftfx_fstat);
- /* write data to flexram as whole-words */
- result = target_write_memory(bank->target, FLEXRAM, 4, wc,
- buffer + i);
+ if (result != ERROR_OK) {
+ LOG_ERROR("Error writing section at %08" PRIx32, bank->base + offset);
+ break;
+ }
- if (result != ERROR_OK) {
- LOG_ERROR("target_write_memory failed");
- return result;
- }
+ if (ftfx_fstat & 0x01)
+ LOG_ERROR("Flash write error at %08" PRIx32, bank->base + offset);
- /* write the residual words to the flexram */
- if (residual_wc) {
- result = target_write_memory(bank->target,
- FLEXRAM+4*wc,
- 4, residual_wc,
- residual_buffer);
+ buffer += size;
+ offset += size;
+ count -= size;
+ }
- if (result != ERROR_OK) {
- LOG_ERROR("target_write_memory failed");
- return result;
- }
- }
+ free(buffer_aligned);
+ return result;
+}
- /* execute section-write command */
- result = kinetis_ftfx_command(bank, FTFx_CMD_SECTWRITE, bank->base + offset + i,
- section_count>>8, section_count, 0, 0,
- 0, 0, 0, 0, &ftfx_fstat);
- if (result != ERROR_OK)
- return ERROR_FLASH_OPERATION_FAILED;
+static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,
+ uint32_t offset, uint32_t count)
+{
+ int result, fallback = 0;
+ struct kinetis_flash_bank *kinfo = bank->driver_priv;
+
+ if (!(kinfo->flash_support & FS_PROGRAM_SECTOR)) {
+ /* fallback to longword write */
+ fallback = 1;
+ LOG_INFO("This device supports Program Longword execution only.");
+ } else {
+ result = kinetis_make_ram_ready(bank->target);
+ if (result != ERROR_OK) {
+ fallback = 1;
+ LOG_WARNING("FlexRAM not ready, fallback to slow longword write.");
}
}
- /* program longword command, not supported in "SF3" devices */
+
+ LOG_DEBUG("flash write @08%" PRIx32, bank->base + offset);
+
+ if (fallback == 0) {
+ /* program section command */
+ kinetis_write_sections(bank, buffer, offset, count);
+ }
else if (kinfo->flash_support & FS_PROGRAM_LONGWORD) {
+ /* program longword command, not supported in FTFE */
+ uint8_t *new_buffer = NULL;
+
+ /* check word alignment */
+ if (offset & 0x3) {
+ LOG_ERROR("offset 0x%" PRIx32 " breaks the required alignment", offset);
+ return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+ }
+
if (count & 0x3) {
uint32_t old_count = count;
count = (old_count | 3) + 1;
@@ -1133,7 +1407,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
}
LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " "
"and padding with 0xff", old_count, count);
- memset(new_buffer, 0xff, count);
+ memset(new_buffer + old_count, 0xff, count - old_count);
buffer = memcpy(new_buffer, buffer, old_count);
}
@@ -1142,49 +1416,125 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
kinetis_disable_wdog(bank->target, kinfo->sim_sdid);
/* try using a block write */
- int retval = kinetis_write_block(bank, buffer, offset, words_remaining);
+ result = kinetis_write_block(bank, buffer, offset, words_remaining);
- if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
+ if (result == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
/* if block write failed (no sufficient working area),
* we use normal (slow) single word accesses */
LOG_WARNING("couldn't use block writes, falling back to single "
"memory accesses");
- for (i = 0; i < count; i += 4) {
+ while (words_remaining) {
uint8_t ftfx_fstat;
- LOG_DEBUG("write longword @ %08" PRIX32, (uint32_t)(offset + i));
+ LOG_DEBUG("write longword @ %08" PRIx32, (uint32_t)(bank->base + offset));
- uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};
- memcpy(padding, buffer + i, MIN(4, count-i));
-
- result = kinetis_ftfx_command(bank, FTFx_CMD_LWORDPROG, bank->base + offset + i,
- padding[3], padding[2], padding[1], padding[0],
+ result = kinetis_ftfx_command(bank->target, FTFx_CMD_LWORDPROG, kinfo->prog_base + offset,
+ buffer[3], buffer[2], buffer[1], buffer[0],
0, 0, 0, 0, &ftfx_fstat);
- if (result != ERROR_OK)
- return ERROR_FLASH_OPERATION_FAILED;
+ if (result != ERROR_OK) {
+ LOG_ERROR("Error writing longword at %08" PRIx32, bank->base + offset);
+ break;
+ }
+
+ if (ftfx_fstat & 0x01)
+ LOG_ERROR("Flash write error at %08" PRIx32, bank->base + offset);
+
+ buffer += 4;
+ offset += 4;
+ words_remaining--;
}
}
+ free(new_buffer);
} else {
LOG_ERROR("Flash write strategy not implemented");
return ERROR_FLASH_OPERATION_FAILED;
}
- return ERROR_OK;
+ kinetis_invalidate_flash_cache(bank);
+ return result;
}
-static int kinetis_read_part_info(struct flash_bank *bank)
+
+static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
+ uint32_t offset, uint32_t count)
+{
+ int result;
+ bool set_fcf = false;
+ int sect = 0;
+
+ result = kinetis_check_run_mode(bank->target);
+ if (result != ERROR_OK)
+ return result;
+
+ /* reset error flags */
+ result = kinetis_ftfx_prepare(bank->target);
+ if (result != ERROR_OK)
+ return result;
+
+ if (bank->base == 0 && !allow_fcf_writes) {
+ if (bank->sectors[1].offset <= FCF_ADDRESS)
+ sect = 1; /* 1kb sector, FCF in 2nd sector */
+
+ if (offset < bank->sectors[sect].offset + bank->sectors[sect].size
+ && offset + count > bank->sectors[sect].offset)
+ set_fcf = true; /* write to any part of sector with FCF */
+ }
+
+ if (set_fcf) {
+ uint8_t fcf_buffer[FCF_SIZE];
+ uint8_t fcf_current[FCF_SIZE];
+
+ kinetis_fill_fcf(bank, fcf_buffer);
+
+ if (offset < FCF_ADDRESS) {
+ /* write part preceding FCF */
+ result = kinetis_write_inner(bank, buffer, offset, FCF_ADDRESS - offset);
+ if (result != ERROR_OK)
+ return result;
+ }
+
+ result = target_read_memory(bank->target, FCF_ADDRESS, 4, FCF_SIZE / 4, fcf_current);
+ if (result == ERROR_OK && memcmp(fcf_current, fcf_buffer, FCF_SIZE) == 0)
+ set_fcf = false;
+
+ if (set_fcf) {
+ /* write FCF if differs from flash - eliminate multiple writes */
+ result = kinetis_write_inner(bank, fcf_buffer, FCF_ADDRESS, FCF_SIZE);
+ if (result != ERROR_OK)
+ return result;
+ }
+
+ LOG_WARNING("Flash Configuration Field written.");
+ LOG_WARNING("Reset or power off the device to make settings effective.");
+
+ if (offset + count > FCF_ADDRESS + FCF_SIZE) {
+ uint32_t delta = FCF_ADDRESS + FCF_SIZE - offset;
+ /* write part after FCF */
+ result = kinetis_write_inner(bank, buffer + delta, FCF_ADDRESS + FCF_SIZE, count - delta);
+ }
+ return result;
+
+ } else
+ /* no FCF fiddling, normal write */
+ return kinetis_write_inner(bank, buffer, offset, count);
+}
+
+
+static int kinetis_probe(struct flash_bank *bank)
{
int result, i;
- uint32_t offset = 0;
- uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg2_pflsh;
- uint32_t nvm_size = 0, pf_size = 0, ee_size = 0;
+ uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg1_depart;
+ uint8_t fcfg2_maxaddr0, fcfg2_pflsh, fcfg2_maxaddr1;
+ uint32_t nvm_size = 0, pf_size = 0, df_size = 0, ee_size = 0;
unsigned num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0, first_nvm_bank = 0,
- reassign = 0, pflash_sector_size_bytes = 0, nvm_sector_size_bytes = 0;
+ pflash_sector_size_bytes = 0, nvm_sector_size_bytes = 0;
struct target *target = bank->target;
struct kinetis_flash_bank *kinfo = bank->driver_priv;
+ kinfo->probed = false;
+
result = target_read_u32(target, SIM_SDID, &kinfo->sim_sdid);
if (result != ERROR_OK)
return result;
@@ -1200,7 +1550,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
pflash_sector_size_bytes = 1<<10;
nvm_sector_size_bytes = 1<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_K_SDID_K10_M72:
case KINETIS_K_SDID_K20_M72:
@@ -1213,7 +1563,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
pflash_sector_size_bytes = 2<<10;
nvm_sector_size_bytes = 1<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
kinfo->max_flash_prog_size = 1<<10;
break;
case KINETIS_K_SDID_K10_M100:
@@ -1229,7 +1579,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
pflash_sector_size_bytes = 2<<10;
nvm_sector_size_bytes = 2<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_K_SDID_K21_M120:
case KINETIS_K_SDID_K22_M120:
@@ -1238,7 +1588,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
kinfo->max_flash_prog_size = 1<<10;
nvm_sector_size_bytes = 4<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_K_SDID_K10_M120:
case KINETIS_K_SDID_K20_M120:
@@ -1248,7 +1598,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
pflash_sector_size_bytes = 4<<10;
nvm_sector_size_bytes = 4<<10;
num_blocks = 4;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
default:
LOG_ERROR("Unsupported K-family FAMID");
@@ -1262,7 +1612,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
/* K02FN64, K02FN128: FTFA, 2kB sectors */
pflash_sector_size_bytes = 2<<10;
num_blocks = 1;
- kinfo->flash_support = FS_PROGRAM_LONGWORD;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX2: {
@@ -1277,7 +1627,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
/* MK24FN1M */
pflash_sector_size_bytes = 4<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
kinfo->max_flash_prog_size = 1<<10;
break;
}
@@ -1286,8 +1636,8 @@ static int kinetis_read_part_info(struct flash_bank *bank)
|| (kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN512) {
/* K22 with new-style SDID - smaller pflash with FTFA, 2kB sectors */
pflash_sector_size_bytes = 2<<10;
- num_blocks = 2; /* 1 or 2 blocks */
- kinfo->flash_support = FS_PROGRAM_LONGWORD;
+ /* autodetect 1 or 2 blocks */
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
break;
}
LOG_ERROR("Unsupported Kinetis K22 DIEID");
@@ -1298,12 +1648,12 @@ static int kinetis_read_part_info(struct flash_bank *bank)
if ((kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN256) {
/* K24FN256 - smaller pflash with FTFA */
num_blocks = 1;
- kinfo->flash_support = FS_PROGRAM_LONGWORD;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
break;
}
/* K24FN1M without errata 7534 */
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
kinfo->max_flash_prog_size = 1<<10;
break;
@@ -1317,7 +1667,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
nvm_sector_size_bytes = 4<<10;
kinfo->max_flash_prog_size = 1<<10;
num_blocks = 2;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX6:
@@ -1328,19 +1678,71 @@ static int kinetis_read_part_info(struct flash_bank *bank)
nvm_sector_size_bytes = 4<<10;
kinfo->max_flash_prog_size = 1<<10;
num_blocks = 4;
- kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+ kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
break;
+
+ case KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX0:
+ case KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX1:
+ case KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX2:
+ /* K80FN256, K81FN256, K82FN256 */
+ pflash_sector_size_bytes = 4<<10;
+ num_blocks = 1;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+ break;
+
default:
LOG_ERROR("Unsupported Kinetis FAMILYID SUBFAMID");
}
break;
+
case KINETIS_SDID_SERIESID_KL:
/* KL-series */
pflash_sector_size_bytes = 1<<10;
nvm_sector_size_bytes = 1<<10;
- num_blocks = 1;
- kinfo->flash_support = FS_PROGRAM_LONGWORD;
+ /* autodetect 1 or 2 blocks */
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+ break;
+
+ case KINETIS_SDID_SERIESID_KV:
+ /* KV-series */
+ switch (kinfo->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {
+ case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX0:
+ /* KV10: FTFA, 1kB sectors */
+ pflash_sector_size_bytes = 1<<10;
+ num_blocks = 1;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+ break;
+
+ case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX1:
+ /* KV11: FTFA, 2kB sectors */
+ pflash_sector_size_bytes = 2<<10;
+ num_blocks = 1;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+ break;
+
+ case KINETIS_SDID_FAMILYID_K3X | KINETIS_SDID_SUBFAMID_KX0:
+ /* KV30: FTFA, 2kB sectors, 1 block */
+ case KINETIS_SDID_FAMILYID_K3X | KINETIS_SDID_SUBFAMID_KX1:
+ /* KV31: FTFA, 2kB sectors, 2 blocks */
+ pflash_sector_size_bytes = 2<<10;
+ /* autodetect 1 or 2 blocks */
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+ break;
+
+ case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX2:
+ case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX4:
+ case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX6:
+ /* KV4x: FTFA, 4kB sectors */
+ pflash_sector_size_bytes = 4<<10;
+ num_blocks = 1;
+ kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+ break;
+
+ default:
+ LOG_ERROR("Unsupported KV FAMILYID SUBFAMID");
+ }
break;
+
default:
LOG_ERROR("Unsupported K-series");
}
@@ -1358,7 +1760,6 @@ static int kinetis_read_part_info(struct flash_bank *bank)
result = target_read_u32(target, SIM_FCFG2, &kinfo->sim_fcfg2);
if (result != ERROR_OK)
return result;
- fcfg2_pflsh = (kinfo->sim_fcfg2 >> 23) & 0x01;
LOG_DEBUG("SDID: 0x%08" PRIX32 " FCFG1: 0x%08" PRIX32 " FCFG2: 0x%08" PRIX32, kinfo->sim_sdid,
kinfo->sim_fcfg1, kinfo->sim_fcfg2);
@@ -1366,11 +1767,27 @@ static int kinetis_read_part_info(struct flash_bank *bank)
fcfg1_nvmsize = (uint8_t)((kinfo->sim_fcfg1 >> 28) & 0x0f);
fcfg1_pfsize = (uint8_t)((kinfo->sim_fcfg1 >> 24) & 0x0f);
fcfg1_eesize = (uint8_t)((kinfo->sim_fcfg1 >> 16) & 0x0f);
+ fcfg1_depart = (uint8_t)((kinfo->sim_fcfg1 >> 8) & 0x0f);
+
+ fcfg2_pflsh = (uint8_t)((kinfo->sim_fcfg2 >> 23) & 0x01);
+ fcfg2_maxaddr0 = (uint8_t)((kinfo->sim_fcfg2 >> 24) & 0x7f);
+ fcfg2_maxaddr1 = (uint8_t)((kinfo->sim_fcfg2 >> 16) & 0x7f);
+
+ if (num_blocks == 0)
+ num_blocks = fcfg2_maxaddr1 ? 2 : 1;
+ else if (fcfg2_maxaddr1 == 0 && num_blocks >= 2) {
+ num_blocks = 1;
+ LOG_WARNING("MAXADDR1 is zero, number of flash banks adjusted to 1");
+ } else if (fcfg2_maxaddr1 != 0 && num_blocks == 1) {
+ num_blocks = 2;
+ LOG_WARNING("MAXADDR1 is non zero, number of flash banks adjusted to 2");
+ }
/* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
if (!fcfg2_pflsh) {
switch (fcfg1_nvmsize) {
case 0x03:
+ case 0x05:
case 0x07:
case 0x09:
case 0x0b:
@@ -1405,6 +1822,30 @@ static int kinetis_read_part_info(struct flash_bank *bank)
ee_size = 0;
break;
}
+
+ switch (fcfg1_depart) {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ df_size = nvm_size - (4096 << fcfg1_depart);
+ break;
+ case 0x08:
+ df_size = 0;
+ break;
+ case 0x09:
+ case 0x0a:
+ case 0x0b:
+ case 0x0c:
+ case 0x0d:
+ df_size = 4096 << (fcfg1_depart & 0x7);
+ break;
+ default:
+ df_size = nvm_size;
+ break;
+ }
}
switch (fcfg1_pfsize) {
@@ -1417,12 +1858,22 @@ static int kinetis_read_part_info(struct flash_bank *bank)
pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
break;
case 0x0f:
- if (pflash_sector_size_bytes >= 4<<10)
- pf_size = 1024<<10;
- else if (fcfg2_pflsh)
- pf_size = 512<<10;
+ /* a peculiar case: Freescale states different sizes for 0xf
+ * K02P64M100SFARM 128 KB ... duplicate of code 0x7
+ * K22P121M120SF8RM 256 KB ... duplicate of code 0x9
+ * K22P121M120SF7RM 512 KB ... duplicate of code 0xb
+ * K22P100M120SF5RM 1024 KB ... duplicate of code 0xd
+ * K26P169M180SF5RM 2048 KB ... the only unique value
+ * fcfg2_maxaddr0 seems to be the only clue to pf_size
+ * Checking fcfg2_maxaddr0 later in this routine is pointless then
+ */
+ if (fcfg2_pflsh)
+ pf_size = ((uint32_t)fcfg2_maxaddr0 << 13) * num_blocks;
else
- pf_size = 256<<10;
+ pf_size = ((uint32_t)fcfg2_maxaddr0 << 13) * num_blocks / 2;
+ if (pf_size != 2048<<10)
+ LOG_WARNING("SIM_FCFG1 PFSIZE = 0xf: please check if pflash is %u KB", pf_size>>10);
+
break;
default:
pf_size = 0;
@@ -1439,101 +1890,57 @@ static int kinetis_read_part_info(struct flash_bank *bank)
LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
num_blocks, num_pflash_blocks, num_nvm_blocks);
- /*
- * If the flash class is already assigned, verify the
- * parameters.
- */
- if (kinfo->flash_class != FC_AUTO) {
- if (kinfo->bank_ordinal != (unsigned) bank->bank_number) {
- LOG_WARNING("Flash ordinal/bank number mismatch");
- reassign = 1;
- } else {
- switch (kinfo->flash_class) {
- case FC_PFLASH:
- if (kinfo->bank_ordinal >= first_nvm_bank) {
- LOG_WARNING("Class mismatch, bank %d is not PFlash", bank->bank_number);
- reassign = 1;
- } else if (bank->size != (pf_size / num_pflash_blocks)) {
- LOG_WARNING("PFlash size mismatch");
- reassign = 1;
- } else if (bank->base !=
- (0x00000000 + bank->size * kinfo->bank_ordinal)) {
- LOG_WARNING("PFlash address range mismatch");
- reassign = 1;
- } else if (kinfo->sector_size != pflash_sector_size_bytes) {
- LOG_WARNING("PFlash sector size mismatch");
- reassign = 1;
- } else {
- LOG_DEBUG("PFlash bank %d already configured okay",
- kinfo->bank_ordinal);
- }
- break;
- case FC_FLEX_NVM:
- if ((kinfo->bank_ordinal >= num_blocks) ||
- (kinfo->bank_ordinal < first_nvm_bank)) {
- LOG_WARNING("Class mismatch, bank %d is not FlexNVM", bank->bank_number);
- reassign = 1;
- } else if (bank->size != (nvm_size / num_nvm_blocks)) {
- LOG_WARNING("FlexNVM size mismatch");
- reassign = 1;
- } else if (bank->base !=
- (0x10000000 + bank->size * kinfo->bank_ordinal)) {
- LOG_WARNING("FlexNVM address range mismatch");
- reassign = 1;
- } else if (kinfo->sector_size != nvm_sector_size_bytes) {
- LOG_WARNING("FlexNVM sector size mismatch");
- reassign = 1;
- } else {
- LOG_DEBUG("FlexNVM bank %d already configured okay",
- kinfo->bank_ordinal);
- }
- break;
- case FC_FLEX_RAM:
- if (kinfo->bank_ordinal != num_blocks) {
- LOG_WARNING("Class mismatch, bank %d is not FlexRAM", bank->bank_number);
- reassign = 1;
- } else if (bank->size != ee_size) {
- LOG_WARNING("FlexRAM size mismatch");
- reassign = 1;
- } else if (bank->base != FLEXRAM) {
- LOG_WARNING("FlexRAM address mismatch");
- reassign = 1;
- } else if (kinfo->sector_size != nvm_sector_size_bytes) {
- LOG_WARNING("FlexRAM sector size mismatch");
- reassign = 1;
- } else {
- LOG_DEBUG("FlexRAM bank %d already configured okay", kinfo->bank_ordinal);
- }
- break;
-
- default:
- LOG_WARNING("Unknown or inconsistent flash class");
- reassign = 1;
- break;
- }
- }
- } else {
- LOG_INFO("Probing flash info for bank %d", bank->bank_number);
- reassign = 1;
- }
-
- if (!reassign)
- return ERROR_OK;
+ LOG_INFO("Probing flash info for bank %d", bank->bank_number);
if ((unsigned)bank->bank_number < num_pflash_blocks) {
/* pflash, banks start at address zero */
kinfo->flash_class = FC_PFLASH;
bank->size = (pf_size / num_pflash_blocks);
bank->base = 0x00000000 + bank->size * bank->bank_number;
+ kinfo->prog_base = bank->base;
kinfo->sector_size = pflash_sector_size_bytes;
- kinfo->protection_size = pf_size / 32;
+ /* pflash is divided into 32 protection areas for
+ * parts with more than 32K of PFlash. For parts with
+ * less the protection unit is set to 1024 bytes */
+ kinfo->protection_size = MAX(pf_size / 32, 1024);
+ bank->num_prot_blocks = 32 / num_pflash_blocks;
+ kinfo->protection_block = bank->num_prot_blocks * bank->bank_number;
+
} else if ((unsigned)bank->bank_number < num_blocks) {
/* nvm, banks start at address 0x10000000 */
+ unsigned nvm_ord = bank->bank_number - first_nvm_bank;
+ uint32_t limit;
+
kinfo->flash_class = FC_FLEX_NVM;
bank->size = (nvm_size / num_nvm_blocks);
- bank->base = 0x10000000 + bank->size * (bank->bank_number - first_nvm_bank);
+ bank->base = 0x10000000 + bank->size * nvm_ord;
+ kinfo->prog_base = 0x00800000 + bank->size * nvm_ord;
kinfo->sector_size = nvm_sector_size_bytes;
- kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART bits, chip */
+ if (df_size == 0) {
+ kinfo->protection_size = 0;
+ } else {
+ for (i = df_size; ~i & 1; i >>= 1)
+ ;
+ if (i == 1)
+ kinfo->protection_size = df_size / 8; /* data flash size = 2^^n */
+ else
+ kinfo->protection_size = nvm_size / 8; /* TODO: verify on SF1, not documented in RM */
+ }
+ bank->num_prot_blocks = 8 / num_nvm_blocks;
+ kinfo->protection_block = bank->num_prot_blocks * nvm_ord;
+
+ /* EEPROM backup part of FlexNVM is not accessible, use df_size as a limit */
+ if (df_size > bank->size * nvm_ord)
+ limit = df_size - bank->size * nvm_ord;
+ else
+ limit = 0;
+
+ if (bank->size > limit) {
+ bank->size = limit;
+ LOG_DEBUG("FlexNVM bank %d limited to 0x%08" PRIx32 " due to active EEPROM backup",
+ bank->bank_number, limit);
+ }
+
} else if ((unsigned)bank->bank_number == num_blocks) {
LOG_ERROR("FlexRAM support not yet implemented");
return ERROR_FLASH_OPER_UNSUPPORTED;
@@ -1543,10 +1950,28 @@ static int kinetis_read_part_info(struct flash_bank *bank)
return ERROR_FLASH_BANK_INVALID;
}
+ if (bank->bank_number == 0 && ((uint32_t)fcfg2_maxaddr0 << 13) != bank->size)
+ LOG_WARNING("MAXADDR0 0x%02" PRIx8 " check failed,"
+ " please report to OpenOCD mailing list", fcfg2_maxaddr0);
+ if (fcfg2_pflsh) {
+ if (bank->bank_number == 1 && ((uint32_t)fcfg2_maxaddr1 << 13) != bank->size)
+ LOG_WARNING("MAXADDR1 0x%02" PRIx8 " check failed,"
+ " please report to OpenOCD mailing list", fcfg2_maxaddr1);
+ } else {
+ if ((unsigned)bank->bank_number == first_nvm_bank
+ && ((uint32_t)fcfg2_maxaddr1 << 13) != df_size)
+ LOG_WARNING("FlexNVM MAXADDR1 0x%02" PRIx8 " check failed,"
+ " please report to OpenOCD mailing list", fcfg2_maxaddr1);
+ }
+
if (bank->sectors) {
free(bank->sectors);
bank->sectors = NULL;
}
+ if (bank->prot_blocks) {
+ free(bank->prot_blocks);
+ bank->prot_blocks = NULL;
+ }
if (kinfo->sector_size == 0) {
LOG_ERROR("Unknown sector size for bank %d", bank->bank_number);
@@ -1560,35 +1985,31 @@ static int kinetis_read_part_info(struct flash_bank *bank)
}
bank->num_sectors = bank->size / kinfo->sector_size;
- assert(bank->num_sectors > 0);
- bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
- for (i = 0; i < bank->num_sectors; i++) {
- bank->sectors[i].offset = offset;
- bank->sectors[i].size = kinfo->sector_size;
- offset += kinfo->sector_size;
- bank->sectors[i].is_erased = -1;
- bank->sectors[i].is_protected = 1;
- }
+ if (bank->num_sectors > 0) {
+ /* FlexNVM bank can be used for EEPROM backup therefore zero sized */
+ bank->sectors = alloc_block_array(0, kinfo->sector_size, bank->num_sectors);
+ if (!bank->sectors)
+ return ERROR_FAIL;
- return ERROR_OK;
-}
+ bank->prot_blocks = alloc_block_array(0, kinfo->protection_size, bank->num_prot_blocks);
+ if (!bank->prot_blocks)
+ return ERROR_FAIL;
-static int kinetis_probe(struct flash_bank *bank)
-{
- if (bank->target->state != TARGET_HALTED) {
- LOG_WARNING("Cannot communicate... target not halted.");
- return ERROR_TARGET_NOT_HALTED;
+ } else {
+ bank->num_prot_blocks = 0;
}
- return kinetis_read_part_info(bank);
+ kinfo->probed = true;
+
+ return ERROR_OK;
}
static int kinetis_auto_probe(struct flash_bank *bank)
{
struct kinetis_flash_bank *kinfo = bank->driver_priv;
- if (kinfo->sim_sdid)
+ if (kinfo && kinfo->probed)
return ERROR_OK;
return kinetis_probe(bank);
@@ -1613,28 +2034,45 @@ static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
static int kinetis_blank_check(struct flash_bank *bank)
{
struct kinetis_flash_bank *kinfo = bank->driver_priv;
+ int result;
- if (bank->target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
+ /* suprisingly blank check does not work in VLPR and HSRUN modes */
+ result = kinetis_check_run_mode(bank->target);
+ if (result != ERROR_OK)
+ return result;
- if (kinfo->flash_class == FC_PFLASH) {
- int result;
+ /* reset error flags */
+ result = kinetis_ftfx_prepare(bank->target);
+ if (result != ERROR_OK)
+ return result;
+
+ if (kinfo->flash_class == FC_PFLASH || kinfo->flash_class == FC_FLEX_NVM) {
+ bool block_dirty = false;
uint8_t ftfx_fstat;
- /* check if whole bank is blank */
- result = kinetis_ftfx_command(bank, FTFx_CMD_BLOCKSTAT, bank->base, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
+ if (kinfo->flash_class == FC_FLEX_NVM) {
+ uint8_t fcfg1_depart = (uint8_t)((kinfo->sim_fcfg1 >> 8) & 0x0f);
+ /* block operation cannot be used on FlexNVM when EEPROM backup partition is set */
+ if (fcfg1_depart != 0xf && fcfg1_depart != 0)
+ block_dirty = true;
+ }
- if (result != ERROR_OK)
- return result;
+ if (!block_dirty) {
+ /* check if whole bank is blank */
+ result = kinetis_ftfx_command(bank->target, FTFx_CMD_BLOCKSTAT, kinfo->prog_base,
+ 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
- if (ftfx_fstat & 0x01) {
+ if (result != ERROR_OK || (ftfx_fstat & 0x01))
+ block_dirty = true;
+ }
+
+ if (block_dirty) {
/* the whole bank is not erased, check sector-by-sector */
int i;
for (i = 0; i < bank->num_sectors; i++) {
/* normal margin */
- result = kinetis_ftfx_command(bank, FTFx_CMD_SECTSTAT, bank->base + bank->sectors[i].offset,
+ result = kinetis_ftfx_command(bank->target, FTFx_CMD_SECTSTAT,
+ kinfo->prog_base + bank->sectors[i].offset,
1, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
if (result == ERROR_OK) {
@@ -1651,34 +2089,222 @@ static int kinetis_blank_check(struct flash_bank *bank)
bank->sectors[i].is_erased = 1;
}
} else {
- LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
+ LOG_WARNING("kinetis_blank_check not supported yet for FlexRAM");
return ERROR_FLASH_OPERATION_FAILED;
}
return ERROR_OK;
}
-static const struct command_registration kinetis_securtiy_command_handlers[] = {
+
+COMMAND_HANDLER(kinetis_nvm_partition)
+{
+ int result, i;
+ unsigned long par, log2 = 0, ee1 = 0, ee2 = 0;
+ enum { SHOW_INFO, DF_SIZE, EEBKP_SIZE } sz_type = SHOW_INFO;
+ bool enable;
+ uint8_t load_flex_ram = 1;
+ uint8_t ee_size_code = 0x3f;
+ uint8_t flex_nvm_partition_code = 0;
+ uint8_t ee_split = 3;
+ struct target *target = get_current_target(CMD_CTX);
+ struct flash_bank *bank;
+ struct kinetis_flash_bank *kinfo;
+ uint32_t sim_fcfg1;
+
+ if (CMD_ARGC >= 2) {
+ if (strcmp(CMD_ARGV[0], "dataflash") == 0)
+ sz_type = DF_SIZE;
+ else if (strcmp(CMD_ARGV[0], "eebkp") == 0)
+ sz_type = EEBKP_SIZE;
+
+ par = strtoul(CMD_ARGV[1], NULL, 10);
+ while (par >> (log2 + 3))
+ log2++;
+ }
+ switch (sz_type) {
+ case SHOW_INFO:
+ result = target_read_u32(target, SIM_FCFG1, &sim_fcfg1);
+ if (result != ERROR_OK)
+ return result;
+
+ flex_nvm_partition_code = (uint8_t)((sim_fcfg1 >> 8) & 0x0f);
+ switch (flex_nvm_partition_code) {
+ case 0:
+ command_print(CMD_CTX, "No EEPROM backup, data flash only");
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ command_print(CMD_CTX, "EEPROM backup %d KB", 4 << flex_nvm_partition_code);
+ break;
+ case 8:
+ command_print(CMD_CTX, "No data flash, EEPROM backup only");
+ break;
+ case 0x9:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0xD:
+ case 0xE:
+ command_print(CMD_CTX, "data flash %d KB", 4 << (flex_nvm_partition_code & 7));
+ break;
+ case 0xf:
+ command_print(CMD_CTX, "No EEPROM backup, data flash only (DEPART not set)");
+ break;
+ default:
+ command_print(CMD_CTX, "Unsupported EEPROM backup size code 0x%02" PRIx8, flex_nvm_partition_code);
+ }
+ return ERROR_OK;
+
+ case DF_SIZE:
+ flex_nvm_partition_code = 0x8 | log2;
+ break;
+
+ case EEBKP_SIZE:
+ flex_nvm_partition_code = log2;
+ break;
+ }
+
+ if (CMD_ARGC == 3)
+ ee1 = ee2 = strtoul(CMD_ARGV[2], NULL, 10) / 2;
+ else if (CMD_ARGC >= 4) {
+ ee1 = strtoul(CMD_ARGV[2], NULL, 10);
+ ee2 = strtoul(CMD_ARGV[3], NULL, 10);
+ }
+
+ enable = ee1 + ee2 > 0;
+ if (enable) {
+ for (log2 = 2; ; log2++) {
+ if (ee1 + ee2 == (16u << 10) >> log2)
+ break;
+ if (ee1 + ee2 > (16u << 10) >> log2 || log2 >= 9) {
+ LOG_ERROR("Unsupported EEPROM size");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ }
+
+ if (ee1 * 3 == ee2)
+ ee_split = 1;
+ else if (ee1 * 7 == ee2)
+ ee_split = 0;
+ else if (ee1 != ee2) {
+ LOG_ERROR("Unsupported EEPROM sizes ratio");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+
+ ee_size_code = log2 | ee_split << 4;
+ }
+
+ if (CMD_ARGC >= 5)
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[4], enable);
+ if (enable)
+ load_flex_ram = 0;
+
+ LOG_INFO("DEPART 0x%" PRIx8 ", EEPROM size code 0x%" PRIx8,
+ flex_nvm_partition_code, ee_size_code);
+
+ result = kinetis_check_run_mode(target);
+ if (result != ERROR_OK)
+ return result;
+
+ /* reset error flags */
+ result = kinetis_ftfx_prepare(target);
+ if (result != ERROR_OK)
+ return result;
+
+ result = kinetis_ftfx_command(target, FTFx_CMD_PGMPART, load_flex_ram,
+ ee_size_code, flex_nvm_partition_code, 0, 0,
+ 0, 0, 0, 0, NULL);
+ if (result != ERROR_OK)
+ return result;
+
+ command_print(CMD_CTX, "FlexNVM partition set. Please reset MCU.");
+
+ for (i = 1; i < 4; i++) {
+ bank = get_flash_bank_by_num_noprobe(i);
+ if (bank == NULL)
+ break;
+
+ kinfo = bank->driver_priv;
+ if (kinfo && kinfo->flash_class == FC_FLEX_NVM)
+ kinfo->probed = false; /* re-probe before next use */
+ }
+
+ command_print(CMD_CTX, "FlexNVM banks will be re-probed to set new data flash size.");
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(kinetis_fcf_source_handler)
+{
+ if (CMD_ARGC > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (CMD_ARGC == 1) {
+ if (strcmp(CMD_ARGV[0], "write") == 0)
+ allow_fcf_writes = true;
+ else if (strcmp(CMD_ARGV[0], "protection") == 0)
+ allow_fcf_writes = false;
+ else
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ if (allow_fcf_writes) {
+ command_print(CMD_CTX, "Arbitrary Flash Configuration Field writes enabled.");
+ command_print(CMD_CTX, "Protection info writes to FCF disabled.");
+ LOG_WARNING("BEWARE: incorrect flash configuration may permanently lock the device.");
+ } else {
+ command_print(CMD_CTX, "Protection info writes to Flash Configuration Field enabled.");
+ command_print(CMD_CTX, "Arbitrary FCF writes disabled. Mode safe from unwanted locking of the device.");
+ }
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(kinetis_fopt_handler)
+{
+ if (CMD_ARGC > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (CMD_ARGC == 1)
+ fcf_fopt = (uint8_t)strtoul(CMD_ARGV[0], NULL, 0);
+ else
+ command_print(CMD_CTX, "FCF_FOPT 0x%02" PRIx8, fcf_fopt);
+
+ return ERROR_OK;
+}
+
+
+static const struct command_registration kinetis_security_command_handlers[] = {
{
.name = "check_security",
.mode = COMMAND_EXEC,
- .help = "",
+ .help = "Check status of device security lock",
.usage = "",
.handler = kinetis_check_flash_security_status,
},
+ {
+ .name = "halt",
+ .mode = COMMAND_EXEC,
+ .help = "Issue a halt via the MDM-AP",
+ .usage = "",
+ .handler = kinetis_mdm_halt,
+ },
{
.name = "mass_erase",
.mode = COMMAND_EXEC,
- .help = "",
+ .help = "Issue a complete flash erase via the MDM-AP",
.usage = "",
.handler = kinetis_mdm_mass_erase,
},
- {
- .name = "test_securing",
+ { .name = "reset",
.mode = COMMAND_EXEC,
- .help = "",
+ .help = "Issue a reset via the MDM-AP",
.usage = "",
- .handler = kinetis_securing_test,
+ .handler = kinetis_mdm_reset,
},
COMMAND_REGISTRATION_DONE
};
@@ -1687,9 +2313,9 @@ static const struct command_registration kinetis_exec_command_handlers[] = {
{
.name = "mdm",
.mode = COMMAND_ANY,
- .help = "",
+ .help = "MDM-AP command group",
.usage = "",
- .chain = kinetis_securtiy_command_handlers,
+ .chain = kinetis_security_command_handlers,
},
{
.name = "disable_wdog",
@@ -1698,6 +2324,29 @@ static const struct command_registration kinetis_exec_command_handlers[] = {
.usage = "",
.handler = kinetis_disable_wdog_handler,
},
+ {
+ .name = "nvm_partition",
+ .mode = COMMAND_EXEC,
+ .help = "Show/set data flash or EEPROM backup size in kilobytes,"
+ " set two EEPROM sizes in bytes and FlexRAM loading during reset",
+ .usage = "('info'|'dataflash' size|'eebkp' size) [eesize1 eesize2] ['on'|'off']",
+ .handler = kinetis_nvm_partition,
+ },
+ {
+ .name = "fcf_source",
+ .mode = COMMAND_EXEC,
+ .help = "Use protection as a source for Flash Configuration Field or allow writing arbitrary values to the FCF"
+ " Mode 'protection' is safe from unwanted locking of the device.",
+ .usage = "['protection'|'write']",
+ .handler = kinetis_fcf_source_handler,
+ },
+ {
+ .name = "fopt",
+ .mode = COMMAND_EXEC,
+ .help = "FCF_FOPT value source in 'kinetis fcf_source protection' mode",
+ .usage = "[num]",
+ .handler = kinetis_fopt_handler,
+ },
COMMAND_REGISTRATION_DONE
};
@@ -1705,7 +2354,7 @@ static const struct command_registration kinetis_command_handler[] = {
{
.name = "kinetis",
.mode = COMMAND_ANY,
- .help = "kinetis NAND flash controller commands",
+ .help = "Kinetis flash controller commands",
.usage = "",
.chain = kinetis_exec_command_handlers,
},
diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c
index cc10a3bb3..9da5da2ca 100644
--- a/src/flash/nor/lpc2000.c
+++ b/src/flash/nor/lpc2000.c
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -261,6 +259,8 @@
#define IAP_CODE_LEN 0x34
+#define LPC11xx_REG_SECTORS 24
+
typedef enum {
lpc2000_v1,
lpc2000_v2,
@@ -556,14 +556,21 @@ static int lpc2000_build_sector_list(struct flash_bank *bank)
exit(-1);
}
lpc2000_info->cmd51_max_buffer = 512; /* smallest MCU in the series, LPC1110, has 1 kB of SRAM */
- bank->num_sectors = bank->size / 4096;
+ unsigned int large_sectors = 0;
+ unsigned int normal_sectors = bank->size / 4096;
+
+ if (normal_sectors > LPC11xx_REG_SECTORS) {
+ large_sectors = (normal_sectors - LPC11xx_REG_SECTORS) / 8;
+ normal_sectors = LPC11xx_REG_SECTORS;
+ }
+
+ bank->num_sectors = normal_sectors + large_sectors;
bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
for (int i = 0; i < bank->num_sectors; i++) {
bank->sectors[i].offset = offset;
- /* all sectors are 4kB-sized */
- bank->sectors[i].size = 4 * 1024;
+ bank->sectors[i].size = (i < LPC11xx_REG_SECTORS ? 4 : 32) * 1024;
offset += bank->sectors[i].size;
bank->sectors[i].is_erased = -1;
bank->sectors[i].is_protected = 1;
@@ -681,7 +688,7 @@ static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working
int retval = target_write_memory(target, (*iap_working_area)->address, 4, 2, jump_gate);
if (retval != ERROR_OK) {
- LOG_ERROR("Write memory at address 0x%8.8" PRIx32 " failed (check work_area definition)",
+ LOG_ERROR("Write memory at address 0x%8.8" TARGET_PRIxADDR " failed (check work_area definition)",
(*iap_working_area)->address);
target_free_working_area(target, *iap_working_area);
}
diff --git a/src/flash/nor/lpc288x.c b/src/flash/nor/lpc288x.c
index 89f79e321..a4d88de78 100644
--- a/src/flash/nor/lpc288x.c
+++ b/src/flash/nor/lpc288x.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/***************************************************************************
diff --git a/src/flash/nor/lpc2900.c b/src/flash/nor/lpc2900.c
index 7c3e67580..515a3f7b2 100644
--- a/src/flash/nor/lpc2900.c
+++ b/src/flash/nor/lpc2900.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -556,7 +554,7 @@ COMMAND_HANDLER(lpc2900_handle_read_custom_command)
target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);
/* Try and open the file */
- struct fileio fileio;
+ struct fileio *fileio;
const char *filename = CMD_ARGV[1];
int ret = fileio_open(&fileio, filename, FILEIO_WRITE, FILEIO_BINARY);
if (ret != ERROR_OK) {
@@ -565,14 +563,14 @@ COMMAND_HANDLER(lpc2900_handle_read_custom_command)
}
size_t nwritten;
- ret = fileio_write(&fileio, sizeof(customer), customer, &nwritten);
+ ret = fileio_write(fileio, sizeof(customer), customer, &nwritten);
if (ret != ERROR_OK) {
LOG_ERROR("Write operation to file %s failed", filename);
- fileio_close(&fileio);
+ fileio_close(fileio);
return ret;
}
- fileio_close(&fileio);
+ fileio_close(fileio);
return ERROR_OK;
}
@@ -1160,7 +1158,6 @@ static int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer,
break;
}
}
- ;
if (warea) {
struct reg_param reg_params[5];
diff --git a/src/flash/nor/lpcspifi.c b/src/flash/nor/lpcspifi.c
index 3b383ebd9..943c151e2 100644
--- a/src/flash/nor/lpcspifi.c
+++ b/src/flash/nor/lpcspifi.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -58,21 +56,6 @@ struct lpcspifi_flash_bank {
const struct flash_device *dev;
};
-struct lpcspifi_target {
- char *name;
- uint32_t tap_idcode;
- uint32_t spifi_base;
- uint32_t ssp_base;
- uint32_t io_base;
- uint32_t ioconfig_base; /* base address for the port word pin registers */
-};
-
-static const struct lpcspifi_target target_devices[] = {
- /* name, tap_idcode, spifi_base, ssp_base, io_base, ioconfig_base */
- { "LPC43xx/18xx", 0x4ba00477, 0x14000000, 0x40083000, 0x400F4000, 0x40086000 },
- { NULL, 0, 0, 0, 0, 0 }
-};
-
/* flash_bank lpcspifi
*/
FLASH_BANK_COMMAND_HANDLER(lpcspifi_flash_bank_command)
@@ -123,7 +106,7 @@ static int ssp_setcs(struct target *target, uint32_t io_base, unsigned int value
* and the controller is idle. */
static int poll_ssp_busy(struct target *target, uint32_t ssp_base, int timeout)
{
- long long endtime;
+ int64_t endtime;
uint32_t value;
int retval;
@@ -203,7 +186,7 @@ static int lpcspifi_set_hw_mode(struct flash_bank *bank)
return retval;
}
- LOG_DEBUG("Writing algorithm to working area at 0x%08" PRIx32,
+ LOG_DEBUG("Writing algorithm to working area at 0x%08" TARGET_PRIxADDR,
spifi_init_algorithm->address);
/* Write algorithm to working area */
retval = target_write_buffer(target,
@@ -342,7 +325,7 @@ static int wait_till_ready(struct flash_bank *bank, int timeout)
{
uint32_t status;
int retval;
- long long endtime;
+ int64_t endtime;
endtime = timeval_ms() + timeout;
do {
@@ -698,7 +681,7 @@ static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer,
" a working area > %zdB in order to write to SPIFI flash.",
sizeof(lpcspifi_flash_write_code));
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
retval = target_write_buffer(target, write_algorithm->address,
sizeof(lpcspifi_flash_write_code),
@@ -734,7 +717,7 @@ static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer,
if (target_alloc_working_area(target, fifo_size, &fifo) != ERROR_OK) {
target_free_working_area(target, write_algorithm);
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
armv7m_info.core_mode = ARM_MODE_THREAD;
@@ -852,14 +835,9 @@ static int lpcspifi_read_flash_id(struct flash_bank *bank, uint32_t *id)
static int lpcspifi_probe(struct flash_bank *bank)
{
- struct target *target = bank->target;
struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
- uint32_t ssp_base;
- uint32_t io_base;
- uint32_t ioconfig_base;
struct flash_sector *sectors;
uint32_t id = 0; /* silence uninitialized warning */
- const struct lpcspifi_target *target_device;
int retval;
/* If we've already probed, we should be fine to skip this time. */
@@ -867,26 +845,11 @@ static int lpcspifi_probe(struct flash_bank *bank)
return ERROR_OK;
lpcspifi_info->probed = 0;
- for (target_device = target_devices ; target_device->name ; ++target_device)
- if (target_device->tap_idcode == target->tap->idcode)
- break;
- if (!target_device->name) {
- LOG_ERROR("Device ID 0x%" PRIx32 " is not known as SPIFI capable",
- target->tap->idcode);
- return ERROR_FAIL;
- }
-
- ssp_base = target_device->ssp_base;
- io_base = target_device->io_base;
- ioconfig_base = target_device->ioconfig_base;
- lpcspifi_info->ssp_base = ssp_base;
- lpcspifi_info->io_base = io_base;
- lpcspifi_info->ioconfig_base = ioconfig_base;
+ lpcspifi_info->ssp_base = 0x40083000;
+ lpcspifi_info->io_base = 0x400F4000;
+ lpcspifi_info->ioconfig_base = 0x40086000;
lpcspifi_info->bank_num = bank->bank_number;
- LOG_DEBUG("Valid SPIFI on device %s at address 0x%" PRIx32,
- target_device->name, bank->base);
-
/* read and decode flash ID; returns in SW mode */
retval = lpcspifi_read_flash_id(bank, &id);
if (retval != ERROR_OK)
diff --git a/src/flash/nor/mdr.c b/src/flash/nor/mdr.c
index 98e013aa3..8ceb1bf46 100644
--- a/src/flash/nor/mdr.c
+++ b/src/flash/nor/mdr.c
@@ -22,9 +22,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -173,7 +171,8 @@ static int mdr_erase(struct flash_bank *bank, int first, int last)
if (retval != ERROR_OK)
goto reset_pg_and_lock;
- if ((first == 0) && (last == (bank->num_sectors - 1))) {
+ if ((first == 0) && (last == (bank->num_sectors - 1)) &&
+ !mdr_info->mem_type) {
retval = mdr_mass_erase(bank);
goto reset_pg_and_lock;
}
@@ -255,7 +254,7 @@ static int mdr_write_block(struct flash_bank *bank, const uint8_t *buffer,
&write_algorithm) != ERROR_OK) {
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
retval = target_write_buffer(target, write_algorithm->address,
sizeof(mdr32fx_flash_write_code), mdr32fx_flash_write_code);
@@ -274,7 +273,7 @@ static int mdr_write_block(struct flash_bank *bank, const uint8_t *buffer,
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- };
+ }
init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* count (32bit) */
@@ -471,6 +470,107 @@ static int mdr_write(struct flash_bank *bank, const uint8_t *buffer,
if (new_buffer)
free(new_buffer);
+ /* read some bytes bytes to flush buffer in flash accelerator.
+ * See errata for 1986VE1T and 1986VE3. Error 0007 */
+ if ((retval == ERROR_OK) && (!mdr_info->mem_type)) {
+ uint32_t tmp;
+ target_checksum_memory(bank->target, bank->base, 64, &tmp);
+ }
+
+ return retval;
+}
+
+static int mdr_read(struct flash_bank *bank, uint8_t *buffer,
+ uint32_t offset, uint32_t count)
+{
+ struct target *target = bank->target;
+ struct mdr_flash_bank *mdr_info = bank->driver_priv;
+ int retval, retval2;
+
+ if (!mdr_info->mem_type)
+ return default_flash_read(bank, buffer, offset, count);
+
+ if (bank->target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (offset & 0x3) {
+ LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-byte alignment", offset);
+ return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+ }
+
+ if (count & 0x3) {
+ LOG_ERROR("count 0x%" PRIx32 " breaks required 4-byte alignment", count);
+ return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+ }
+
+ uint32_t flash_cmd, cur_per_clock;
+
+ retval = target_read_u32(target, MD_PER_CLOCK, &cur_per_clock);
+ if (retval != ERROR_OK)
+ goto err;
+
+ if (!(cur_per_clock & MD_PER_CLOCK_RST_CLK)) {
+ /* Something's very wrong if the RST_CLK module is not clocked */
+ LOG_ERROR("Target needs reset before flash operations");
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ goto err;
+ }
+
+ retval = target_write_u32(target, MD_PER_CLOCK, cur_per_clock | MD_PER_CLOCK_EEPROM);
+ if (retval != ERROR_OK)
+ goto err;
+
+ retval = target_write_u32(target, FLASH_KEY, KEY);
+ if (retval != ERROR_OK)
+ goto err;
+
+ retval = target_read_u32(target, FLASH_CMD, &flash_cmd);
+ if (retval != ERROR_OK)
+ goto err_lock;
+
+ /* Switch on register access */
+ flash_cmd = (flash_cmd & FLASH_DELAY_MASK) | FLASH_CON | FLASH_IFREN;
+ retval = target_write_u32(target, FLASH_CMD, flash_cmd);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ for (uint32_t i = 0; i < count; i += 4) {
+ retval = target_write_u32(target, FLASH_ADR, offset + i);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ retval = target_write_u32(target, FLASH_CMD, flash_cmd |
+ FLASH_XE | FLASH_YE | FLASH_SE);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ uint32_t buf;
+ retval = target_read_u32(target, FLASH_DO, &buf);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ buf_set_u32(buffer, i * 8, 32, buf);
+
+ retval = target_write_u32(target, FLASH_CMD, flash_cmd);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ }
+
+reset_pg_and_lock:
+ flash_cmd &= FLASH_DELAY_MASK;
+ retval2 = target_write_u32(target, FLASH_CMD, flash_cmd);
+ if (retval == ERROR_OK)
+ retval = retval2;
+
+err_lock:
+ retval2 = target_write_u32(target, FLASH_KEY, 0);
+ if (retval == ERROR_OK)
+ retval = retval2;
+
+err:
return retval;
}
@@ -527,7 +627,7 @@ struct flash_driver mdr_flash = {
.erase = mdr_erase,
.protect = mdr_protect,
.write = mdr_write,
- .read = default_flash_read,
+ .read = mdr_read,
.probe = mdr_probe,
.auto_probe = mdr_auto_probe,
.erase_check = default_flash_blank_check,
diff --git a/src/flash/nor/mrvlqspi.c b/src/flash/nor/mrvlqspi.c
index 0dfe6f86f..d79917058 100644
--- a/src/flash/nor/mrvlqspi.c
+++ b/src/flash/nor/mrvlqspi.c
@@ -12,10 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
- * *
+ * along with this program. If not, see . *
***************************************************************************/
/*
@@ -680,7 +677,7 @@ static int mrvlqspi_flash_write(struct flash_bank *bank, const uint8_t *buffer,
" a working area > %zdB in order to write to SPIFI flash.",
sizeof(mrvlqspi_flash_write_code));
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
retval = target_write_buffer(target, write_algorithm->address,
sizeof(mrvlqspi_flash_write_code),
@@ -714,7 +711,7 @@ static int mrvlqspi_flash_write(struct flash_bank *bank, const uint8_t *buffer,
if (target_alloc_working_area(target, fifo_size, &fifo) != ERROR_OK) {
target_free_working_area(target, write_algorithm);
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
armv7m_info.core_mode = ARM_MODE_THREAD;
diff --git a/src/flash/nor/niietcm4.c b/src/flash/nor/niietcm4.c
index 78467c5a2..4a849fd26 100644
--- a/src/flash/nor/niietcm4.c
+++ b/src/flash/nor/niietcm4.c
@@ -13,8 +13,7 @@
* GNU 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. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -155,7 +154,7 @@ static int niietcm4_opstatus_check(struct flash_bank *bank)
{
struct target *target = bank->target;
int retval;
- int timeout = 100;
+ int timeout = 5000;
uint32_t flash_status;
retval = target_read_u32(target, FCIS, &flash_status);
@@ -192,7 +191,7 @@ static int niietcm4_uopstatus_check(struct flash_bank *bank)
{
struct target *target = bank->target;
int retval;
- int timeout = 100;
+ int timeout = 5000;
uint32_t uflash_status;
retval = target_read_u32(target, UFCIS, &uflash_status);
@@ -231,7 +230,8 @@ static int niietcm4_uopstatus_check(struct flash_bank *bank)
static int niietcm4_dump_uflash_page(struct flash_bank *bank, uint32_t *dump, int page_num, int mem_type)
{
struct target *target = bank->target;
- int i, retval;
+ int i;
+ int retval = ERROR_OK;
uint32_t uflash_cmd;
if (mem_type == INFO_MEM_TYPE)
@@ -266,7 +266,8 @@ static int niietcm4_dump_uflash_page(struct flash_bank *bank, uint32_t *dump, in
static int niietcm4_load_uflash_page(struct flash_bank *bank, uint32_t *dump, int page_num, int mem_type)
{
struct target *target = bank->target;
- int i, retval;
+ int i;
+ int retval = ERROR_OK;
uint32_t uflash_cmd;
if (mem_type == INFO_MEM_TYPE)
@@ -1048,7 +1049,7 @@ FLASH_BANK_COMMAND_HANDLER(niietcm4_flash_bank_command)
{
struct niietcm4_flash_bank *niietcm4_info;
- if (CMD_ARGC < 7)
+ if (CMD_ARGC < 6)
return ERROR_COMMAND_SYNTAX_ERROR;
niietcm4_info = malloc(sizeof(struct niietcm4_flash_bank));
@@ -1299,7 +1300,7 @@ static int niietcm4_write_block(struct flash_bank *bank, const uint8_t *buffer,
&write_algorithm) != ERROR_OK) {
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
retval = target_write_buffer(target, write_algorithm->address,
sizeof(niietcm4_flash_write_code), niietcm4_flash_write_code);
@@ -1319,7 +1320,7 @@ static int niietcm4_write_block(struct flash_bank *bank, const uint8_t *buffer,
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- };
+ }
init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* write_cmd base (in), status (out) */
init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* count (128bit) */
@@ -1370,17 +1371,38 @@ static int niietcm4_write(struct flash_bank *bank, const uint8_t *buffer,
{
struct target *target = bank->target;
struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
+ uint8_t *new_buffer = NULL;
if (bank->target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
- if (offset & 0x3) {
- LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-byte alignment", offset);
+ if (offset & 0xF) {
+ LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-word alignment", offset);
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
}
+ /* If there's an odd number of words, the data has to be padded. Duplicate
+ * the buffer and use the normal code path with a single block write since
+ * it's probably cheaper than to special case the last odd write using
+ * discrete accesses. */
+
+ int rem = count % 16;
+ if (rem) {
+ new_buffer = malloc(count + 16 - rem);
+ if (new_buffer == NULL) {
+ LOG_ERROR("Odd number of words to write and no memory for padding buffer");
+ return ERROR_FAIL;
+ }
+ LOG_INFO("Odd number of words to write, padding with 0xFFFFFFFF");
+ buffer = memcpy(new_buffer, buffer, count);
+ while (rem < 16) {
+ new_buffer[count++] = 0xff;
+ rem++;
+ }
+ }
+
int retval;
/* try using block write */
@@ -1406,46 +1428,47 @@ static int niietcm4_write(struct flash_bank *bank, const uint8_t *buffer,
flash_addr = offset + i;
retval = target_write_u32(target, FMA, flash_addr);
if (retval != ERROR_OK)
- return retval;
+ goto free_buffer;
- /* if there's an odd number of bytes, the data has to be padded */
- uint8_t padding[16] = { 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff};
- memcpy(padding, buffer + i, MIN(16, count-i));
+ /* Prepare data (4 words) */
+ uint32_t value[4];
+ memcpy(&value, buffer + i*16, 4*sizeof(uint32_t));
/* place in reg 16 bytes of data */
- flash_data = (padding[3]<<24) | (padding[2]<<16) | (padding[1]<<8) | padding[0];
+ flash_data = value[0];
retval = target_write_u32(target, FMD1, flash_data);
if (retval != ERROR_OK)
- return retval;
- flash_data = (padding[7]<<24) | (padding[6]<<16) | (padding[5]<<8) | padding[4];
+ goto free_buffer;
+ flash_data = value[1];
retval = target_write_u32(target, FMD2, flash_data);
if (retval != ERROR_OK)
- return retval;
- flash_data = (padding[11]<<24) | (padding[10]<<16) | (padding[9]<<8) | padding[8];
+ goto free_buffer;
+ flash_data = value[2];
retval = target_write_u32(target, FMD3, flash_data);
if (retval != ERROR_OK)
- return retval;
- flash_data = (padding[15]<<24) | (padding[14]<<16) | (padding[13]<<8) | padding[12];
+ goto free_buffer;
+ flash_data = value[3];
retval = target_write_u32(target, FMD4, flash_data);
if (retval != ERROR_OK)
- return retval;
+ goto free_buffer;
/* write start */
retval = target_write_u32(target, FMC, flash_cmd);
if (retval != ERROR_OK)
- return retval;
+ goto free_buffer;
/* status check */
retval = niietcm4_opstatus_check(bank);
if (retval != ERROR_OK)
- return retval;
+ goto free_buffer;
}
}
+free_buffer:
+ if (new_buffer)
+ free(new_buffer);
+
return retval;
}
@@ -1697,7 +1720,7 @@ static int niietcm4_auto_probe(struct flash_bank *bank)
static int get_niietcm4_info(struct flash_bank *bank, char *buf, int buf_size)
{
struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
- LOG_INFO("\nNIIET Cortex M4F %s\n%s", niietcm4_info->chip_name, niietcm4_info->chip_brief);
+ LOG_INFO("\nNIIET Cortex-M4F %s\n%s", niietcm4_info->chip_name, niietcm4_info->chip_brief);
snprintf(buf, buf_size, " ");
return ERROR_OK;
diff --git a/src/flash/nor/non_cfi.c b/src/flash/nor/non_cfi.c
index 72f11e553..851c0ae81 100644
--- a/src/flash/nor/non_cfi.c
+++ b/src/flash/nor/non_cfi.c
@@ -15,9 +15,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -540,7 +538,6 @@ void cfi_fixup_non_cfi(struct flash_bank *bank)
pri_ext->SiliconRevision = 0x0;
pri_ext->EraseSuspend = 0x0;
- pri_ext->EraseSuspend = 0x0;
pri_ext->BlkProt = 0x0;
pri_ext->TmpBlkUnprotect = 0x0;
pri_ext->BlkProtUnprot = 0x0;
diff --git a/src/flash/nor/non_cfi.h b/src/flash/nor/non_cfi.h
index e23ab7edd..c411cb885 100644
--- a/src/flash/nor/non_cfi.h
+++ b/src/flash/nor/non_cfi.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef NON_CFI_H
-#define NON_CFI_H
+#ifndef OPENOCD_FLASH_NOR_NON_CFI_H
+#define OPENOCD_FLASH_NOR_NON_CFI_H
struct non_cfi {
uint16_t mfr;
@@ -35,4 +33,4 @@ struct non_cfi {
void cfi_fixup_non_cfi(struct flash_bank *bank);
-#endif /* NON_CFI_H */
+#endif /* OPENOCD_FLASH_NOR_NON_CFI_H */
diff --git a/src/flash/nor/nrf51.c b/src/flash/nor/nrf51.c
index d8706c849..7b7acf479 100644
--- a/src/flash/nor/nrf51.c
+++ b/src/flash/nor/nrf51.c
@@ -15,9 +15,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -110,7 +108,6 @@ enum nrf51_nvmc_config_bits {
struct nrf51_info {
uint32_t code_page_size;
- uint32_t code_memory_size;
struct {
bool probed;
@@ -123,6 +120,7 @@ struct nrf51_info {
struct nrf51_device_spec {
uint16_t hwid;
+ const char *part;
const char *variant;
const char *build_code;
unsigned int flash_size_kb;
@@ -144,30 +142,35 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = {
/* nRF51822 Devices (IC rev 1). */
{
.hwid = 0x001D,
+ .part = "51822",
.variant = "QFAA",
.build_code = "CA/C0",
.flash_size_kb = 256,
},
{
.hwid = 0x0026,
+ .part = "51822",
.variant = "QFAB",
.build_code = "AA",
.flash_size_kb = 128,
},
{
.hwid = 0x0027,
+ .part = "51822",
.variant = "QFAB",
.build_code = "A0",
.flash_size_kb = 128,
},
{
.hwid = 0x0020,
+ .part = "51822",
.variant = "CEAA",
.build_code = "BA",
.flash_size_kb = 256,
},
{
.hwid = 0x002F,
+ .part = "51822",
.variant = "CEAA",
.build_code = "B0",
.flash_size_kb = 256,
@@ -176,42 +179,63 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = {
/* nRF51822 Devices (IC rev 2). */
{
.hwid = 0x002A,
+ .part = "51822",
.variant = "QFAA",
.build_code = "FA0",
.flash_size_kb = 256,
},
{
.hwid = 0x0044,
+ .part = "51822",
.variant = "QFAA",
.build_code = "GC0",
.flash_size_kb = 256,
},
{
.hwid = 0x003C,
+ .part = "51822",
.variant = "QFAA",
.build_code = "G0",
.flash_size_kb = 256,
},
+ {
+ .hwid = 0x0057,
+ .part = "51822",
+ .variant = "QFAA",
+ .build_code = "G2",
+ .flash_size_kb = 256,
+ },
+ {
+ .hwid = 0x0058,
+ .part = "51822",
+ .variant = "QFAA",
+ .build_code = "G3",
+ .flash_size_kb = 256,
+ },
{
.hwid = 0x004C,
+ .part = "51822",
.variant = "QFAB",
.build_code = "B0",
.flash_size_kb = 128,
},
{
.hwid = 0x0040,
+ .part = "51822",
.variant = "CEAA",
.build_code = "CA0",
.flash_size_kb = 256,
},
{
.hwid = 0x0047,
+ .part = "51822",
.variant = "CEAA",
.build_code = "DA0",
.flash_size_kb = 256,
},
{
.hwid = 0x004D,
+ .part = "51822",
.variant = "CEAA",
.build_code = "D00",
.flash_size_kb = 256,
@@ -220,56 +244,79 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = {
/* nRF51822 Devices (IC rev 3). */
{
.hwid = 0x0072,
+ .part = "51822",
.variant = "QFAA",
.build_code = "H0",
.flash_size_kb = 256,
},
{
.hwid = 0x007B,
+ .part = "51822",
.variant = "QFAB",
.build_code = "C0",
.flash_size_kb = 128,
},
{
.hwid = 0x0083,
+ .part = "51822",
.variant = "QFAC",
.build_code = "A0",
.flash_size_kb = 256,
},
+ {
+ .hwid = 0x0084,
+ .part = "51822",
+ .variant = "QFAC",
+ .build_code = "A1",
+ .flash_size_kb = 256,
+ },
{
.hwid = 0x007D,
+ .part = "51822",
.variant = "CDAB",
.build_code = "A0",
.flash_size_kb = 128,
},
{
.hwid = 0x0079,
+ .part = "51822",
.variant = "CEAA",
.build_code = "E0",
.flash_size_kb = 256,
},
{
.hwid = 0x0087,
+ .part = "51822",
.variant = "CFAC",
.build_code = "A0",
.flash_size_kb = 256,
},
+ {
+ .hwid = 0x008F,
+ .part = "51822",
+ .variant = "QFAA",
+ .build_code = "H1",
+ .flash_size_kb = 256,
+ },
/* nRF51422 Devices (IC rev 1). */
{
.hwid = 0x001E,
+ .part = "51422",
.variant = "QFAA",
.build_code = "CA",
.flash_size_kb = 256,
},
{
.hwid = 0x0024,
+ .part = "51422",
.variant = "QFAA",
.build_code = "C0",
.flash_size_kb = 256,
},
{
.hwid = 0x0031,
+ .part = "51422",
.variant = "CEAA",
.build_code = "A0A",
.flash_size_kb = 256,
@@ -278,24 +325,28 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = {
/* nRF51422 Devices (IC rev 2). */
{
.hwid = 0x002D,
+ .part = "51422",
.variant = "QFAA",
.build_code = "DAA",
.flash_size_kb = 256,
},
{
.hwid = 0x002E,
+ .part = "51422",
.variant = "QFAA",
.build_code = "E0",
.flash_size_kb = 256,
},
{
.hwid = 0x0061,
+ .part = "51422",
.variant = "QFAB",
.build_code = "A00",
.flash_size_kb = 128,
},
{
.hwid = 0x0050,
+ .part = "51422",
.variant = "CEAA",
.build_code = "B0",
.flash_size_kb = 256,
@@ -304,48 +355,49 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = {
/* nRF51422 Devices (IC rev 3). */
{
.hwid = 0x0073,
+ .part = "51422",
.variant = "QFAA",
.build_code = "F0",
.flash_size_kb = 256,
},
{
.hwid = 0x007C,
+ .part = "51422",
.variant = "QFAB",
.build_code = "B0",
.flash_size_kb = 128,
},
- {
- .hwid = 0x0084,
- .variant = "QFAC",
- .build_code = "A1",
- .flash_size_kb = 256,
- },
{
.hwid = 0x0085,
+ .part = "51422",
.variant = "QFAC",
.build_code = "A0",
.flash_size_kb = 256,
},
{
.hwid = 0x0086,
+ .part = "51422",
.variant = "QFAC",
.build_code = "A1",
.flash_size_kb = 256,
},
{
.hwid = 0x007E,
+ .part = "51422",
.variant = "CDAB",
.build_code = "A0",
.flash_size_kb = 128,
},
{
.hwid = 0x007A,
+ .part = "51422",
.variant = "CEAA",
.build_code = "C0",
.flash_size_kb = 256,
},
{
.hwid = 0x0088,
+ .part = "51422",
.variant = "CFAC",
.build_code = "A0",
.flash_size_kb = 256,
@@ -356,6 +408,7 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = {
in the nRF51 Series Compatibility Matrix V1.0. */
{
.hwid = 0x0071,
+ .part = "51822",
.variant = "QFAC",
.build_code = "AB",
.flash_size_kb = 256,
@@ -575,7 +628,7 @@ static int nrf51_protect(struct flash_bank *bank, int set, int first, int last)
if ((ppfc & 0xFF) == 0x00) {
LOG_ERROR("Code region 0 size was pre-programmed at the factory, can't change flash protection settings");
return ERROR_FAIL;
- };
+ }
res = target_read_u32(chip->target, NRF51_UICR_CLENR0,
&clenr0);
@@ -617,43 +670,46 @@ static int nrf51_probe(struct flash_bank *bank)
* bytes of the CONFIGID register */
const struct nrf51_device_spec *spec = NULL;
- for (size_t i = 0; i < ARRAY_SIZE(nrf51_known_devices_table); i++)
+ for (size_t i = 0; i < ARRAY_SIZE(nrf51_known_devices_table); i++) {
if (hwid == nrf51_known_devices_table[i].hwid) {
spec = &nrf51_known_devices_table[i];
break;
}
+ }
if (!chip->bank[0].probed && !chip->bank[1].probed) {
if (spec)
- LOG_INFO("nRF51822-%s(build code: %s) %ukB Flash",
- spec->variant, spec->build_code, spec->flash_size_kb);
+ LOG_INFO("nRF%s-%s(build code: %s) %ukB Flash",
+ spec->part, spec->variant, spec->build_code,
+ spec->flash_size_kb);
else
LOG_WARNING("Unknown device (HWID 0x%08" PRIx32 ")", hwid);
}
-
if (bank->base == NRF51_FLASH_BASE) {
+ /* The value stored in NRF51_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */
res = target_read_u32(chip->target, NRF51_FICR_CODEPAGESIZE,
- &chip->code_page_size);
+ &chip->code_page_size);
if (res != ERROR_OK) {
LOG_ERROR("Couldn't read code page size");
return res;
}
- res = target_read_u32(chip->target, NRF51_FICR_CODESIZE,
- &chip->code_memory_size);
+ /* Note the register name is misleading,
+ * NRF51_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */
+ uint32_t num_sectors;
+ res = target_read_u32(chip->target, NRF51_FICR_CODESIZE, &num_sectors);
if (res != ERROR_OK) {
LOG_ERROR("Couldn't read code memory size");
return res;
}
- if (spec && chip->code_memory_size != spec->flash_size_kb) {
- LOG_ERROR("Chip's reported Flash capacity does not match expected one");
- return ERROR_FAIL;
- }
+ bank->num_sectors = num_sectors;
+ bank->size = num_sectors * chip->code_page_size;
+
+ if (spec && bank->size / 1024 != spec->flash_size_kb)
+ LOG_WARNING("Chip's reported Flash capacity does not match expected one");
- bank->size = chip->code_memory_size * 1024;
- bank->num_sectors = bank->size / chip->code_page_size;
bank->sectors = calloc(bank->num_sectors,
sizeof((bank->sectors)[0]));
if (!bank->sectors)
@@ -755,7 +811,7 @@ static int nrf51_erase_page(struct flash_bank *bank,
LOG_ERROR("The chip was not pre-programmed with SoftDevice stack and UICR cannot be erased separately. Please issue mass erase before trying to write to this region");
return ERROR_FAIL;
- };
+ }
res = nrf51_nvmc_generic_erase(chip,
NRF51_NVMC_ERASEUICR,
@@ -1136,7 +1192,7 @@ COMMAND_HANDLER(nrf51_handle_mass_erase_command)
LOG_ERROR("Code region 0 size was pre-programmed at the factory, "
"mass erase command won't work.");
return ERROR_FAIL;
- };
+ }
res = nrf51_erase_all(chip);
if (res != ERROR_OK) {
@@ -1262,7 +1318,7 @@ static int nrf51_info(struct flash_bank *bank, char *buf, int buf_size)
"reset value for XTALFREQ: %"PRIx32"\n"
"firmware id: 0x%04"PRIx32,
ficr[0].value,
- ficr[1].value,
+ (ficr[1].value * ficr[0].value) / 1024,
(ficr[2].value == 0xFFFFFFFF) ? 0 : ficr[2].value / 1024,
((ficr[3].value & 0xFF) == 0x00) ? "present" : "not present",
ficr[4].value,
diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c
index 8d8ed6ebb..992baa515 100644
--- a/src/flash/nor/numicro.c
+++ b/src/flash/nor/numicro.c
@@ -20,6 +20,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/ocl.c b/src/flash/nor/ocl.c
index c547d9a17..4ae565219 100644
--- a/src/flash/nor/ocl.c
+++ b/src/flash/nor/ocl.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/ocl.h b/src/flash/nor/ocl.h
index d056b46d5..3e83f76cf 100644
--- a/src/flash/nor/ocl.h
+++ b/src/flash/nor/ocl.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef OCL_H
-#define OCL_H
+#ifndef OPENOCD_FLASH_NOR_OCL_H
+#define OPENOCD_FLASH_NOR_OCL_H
/* command/response mask */
#define OCL_CMD_MASK 0xFFFF0000L
@@ -38,4 +36,4 @@
#define OCL_CHKS_INIT 0xC100CD0CL
-#endif /* OCL_H */
+#endif /* OPENOCD_FLASH_NOR_OCL_H */
diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c
index 5e82ba63d..1f148fd73 100644
--- a/src/flash/nor/pic32mx.c
+++ b/src/flash/nor/pic32mx.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -52,7 +50,7 @@
/* pic32mx configuration register locations */
-#define PIC32MX_DEVCFG0_1_2 0xBFC00BFC
+#define PIC32MX_DEVCFG0_1xx_2xx 0xBFC00BFC
#define PIC32MX_DEVCFG0 0xBFC02FFC
#define PIC32MX_DEVCFG1 0xBFC02FF8
#define PIC32MX_DEVCFG2 0xBFC02FF4
@@ -93,7 +91,8 @@
#define NVMKEY1 0xAA996655
#define NVMKEY2 0x556699AA
-#define MX_1_2 1 /* PIC32mx1xx/2xx */
+#define MX_1xx_2xx 1 /* PIC32mx1xx/2xx */
+#define MX_17x_27x 2 /* PIC32mx17x/27x */
struct pic32mx_flash_bank {
int probed;
@@ -101,7 +100,7 @@ struct pic32mx_flash_bank {
};
/*
- * DEVID values as per PIC32MX Flash Programming Specification Rev J
+ * DEVID values as per PIC32MX Flash Programming Specification Rev N
*/
static const struct pic32mx_devs_s {
@@ -120,6 +119,8 @@ static const struct pic32mx_devs_s {
{0x04D06053, "150F128B"},
{0x04D08053, "150F128C"},
{0x04D0A053, "150F128D"},
+ {0x06610053, "170F256B"},
+ {0x0661A053, "170F256D"},
{0x04A01053, "210F016B"},
{0x04A03053, "210F016C"},
{0x04A05053, "210F016D"},
@@ -132,6 +133,24 @@ static const struct pic32mx_devs_s {
{0x04D00053, "250F128B"},
{0x04D02053, "250F128C"},
{0x04D04053, "250F128D"},
+ {0x06600053, "270F256B"},
+ {0x0660A053, "270F256D"},
+ {0x05600053, "330F064H"},
+ {0x05601053, "330F064L"},
+ {0x05602053, "430F064H"},
+ {0x05603053, "430F064L"},
+ {0x0570C053, "350F128H"},
+ {0x0570D053, "350F128L"},
+ {0x0570E053, "450F128H"},
+ {0x0570F053, "450F128L"},
+ {0x05704053, "350F256H"},
+ {0x05705053, "350F256L"},
+ {0x05706053, "450F256H"},
+ {0x05707053, "450F256L"},
+ {0x05808053, "370F512H"},
+ {0x05809053, "370F512L"},
+ {0x0580A053, "470F512H"},
+ {0x0580B053, "470F512L"},
{0x00938053, "360F512L"},
{0x00934053, "360F256L"},
{0x0092D053, "340F128L"},
@@ -260,10 +279,15 @@ static int pic32mx_protect_check(struct flash_bank *bank)
return ERROR_TARGET_NOT_HALTED;
}
- if (pic32mx_info->dev_type == MX_1_2)
- config0_address = PIC32MX_DEVCFG0_1_2;
- else
+ switch (pic32mx_info->dev_type) {
+ case MX_1xx_2xx:
+ case MX_17x_27x:
+ config0_address = PIC32MX_DEVCFG0_1xx_2xx;
+ break;
+ default:
config0_address = PIC32MX_DEVCFG0;
+ break;
+ }
target_read_u32(target, config0_address, &devcfg0);
@@ -276,10 +300,17 @@ static int pic32mx_protect_check(struct flash_bank *bank)
num_pages = 0xffff; /* All pages protected */
} else {
/* pgm flash */
- if (pic32mx_info->dev_type == MX_1_2)
- num_pages = (~devcfg0 >> 10) & 0x3f;
- else
+ switch (pic32mx_info->dev_type) {
+ case MX_1xx_2xx:
+ num_pages = (~devcfg0 >> 10) & 0x7f;
+ break;
+ case MX_17x_27x:
+ num_pages = (~devcfg0 >> 10) & 0x1ff;
+ break;
+ default:
num_pages = (~devcfg0 >> 12) & 0xff;
+ break;
+ }
}
for (s = 0; s < bank->num_sectors && s < num_pages; s++)
@@ -430,23 +461,27 @@ static int pic32mx_write_block(struct flash_bank *bank, const uint8_t *buffer,
&write_algorithm) != ERROR_OK) {
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
/* Change values for counters and row size, depending on variant */
- if (pic32mx_info->dev_type == MX_1_2) {
+ switch (pic32mx_info->dev_type) {
+ case MX_1xx_2xx:
+ case MX_17x_27x:
/* 128 byte row */
pic32mx_flash_write_code[8] = 0x2CD30020;
pic32mx_flash_write_code[14] = 0x24840080;
pic32mx_flash_write_code[15] = 0x24A50080;
pic32mx_flash_write_code[17] = 0x24C6FFE0;
row_size = 128;
- } else {
+ break;
+ default:
/* 512 byte row */
pic32mx_flash_write_code[8] = 0x2CD30080;
pic32mx_flash_write_code[14] = 0x24840200;
pic32mx_flash_write_code[15] = 0x24A50200;
pic32mx_flash_write_code[17] = 0x24C6FF80;
row_size = 512;
+ break;
}
uint8_t code[sizeof(pic32mx_flash_write_code)];
@@ -472,9 +507,9 @@ static int pic32mx_write_block(struct flash_bank *bank, const uint8_t *buffer,
mips32_info.common_magic = MIPS32_COMMON_MAGIC;
mips32_info.isa_mode = MIPS32_ISA_MIPS32;
- init_reg_param(®_params[0], "a0", 32, PARAM_IN_OUT);
- init_reg_param(®_params[1], "a1", 32, PARAM_OUT);
- init_reg_param(®_params[2], "a2", 32, PARAM_OUT);
+ init_reg_param(®_params[0], "r4", 32, PARAM_IN_OUT);
+ init_reg_param(®_params[1], "r5", 32, PARAM_OUT);
+ init_reg_param(®_params[2], "r6", 32, PARAM_OUT);
int row_offset = offset % row_size;
uint8_t *new_buffer = NULL;
@@ -682,17 +717,21 @@ static int pic32mx_probe(struct flash_bank *bank)
/* Check for PIC32mx1xx/2xx */
for (i = 0; pic32mx_devs[i].name != NULL; i++) {
if (pic32mx_devs[i].devid == (device_id & 0x0fffffff)) {
- if ((*(pic32mx_devs[i].name) == '1') || (*(pic32mx_devs[i].name) == '2'))
- pic32mx_info->dev_type = MX_1_2;
+ if ((pic32mx_devs[i].name[0] == '1') || (pic32mx_devs[i].name[0] == '2'))
+ pic32mx_info->dev_type = (pic32mx_devs[i].name[1] == '7') ? MX_17x_27x : MX_1xx_2xx;
break;
}
}
- if (pic32mx_info->dev_type == MX_1_2)
+ switch (pic32mx_info->dev_type) {
+ case MX_1xx_2xx:
+ case MX_17x_27x:
page_size = 1024;
- else
+ break;
+ default:
page_size = 4096;
-
+ break;
+ }
if (Virt2Phys(bank->base) == PIC32MX_PHYS_BOOT_FLASH) {
/* 0x1FC00000: Boot flash size */
@@ -706,20 +745,29 @@ static int pic32mx_probe(struct flash_bank *bank)
}
#else
/* fixed 12k boot bank - see comments above */
- if (pic32mx_info->dev_type == MX_1_2)
+ switch (pic32mx_info->dev_type) {
+ case MX_1xx_2xx:
+ case MX_17x_27x:
num_pages = (3 * 1024);
- else
+ break;
+ default:
num_pages = (12 * 1024);
+ break;
+ }
#endif
} else {
/* read the flash size from the device */
if (target_read_u32(target, PIC32MX_BMXPFMSZ, &num_pages) != ERROR_OK) {
- if (pic32mx_info->dev_type == MX_1_2) {
+ switch (pic32mx_info->dev_type) {
+ case MX_1xx_2xx:
+ case MX_17x_27x:
LOG_WARNING("PIC32MX flash size failed, probe inaccurate - assuming 32k flash");
num_pages = (32 * 1024);
- } else {
+ break;
+ default:
LOG_WARNING("PIC32MX flash size failed, probe inaccurate - assuming 512k flash");
num_pages = (512 * 1024);
+ break;
}
}
}
@@ -831,7 +879,6 @@ COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
COMMAND_HANDLER(pic32mx_handle_unlock_command)
{
- uint32_t mchip_cmd;
struct target *target = NULL;
struct mips_m4k_common *mips_m4k;
struct mips_ejtag *ejtag_info;
@@ -856,7 +903,7 @@ COMMAND_HANDLER(pic32mx_handle_unlock_command)
mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);
/* first check status of device */
- mchip_cmd = MCHP_STATUS;
+ uint8_t mchip_cmd = MCHP_STATUS;
mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
if (mchip_cmd & (1 << 7)) {
/* device is not locked */
diff --git a/src/flash/nor/psoc4.c b/src/flash/nor/psoc4.c
index 72541d5dc..c7c85737c 100644
--- a/src/flash/nor/psoc4.c
+++ b/src/flash/nor/psoc4.c
@@ -20,6 +20,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -102,12 +105,12 @@ const struct psoc4_chip_details psoc4_devices[] = {
/* 4100 series */
{ 0x0410, "CY8C4124PVI-432", "SSOP-28", .flash_size_in_kb = 16 },
{ 0x0411, "CY8C4124PVI-442", "SSOP-28", .flash_size_in_kb = 16 },
- { 0x0416, "CY8C4124LQI-443", "QFN-40", .flash_size_in_kb = 16 },
+ { 0x041C, "CY8C4124LQI-443", "QFN-40", .flash_size_in_kb = 16 },
{ 0x041A, "CY8C4124AXI-443", "TQFP-44", .flash_size_in_kb = 16 },
{ 0x041B, "CY8C4125AXI-473", "TQFP-44", .flash_size_in_kb = 32 },
{ 0x0412, "CY8C4125PVI-482", "SSOP-28", .flash_size_in_kb = 32 },
{ 0x0417, "CY8C4125LQI-483", "QFN-40", .flash_size_in_kb = 32 },
- { 0x041C, "CY8C4125AXI-483", "TQFP-44", .flash_size_in_kb = 32 },
+ { 0x0416, "CY8C4125AXI-483", "TQFP-44", .flash_size_in_kb = 32 },
/* CCG1 series */
{ 0x0490, "CYPD1103-35FNXI", "CSP-35", .flash_size_in_kb = 32 },
@@ -221,7 +224,7 @@ static int psoc4_sysreq(struct target *target, uint8_t cmd, uint16_t cmd_param,
&sysreq_wait_algorithm) != ERROR_OK) {
LOG_DEBUG("no working area for sysreq code");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
/* Write the code */
retval = target_write_buffer(target,
diff --git a/src/flash/nor/sim3x.c b/src/flash/nor/sim3x.c
index df4e19c29..ce9a21ed5 100644
--- a/src/flash/nor/sim3x.c
+++ b/src/flash/nor/sim3x.c
@@ -14,6 +14,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -748,7 +751,7 @@ static int sim3x_read_info(struct flash_bank *bank)
}
if (((cpuid >> 4) & 0xfff) != 0xc23) {
- LOG_ERROR("Target is not CortexM3");
+ LOG_ERROR("Target is not Cortex-M3");
return ERROR_FAIL;
}
@@ -1009,7 +1012,7 @@ COMMAND_HANDLER(sim3x_lock)
return ret;
if ((val & CPUID_CHECK_VALUE_MASK) != CPUID_CHECK_VALUE) {
- LOG_ERROR("Target is not ARM CortexM3 or is already locked");
+ LOG_ERROR("Target is not ARM Cortex-M3 or is already locked");
return ERROR_FAIL;
}
} else {
diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c
index fdbdec484..ef7672d14 100644
--- a/src/flash/nor/spi.c
+++ b/src/flash/nor/spi.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -49,27 +47,31 @@ const struct flash_device flash_devices[] = {
FLASH_ID("sp s25fl004", 0xd8, 0xc7, 0x00120201, 0x100, 0x10000, 0x80000),
FLASH_ID("sp s25fl008", 0xd8, 0xc7, 0x00130201, 0x100, 0x10000, 0x100000),
FLASH_ID("sp s25fl016", 0xd8, 0xc7, 0x00140201, 0x100, 0x10000, 0x200000),
- FLASH_ID("sp s25fl116k", 0xd8, 0xC7, 0x00154001, 0x100, 0x10000, 0x200000),
+ FLASH_ID("sp s25fl116k", 0xd8, 0xc7, 0x00154001, 0x100, 0x10000, 0x200000),
FLASH_ID("sp s25fl032", 0xd8, 0xc7, 0x00150201, 0x100, 0x10000, 0x400000),
- FLASH_ID("sp s25fl132k", 0xd8, 0xC7, 0x00164001, 0x100, 0x10000, 0x400000),
+ FLASH_ID("sp s25fl132k", 0xd8, 0xc7, 0x00164001, 0x100, 0x10000, 0x400000),
FLASH_ID("sp s25fl064", 0xd8, 0xc7, 0x00160201, 0x100, 0x10000, 0x800000),
- FLASH_ID("sp s25fl164k", 0xd8, 0xC7, 0x00174001, 0x100, 0x10000, 0x800000),
- FLASH_ID("sp s25fl128", 0xd8, 0xC7, 0x00182001, 0x100, 0x10000, 0x1000000),
- FLASH_ID("sp s25fl256", 0xd8, 0xC7, 0x00190201, 0x100, 0x10000, 0x2000000),
+ FLASH_ID("sp s25fl164k", 0xd8, 0xc7, 0x00174001, 0x100, 0x10000, 0x800000),
+ FLASH_ID("sp s25fl128", 0xd8, 0xc7, 0x00182001, 0x100, 0x10000, 0x1000000),
+ FLASH_ID("sp s25fl256", 0xd8, 0xc7, 0x00190201, 0x100, 0x10000, 0x2000000),
FLASH_ID("atmel 25f512", 0x52, 0xc7, 0x0065001f, 0x80, 0x8000, 0x10000),
FLASH_ID("atmel 25f1024", 0x52, 0x62, 0x0060001f, 0x100, 0x8000, 0x20000),
FLASH_ID("atmel 25f2048", 0x52, 0x62, 0x0063001f, 0x100, 0x10000, 0x40000),
FLASH_ID("atmel 25f4096", 0x52, 0x62, 0x0064001f, 0x100, 0x10000, 0x80000),
FLASH_ID("atmel 25fs040", 0xd7, 0xc7, 0x0004661f, 0x100, 0x10000, 0x80000),
FLASH_ID("mac 25l512", 0xd8, 0xc7, 0x001020c2, 0x010, 0x10000, 0x10000),
- FLASH_ID("mac 25l1005", 0xd8, 0xd8, 0x001120c2, 0x010, 0x10000, 0x20000),
+ FLASH_ID("mac 25l1005", 0xd8, 0xc7, 0x001120c2, 0x010, 0x10000, 0x20000),
FLASH_ID("mac 25l2005", 0xd8, 0xc7, 0x001220c2, 0x010, 0x10000, 0x40000),
FLASH_ID("mac 25l4005", 0xd8, 0xc7, 0x001320c2, 0x010, 0x10000, 0x80000),
FLASH_ID("mac 25l8005", 0xd8, 0xc7, 0x001420c2, 0x010, 0x10000, 0x100000),
FLASH_ID("mac 25l1605", 0xd8, 0xc7, 0x001520c2, 0x100, 0x10000, 0x200000),
FLASH_ID("mac 25l3205", 0xd8, 0xc7, 0x001620c2, 0x100, 0x10000, 0x400000),
FLASH_ID("mac 25l6405", 0xd8, 0xc7, 0x001720c2, 0x100, 0x10000, 0x800000),
- FLASH_ID("mcr n25q064", 0xd8, 0xc7, 0x0017ba20, 0x100, 0x10000, 0x800000),
+ FLASH_ID("micron n25q064", 0xd8, 0xc7, 0x0017ba20, 0x100, 0x10000, 0x800000),
+ FLASH_ID("micron n25q128", 0xd8, 0xc7, 0x0018ba20, 0x100, 0x10000, 0x1000000),
+#if BUILD_RISCV == 1
+ FLASH_ID("issi is25lp128", 0xd8, 0xc7, 0x0018609d, 0x100, 0x10000, 0x1000000),
+#endif
FLASH_ID("win w25q80bv", 0xd8, 0xc7, 0x001440ef, 0x100, 0x10000, 0x100000),
FLASH_ID("win w25q32fv", 0xd8, 0xc7, 0x001640ef, 0x100, 0x10000, 0x400000),
FLASH_ID("win w25q32dw", 0xd8, 0xc7, 0x001660ef, 0x100, 0x10000, 0x400000),
@@ -79,6 +81,5 @@ const struct flash_device flash_devices[] = {
FLASH_ID("gd gd25q16c", 0xd8, 0xc7, 0x001540c8, 0x100, 0x10000, 0x200000),
FLASH_ID("gd gd25q32c", 0xd8, 0xc7, 0x001640c8, 0x100, 0x10000, 0x400000),
FLASH_ID("gd gd25q128c", 0xd8, 0xc7, 0x001840c8, 0x100, 0x10000, 0x1000000),
- FLASH_ID("micron n25q128", 0xd8, 0xc7, 0x0018ba20, 0x100, 0x10000, 0x1000000),
FLASH_ID(NULL, 0, 0, 0, 0, 0, 0)
};
diff --git a/src/flash/nor/spi.h b/src/flash/nor/spi.h
index 6e939b769..a1849983f 100644
--- a/src/flash/nor/spi.h
+++ b/src/flash/nor/spi.h
@@ -16,11 +16,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_FLASH_NOR_SPI_H
+#define OPENOCD_FLASH_NOR_SPI_H
+
/* data structure to maintain flash ids from different vendors */
struct flash_device {
char *name;
@@ -56,3 +57,5 @@ extern const struct flash_device flash_devices[];
#define SPIFLASH_PAGE_PROGRAM 0x02 /* Page Program */
#define SPIFLASH_FAST_READ 0x0B /* Fast Read */
#define SPIFLASH_READ 0x03 /* Normal Read */
+
+#endif /* OPENOCD_FLASH_NOR_SPI_H */
diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c
index 451f19b7b..d28ceee4b 100644
--- a/src/flash/nor/stellaris.c
+++ b/src/flash/nor/stellaris.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/***************************************************************************
@@ -602,7 +600,7 @@ static void stellaris_read_clock_info(struct flash_bank *bank)
LOG_DEBUG("Stellaris PLLCFG %" PRIx32 "", pllcfg);
stellaris_info->rcc = rcc;
- stellaris_info->rcc = rcc2;
+ stellaris_info->rcc2 = rcc2;
sysdiv = (rcc >> 23) & 0xF;
usesysdiv = (rcc >> 22) & 0x1;
@@ -1065,7 +1063,7 @@ static int stellaris_write_block(struct flash_bank *bank,
&write_algorithm) != ERROR_OK) {
LOG_DEBUG("no working area for block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
/* plus a buffer big enough for this data */
if (wcount * 4 < buffer_size)
@@ -1080,7 +1078,7 @@ static int stellaris_write_block(struct flash_bank *bank,
}
LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
target_name(target), (unsigned) buffer_size);
- };
+ }
target_write_buffer(target, write_algorithm->address,
sizeof(stellaris_write_code),
diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c
index 82f112ef7..d44670768 100644
--- a/src/flash/nor/stm32f1x.c
+++ b/src/flash/nor/stm32f1x.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -620,7 +618,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
&write_algorithm) != ERROR_OK) {
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
retval = target_write_buffer(target, write_algorithm->address,
sizeof(stm32x_flash_write_code), stm32x_flash_write_code);
@@ -639,7 +637,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- };
+ }
init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* count (halfword-16bit) */
diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c
index 89fc75dcf..4d750951c 100644
--- a/src/flash/nor/stm32f2x.c
+++ b/src/flash/nor/stm32f2x.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -65,9 +63,15 @@
* 1 MiByte STM32F42x/43x part with DB1M Option set:
* 4 x 16, 1 x 64, 3 x 128, 4 x 16, 1 x 64, 3 x 128.
*
- * STM32F7
+ * STM32F7[4|5]
* 1 MiByte part with 4 x 32, 1 x 128, 3 x 256.
*
+ * STM32F7[6|7]
+ * 1 MiByte part in single bank mode with 4 x 32, 1 x 128, 3 x 256.
+ * 1 MiByte part in dual-bank mode two banks with 4 x 16, 1 x 64, 3 x 128 each.
+ * 2 MiByte part in single-bank mode with 4 x 32, 1 x 128, 7 x 256.
+ * 2 MiByte part in dual-bank mode two banks with 4 x 16, 1 x 64, 7 x 128 each.
+ *
* Protection size is sector size.
*
* Tested with STM3220F-EVAL board.
@@ -86,6 +90,9 @@
* RM0385
* http://www.st.com/web/en/resource/technical/document/reference_manual/DM00124865.pdf
*
+ * RM0410
+ * http://www.st.com/resource/en/reference_manual/dm00224583.pdf
+ *
* STM32F1x series - notice that this code was copy, pasted and knocked
* into a stm32f2x driver, so in case something has been converted or
* bugs haven't been fixed, here are the original manuals:
@@ -103,6 +110,9 @@
#define FLASH_ERASE_TIMEOUT 10000
#define FLASH_WRITE_TIMEOUT 5
+/* Mass erase time can be as high as 32 s in x8 mode. */
+#define FLASH_MASS_ERASE_TIMEOUT 33000
+
#define STM32_FLASH_BASE 0x40023c00
#define STM32_FLASH_ACR 0x40023c00
#define STM32_FLASH_KEYR 0x40023c04
@@ -113,11 +123,10 @@
#define STM32_FLASH_OPTCR1 0x40023c18
/* FLASH_CR register bits */
-
#define FLASH_PG (1 << 0)
#define FLASH_SER (1 << 1)
-#define FLASH_MER (1 << 2)
-#define FLASH_MER1 (1 << 15)
+#define FLASH_MER (1 << 2) /* MER/MER1 for f76x/77x */
+#define FLASH_MER1 (1 << 15) /* MER2 for f76x/77x, confusing ... */
#define FLASH_STRT (1 << 16)
#define FLASH_PSIZE_8 (0 << 8)
#define FLASH_PSIZE_16 (1 << 8)
@@ -129,7 +138,6 @@
#define FLASH_LOCK (1 << 31)
/* FLASH_SR register bits */
-
#define FLASH_BSY (1 << 16)
#define FLASH_PGSERR (1 << 7) /* Programming sequence error */
#define FLASH_PGPERR (1 << 6) /* Programming parallelism error */
@@ -140,22 +148,12 @@
#define FLASH_ERROR (FLASH_PGSERR | FLASH_PGPERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_OPERR)
/* STM32_FLASH_OPTCR register bits */
-
-#define OPT_LOCK (1 << 0)
-#define OPT_START (1 << 1)
-
-/* STM32_FLASH_OBR bit definitions (reading) */
-
-#define OPT_ERROR 0
-#define OPT_READOUT 1
-#define OPT_RDWDGSW 2
-#define OPT_RDRSTSTOP 3
-#define OPT_RDRSTSTDBY 4
-#define OPT_BFB2 5 /* dual flash bank only */
-#define OPT_DB1M 14 /* 1 MiB devices dual flash bank option */
+#define OPTCR_LOCK (1 << 0)
+#define OPTCR_START (1 << 1)
+#define OPTCR_NDBANK (1 << 29) /* not dual bank mode */
+#define OPTCR_DB1M (1 << 30) /* 1 MiB devices dual flash bank option */
/* register unlock keys */
-
#define KEY1 0x45670123
#define KEY2 0xCDEF89AB
@@ -165,14 +163,17 @@
struct stm32x_options {
uint8_t RDP;
- uint8_t user_options;
+ uint16_t user_options; /* bit 0-7 usual options, bit 8-11 extra options */
uint32_t protection;
+ uint32_t boot_addr;
};
struct stm32x_flash_bank {
struct stm32x_options option_bytes;
int probed;
- bool has_large_mem; /* stm32f42x/stm32f43x family */
+ bool has_large_mem; /* F42x/43x/469/479/7xx in dual bank mode */
+ bool has_boot_addr; /* F7xx */
+ bool has_extra_options; /* F42x/43x/469/479/7xx */
uint32_t user_bank_size;
};
@@ -286,7 +287,7 @@ static int stm32x_unlock_option_reg(struct target *target)
if (retval != ERROR_OK)
return retval;
- if ((ctrl & OPT_LOCK) == 0)
+ if ((ctrl & OPTCR_LOCK) == 0)
return ERROR_OK;
/* unlock option registers */
@@ -302,7 +303,7 @@ static int stm32x_unlock_option_reg(struct target *target)
if (retval != ERROR_OK)
return retval;
- if (ctrl & OPT_LOCK) {
+ if (ctrl & OPTCR_LOCK) {
LOG_ERROR("options not unlocked STM32_FLASH_OPTCR: %" PRIx32, ctrl);
return ERROR_TARGET_FAILURE;
}
@@ -323,18 +324,30 @@ static int stm32x_read_options(struct flash_bank *bank)
if (retval != ERROR_OK)
return retval;
- stm32x_info->option_bytes.user_options = optiondata & 0xec;
+ /* caution: F2 implements 5 bits (WDG_SW only)
+ * whereas F7 6 bits (IWDG_SW and WWDG_SW) in user_options */
+ stm32x_info->option_bytes.user_options = optiondata & 0xfc;
stm32x_info->option_bytes.RDP = (optiondata >> 8) & 0xff;
stm32x_info->option_bytes.protection = (optiondata >> 16) & 0xfff;
- if (stm32x_info->has_large_mem) {
+ if (stm32x_info->has_extra_options) {
+ /* F42x/43x/469/479 and 7xx have up to 4 bits of extra options */
+ stm32x_info->option_bytes.user_options |= (optiondata >> 20) & 0xf00;
+ }
+ if (stm32x_info->has_large_mem || stm32x_info->has_boot_addr) {
retval = target_read_u32(target, STM32_FLASH_OPTCR1, &optiondata);
if (retval != ERROR_OK)
return retval;
- /* append protection bits */
- stm32x_info->option_bytes.protection |= (optiondata >> 4) & 0x00fff000;
+ /* FLASH_OPTCR1 has quite diffent meanings ... */
+ if (stm32x_info->has_boot_addr) {
+ /* for F7xx it contains boot0 and boot1 */
+ stm32x_info->option_bytes.boot_addr = optiondata;
+ } else {
+ /* for F42x/43x/469/479 it contains 12 additional protection bits */
+ stm32x_info->option_bytes.protection |= (optiondata >> 4) & 0x00fff000;
+ }
}
if (stm32x_info->option_bytes.RDP != 0xAA)
@@ -347,7 +360,7 @@ static int stm32x_write_options(struct flash_bank *bank)
{
struct stm32x_flash_bank *stm32x_info = NULL;
struct target *target = bank->target;
- uint32_t optiondata;
+ uint32_t optiondata, optiondata2;
stm32x_info = bank->driver_priv;
@@ -356,36 +369,46 @@ static int stm32x_write_options(struct flash_bank *bank)
return retval;
/* rebuild option data */
- optiondata = stm32x_info->option_bytes.user_options;
+ optiondata = stm32x_info->option_bytes.user_options & 0xfc;
optiondata |= stm32x_info->option_bytes.RDP << 8;
optiondata |= (stm32x_info->option_bytes.protection & 0x0fff) << 16;
- /* program options */
- retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata);
- if (retval != ERROR_OK)
- return retval;
+ if (stm32x_info->has_extra_options) {
+ /* F42x/43x/469/479 and 7xx have up to 4 bits of extra options */
+ optiondata |= (stm32x_info->option_bytes.user_options & 0xf00) << 20;
+ }
- if (stm32x_info->has_large_mem) {
+ if (stm32x_info->has_large_mem || stm32x_info->has_boot_addr) {
+ if (stm32x_info->has_boot_addr) {
+ /* F7xx uses FLASH_OPTCR1 for boot0 and boot1 ... */
+ optiondata2 = stm32x_info->option_bytes.boot_addr;
+ } else {
+ /* F42x/43x/469/479 uses FLASH_OPTCR1 for additional protection bits */
+ optiondata2 = (stm32x_info->option_bytes.protection & 0x00fff000) << 4;
+ }
- uint32_t optiondata2 = 0;
- optiondata2 |= (stm32x_info->option_bytes.protection & 0x00fff000) << 4;
retval = target_write_u32(target, STM32_FLASH_OPTCR1, optiondata2);
if (retval != ERROR_OK)
return retval;
}
+ /* program options */
+ retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata);
+ if (retval != ERROR_OK)
+ return retval;
+
/* start programming cycle */
- retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata | OPT_START);
+ retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata | OPTCR_START);
if (retval != ERROR_OK)
return retval;
- /* wait for completion */
- retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
+ /* wait for completion, this might trigger a security erase and take a while */
+ retval = stm32x_wait_status_busy(bank, FLASH_MASS_ERASE_TIMEOUT);
if (retval != ERROR_OK)
return retval;
/* relock registers */
- retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata | OPT_LOCK);
+ retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata | OPTCR_LOCK);
if (retval != ERROR_OK)
return retval;
@@ -403,11 +426,25 @@ static int stm32x_protect_check(struct flash_bank *bank)
return retval;
}
- for (int i = 0; i < bank->num_sectors; i++) {
- if (stm32x_info->option_bytes.protection & (1 << i))
- bank->sectors[i].is_protected = 0;
- else
- bank->sectors[i].is_protected = 1;
+ if (stm32x_info->has_boot_addr && stm32x_info->has_large_mem) {
+ /* F76x/77x: bit k protects sectors 2*k and 2*k+1 */
+ for (int i = 0; i < (bank->num_sectors >> 1); i++) {
+ if (stm32x_info->option_bytes.protection & (1 << i)) {
+ bank->sectors[i << 1].is_protected = 0;
+ bank->sectors[(i << 1) + 1].is_protected = 0;
+ } else {
+ bank->sectors[i << 1].is_protected = 1;
+ bank->sectors[(i << 1) + 1].is_protected = 1;
+ }
+ }
+ } else {
+ /* one protection bit per sector */
+ for (int i = 0; i < bank->num_sectors; i++) {
+ if (stm32x_info->option_bytes.protection & (1 << i))
+ bank->sectors[i].is_protected = 0;
+ else
+ bank->sectors[i].is_protected = 1;
+ }
}
return ERROR_OK;
@@ -418,8 +455,7 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last)
struct target *target = bank->target;
int i;
- assert(first < bank->num_sectors);
- assert(last < bank->num_sectors);
+ assert((0 <= first) && (first <= last) && (last < bank->num_sectors));
if (bank->target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
@@ -479,8 +515,18 @@ static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
return retval;
}
- for (int i = first; i <= last; i++) {
+ if (stm32x_info->has_boot_addr && stm32x_info->has_large_mem) {
+ /* F76x/77x: bit k protects sectors 2*k and 2*k+1 */
+ if ((first & 1) != 0 || (last & 1) != 1) {
+ LOG_ERROR("sector protection must be double sector aligned");
+ return ERROR_FAIL;
+ } else {
+ first >>= 1;
+ last >>= 1;
+ }
+ }
+ for (int i = first; i <= last; i++) {
if (set)
stm32x_info->option_bytes.protection &= ~(1 << i);
else
@@ -551,7 +597,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
&write_algorithm) != ERROR_OK) {
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
retval = target_write_buffer(target, write_algorithm->address,
sizeof(stm32x_flash_write_code),
@@ -570,7 +616,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- };
+ }
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
armv7m_info.core_mode = ARM_MODE_THREAD;
@@ -721,14 +767,31 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,
return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
}
-static void setup_sector(struct flash_bank *bank, int start, int num, int size)
+static int setup_sector(struct flash_bank *bank, int start, int num, int size)
{
+
for (int i = start; i < (start + num) ; i++) {
assert(i < bank->num_sectors);
bank->sectors[i].offset = bank->size;
bank->sectors[i].size = size;
bank->size += bank->sectors[i].size;
+ LOG_DEBUG("sector %d: %dkBytes", i, size >> 10);
}
+
+ return start + num;
+}
+
+static void setup_bank(struct flash_bank *bank, int start,
+ uint16_t flash_size_in_kb, uint16_t max_sector_size_in_kb)
+{
+ int remain;
+
+ start = setup_sector(bank, start, 4, (max_sector_size_in_kb / 8) * 1024);
+ start = setup_sector(bank, start, 1, (max_sector_size_in_kb / 2) * 1024);
+
+ /* remaining sectors all of size max_sector_size_in_kb */
+ remain = (flash_size_in_kb / max_sector_size_in_kb) - 1;
+ start = setup_sector(bank, start, remain, max_sector_size_in_kb * 1024);
}
static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id)
@@ -776,6 +839,8 @@ static int stm32x_probe(struct flash_bank *bank)
stm32x_info->probed = 0;
stm32x_info->has_large_mem = false;
+ stm32x_info->has_boot_addr = false;
+ stm32x_info->has_extra_options = false;
/* read stm32 device id register */
int retval = stm32x_get_device_id(bank, &device_id);
@@ -783,29 +848,50 @@ static int stm32x_probe(struct flash_bank *bank)
return retval;
LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
- /* set max flash size depending on family */
+ /* set max flash size depending on family, id taken from AN2606 */
switch (device_id & 0xfff) {
- case 0x411:
- case 0x413:
+ case 0x411: /* F20x/21x */
+ case 0x413: /* F40x/41x */
max_flash_size_in_kb = 1024;
break;
- case 0x419:
- case 0x434:
+
+ case 0x419: /* F42x/43x */
+ case 0x434: /* F469/479 */
+ stm32x_info->has_extra_options = true;
max_flash_size_in_kb = 2048;
break;
- case 0x423:
+
+ case 0x423: /* F401xB/C */
max_flash_size_in_kb = 256;
break;
- case 0x431:
- case 0x433:
- case 0x421:
+
+ case 0x421: /* F446 */
+ case 0x431: /* F411 */
+ case 0x433: /* F401xD/E */
+ case 0x441: /* F412 */
max_flash_size_in_kb = 512;
break;
- case 0x449:
+
+ case 0x458: /* F410 */
+ max_flash_size_in_kb = 128;
+ break;
+
+ case 0x449: /* F74x/75x */
max_flash_size_in_kb = 1024;
max_sector_size_in_kb = 256;
flash_size_reg = 0x1FF0F442;
+ stm32x_info->has_extra_options = true;
+ stm32x_info->has_boot_addr = true;
break;
+
+ case 0x451: /* F76x/77x */
+ max_flash_size_in_kb = 2048;
+ max_sector_size_in_kb = 256;
+ flash_size_reg = 0x1FF0F442;
+ stm32x_info->has_extra_options = true;
+ stm32x_info->has_boot_addr = true;
+ break;
+
default:
LOG_WARNING("Cannot identify target as a STM32 family.");
return ERROR_FAIL;
@@ -834,33 +920,48 @@ static int stm32x_probe(struct flash_bank *bank)
/* did we assign flash size? */
assert(flash_size_in_kb != 0xffff);
- /* calculate numbers of pages */
- int num_pages = (flash_size_in_kb / max_sector_size_in_kb) + 4;
-
/* Devices with > 1024 kiByte always are dual-banked */
if (flash_size_in_kb > 1024)
stm32x_info->has_large_mem = true;
- /* F42x/43x 1024 kiByte devices have a dual bank option */
- if ((device_id & 0xfff) == 0x419 && (flash_size_in_kb == 1024)) {
+ /* F42x/43x/469/479 1024 kiByte devices have a dual bank option */
+ if ((device_id & 0xfff) == 0x419 || (device_id & 0xfff) == 0x434) {
uint32_t optiondata;
retval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);
if (retval != ERROR_OK) {
LOG_DEBUG("unable to read option bytes");
return retval;
}
- if (optiondata & (1 << OPT_DB1M)) {
+ if ((flash_size_in_kb > 1024) || (optiondata & OPTCR_DB1M)) {
stm32x_info->has_large_mem = true;
- LOG_INFO("Dual Bank 1024 kiB STM32F42x/43x found");
+ LOG_INFO("Dual Bank %d kiB STM32F42x/43x/469/479 found", flash_size_in_kb);
+ } else {
+ stm32x_info->has_large_mem = false;
+ LOG_INFO("Single Bank %d kiB STM32F42x/43x/469/479 found", flash_size_in_kb);
}
}
- /* check for dual-banked devices */
- if (stm32x_info->has_large_mem)
- num_pages += 4;
+ /* F76x/77x devices have a dual bank option */
+ if ((device_id & 0xfff) == 0x451) {
+ uint32_t optiondata;
+ retval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);
+ if (retval != ERROR_OK) {
+ LOG_DEBUG("unable to read option bytes");
+ return retval;
+ }
+ if (optiondata & OPTCR_NDBANK) {
+ stm32x_info->has_large_mem = false;
+ LOG_INFO("Single Bank %d kiB STM32F76x/77x found", flash_size_in_kb);
+ } else {
+ stm32x_info->has_large_mem = true;
+ max_sector_size_in_kb >>= 1; /* sector size divided by 2 in dual-bank mode */
+ LOG_INFO("Dual Bank %d kiB STM32F76x/77x found", flash_size_in_kb);
+ }
+ }
- /* check that calculation result makes sense */
- assert(num_pages > 0);
+ /* calculate numbers of pages */
+ int num_pages = flash_size_in_kb / max_sector_size_in_kb
+ + (stm32x_info->has_large_mem ? 8 : 4);
if (bank->sectors) {
free(bank->sectors);
@@ -870,35 +971,25 @@ static int stm32x_probe(struct flash_bank *bank)
bank->base = base_address;
bank->num_sectors = num_pages;
bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
+ for (i = 0; i < num_pages; i++) {
+ bank->sectors[i].is_erased = -1;
+ bank->sectors[i].is_protected = 0;
+ }
bank->size = 0;
-
- /* fixed memory */
- setup_sector(bank, 0, 4, (max_sector_size_in_kb / 8) * 1024);
- setup_sector(bank, 4, 1, (max_sector_size_in_kb / 2) * 1024);
+ LOG_DEBUG("allocated %d sectors", num_pages);
if (stm32x_info->has_large_mem) {
- if (flash_size_in_kb == 1024) {
- setup_sector(bank, 5, 3, 128 * 1024);
- setup_sector(bank, 12, 4, 16 * 1024);
- setup_sector(bank, 16, 1, 64 * 1024);
- setup_sector(bank, 17, 3, 128 * 1024);
- } else {
- setup_sector(bank, 5, 7, 128 * 1024);
- setup_sector(bank, 12, 4, 16 * 1024);
- setup_sector(bank, 16, 1, 64 * 1024);
- setup_sector(bank, 17, 7, 128 * 1024);
- }
+ /* dual-bank */
+ setup_bank(bank, 0, flash_size_in_kb >> 1, max_sector_size_in_kb);
+ setup_bank(bank, num_pages >> 1, flash_size_in_kb >> 1,
+ max_sector_size_in_kb);
} else {
- setup_sector(bank, 4 + 1, MIN(12, num_pages) - 5,
- max_sector_size_in_kb * 1024);
- }
- for (i = 0; i < num_pages; i++) {
- bank->sectors[i].is_erased = -1;
- bank->sectors[i].is_protected = 0;
+ /* single-bank */
+ setup_bank(bank, 0, flash_size_in_kb, max_sector_size_in_kb);
}
+ assert((bank->size >> 10) == flash_size_in_kb);
stm32x_info->probed = 1;
-
return ERROR_OK;
}
@@ -948,6 +1039,18 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
case 0x2003:
rev_str = "X";
break;
+
+ case 0x2007:
+ rev_str = "1";
+ break;
+
+ case 0x200F:
+ rev_str = "V";
+ break;
+
+ case 0x201F:
+ rev_str = "2";
+ break;
}
break;
@@ -978,6 +1081,7 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
break;
}
break;
+
case 0x421:
device_str = "STM32F446";
@@ -987,9 +1091,12 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
break;
}
break;
+
case 0x423:
case 0x431:
case 0x433:
+ case 0x458:
+ case 0x441:
device_str = "STM32F4xx (Low Power)";
switch (rev_id) {
@@ -1017,6 +1124,16 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
}
break;
+ case 0x451:
+ device_str = "STM32F7[6|7]x";
+
+ switch (rev_id) {
+ case 0x1000:
+ rev_str = "A";
+ break;
+ }
+ break;
+
default:
snprintf(buf, buf_size, "Cannot identify target as a STM32F2/4/7\n");
return ERROR_FAIL;
@@ -1114,6 +1231,7 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
static int stm32x_mass_erase(struct flash_bank *bank)
{
int retval;
+ uint32_t flash_mer;
struct target *target = bank->target;
struct stm32x_flash_bank *stm32x_info = NULL;
@@ -1130,17 +1248,19 @@ static int stm32x_mass_erase(struct flash_bank *bank)
/* mass erase flash memory */
if (stm32x_info->has_large_mem)
- retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_MER | FLASH_MER1);
+ flash_mer = FLASH_MER | FLASH_MER1;
else
- retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_MER);
+ flash_mer = FLASH_MER;
+
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), flash_mer);
if (retval != ERROR_OK)
return retval;
retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
- FLASH_MER | FLASH_STRT);
+ flash_mer | FLASH_STRT);
if (retval != ERROR_OK)
return retval;
- retval = stm32x_wait_status_busy(bank, 30000);
+ retval = stm32x_wait_status_busy(bank, FLASH_MASS_ERASE_TIMEOUT);
if (retval != ERROR_OK)
return retval;
@@ -1179,6 +1299,107 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command)
return retval;
}
+COMMAND_HANDLER(stm32f2x_handle_options_read_command)
+{
+ int retval;
+ struct flash_bank *bank;
+ struct stm32x_flash_bank *stm32x_info = NULL;
+
+ if (CMD_ARGC != 1) {
+ command_print(CMD_CTX, "stm32f2x options_read ");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ retval = stm32x_read_options(bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ stm32x_info = bank->driver_priv;
+ if (stm32x_info->has_extra_options) {
+ if (stm32x_info->has_boot_addr) {
+ uint32_t boot_addr = stm32x_info->option_bytes.boot_addr;
+
+ command_print(CMD_CTX, "stm32f2x user_options 0x%03X,"
+ " boot_add0 0x%04X, boot_add1 0x%04X",
+ stm32x_info->option_bytes.user_options,
+ boot_addr & 0xffff, (boot_addr & 0xffff0000) >> 16);
+ } else {
+ command_print(CMD_CTX, "stm32f2x user_options 0x%03X,",
+ stm32x_info->option_bytes.user_options);
+ }
+ } else {
+ command_print(CMD_CTX, "stm32f2x user_options 0x%02X",
+ stm32x_info->option_bytes.user_options);
+
+ }
+
+ return retval;
+}
+
+COMMAND_HANDLER(stm32f2x_handle_options_write_command)
+{
+ int retval;
+ struct flash_bank *bank;
+ struct stm32x_flash_bank *stm32x_info = NULL;
+ uint16_t user_options, boot_addr0, boot_addr1;
+
+ if (CMD_ARGC < 1) {
+ command_print(CMD_CTX, "stm32f2x options_write ...");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ retval = stm32x_read_options(bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ stm32x_info = bank->driver_priv;
+ if (stm32x_info->has_boot_addr) {
+ if (CMD_ARGC != 4) {
+ command_print(CMD_CTX, "stm32f2x options_write "
+ " ");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[2], boot_addr0);
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[3], boot_addr1);
+ stm32x_info->option_bytes.boot_addr = boot_addr0 | (((uint32_t) boot_addr1) << 16);
+ } else {
+ if (CMD_ARGC != 2) {
+ command_print(CMD_CTX, "stm32f2x options_write ");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ }
+
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], user_options);
+ if (user_options & (stm32x_info->has_extra_options ? ~0xffc : ~0xfc)) {
+ command_print(CMD_CTX, "stm32f2x invalid user_options");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ stm32x_info->option_bytes.user_options = user_options;
+
+ if (stm32x_write_options(bank) != ERROR_OK) {
+ command_print(CMD_CTX, "stm32f2x failed to write options");
+ return ERROR_OK;
+ }
+
+ /* switching between single- and dual-bank modes requires re-probe */
+ /* ... and reprogramming of whole flash */
+ stm32x_info->probed = 0;
+
+ command_print(CMD_CTX, "stm32f2x write options complete.\n"
+ "INFO: a reset or power cycle is required "
+ "for the new settings to take effect.");
+ return retval;
+}
+
static const struct command_registration stm32x_exec_command_handlers[] = {
{
.name = "lock",
@@ -1201,6 +1422,20 @@ static const struct command_registration stm32x_exec_command_handlers[] = {
.usage = "bank_id",
.help = "Erase entire flash device.",
},
+ {
+ .name = "options_read",
+ .handler = stm32f2x_handle_options_read_command,
+ .mode = COMMAND_EXEC,
+ .usage = "bank_id",
+ .help = "Read and display device option bytes.",
+ },
+ {
+ .name = "options_write",
+ .handler = stm32f2x_handle_options_write_command,
+ .mode = COMMAND_EXEC,
+ .usage = "bank_id user_options [ boot_add0 boot_add1]",
+ .help = "Write option bytes",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index 6bdb51d60..fa0c48b4f 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -13,8 +13,7 @@
* GNU 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. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -28,18 +27,22 @@
/* STM32L4xxx series for reference.
*
- * RM0351
- * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00083560.pdf
+ * RM0351 (STM32L4x5/STM32L4x6)
+ * http://www.st.com/resource/en/reference_manual/dm00083560.pdf
*
- * STM32L476RG Datasheet (for erase timing)
- * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00108832.pdf
+ * RM0394 (STM32L43x/44x/45x/46x)
+ * http://www.st.com/resource/en/reference_manual/dm00151940.pdf
*
+ * STM32L476RG Datasheet (for erase timing)
+ * http://www.st.com/resource/en/datasheet/stm32l476rg.pdf
*
- * The device has normally two banks, but on 512 and 256 kiB devices an
- * option byte is available to map all sectors to the first bank.
+ * The RM0351 devices have normally two banks, but on 512 and 256 kiB devices
+ * an option byte is available to map all sectors to the first bank.
* Both STM32 banks are treated as one OpenOCD bank, as other STM32 devices
* handlers do!
*
+ * RM0394 devices have a single bank only.
+ *
*/
/* Erase time can be as high as 25ms, 10x this and assume it's toast... */
@@ -463,21 +466,21 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
*/
static const uint8_t stm32l4_flash_write_code[] = {
- 0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, 0x00, 0x0f, 0x22, 0xd0, 0x47, 0x68,
- 0xb8, 0xeb, 0x07, 0x06, 0x07, 0x2e, 0xf5, 0xd3, 0xdf, 0xf8, 0x3c, 0x60,
- 0x66, 0x61, 0x57, 0xf8, 0x04, 0x6b, 0x42, 0xf8, 0x04, 0x6b, 0x57, 0xf8,
- 0x04, 0x6b, 0x42, 0xf8, 0x04, 0x6b, 0xbf, 0xf3, 0x4f, 0x8f, 0x26, 0x69,
- 0x16, 0xf4, 0x80, 0x3f, 0xfb, 0xd1, 0x16, 0xf0, 0xfa, 0x0f, 0x07, 0xd1,
- 0x8f, 0x42, 0x28, 0xbf, 0x00, 0xf1, 0x08, 0x07, 0x47, 0x60, 0x01, 0x3b,
- 0x13, 0xb1, 0xd9, 0xe7, 0x00, 0x21, 0x41, 0x60, 0x30, 0x46, 0x00, 0xbe,
- 0x01, 0x00, 0x00, 0x00
+ 0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, 0x00, 0x0f, 0x21, 0xd0, 0x45, 0x68,
+ 0xb8, 0xeb, 0x05, 0x06, 0x44, 0xbf, 0x76, 0x18, 0x36, 0x1a, 0x08, 0x2e,
+ 0xf2, 0xd3, 0xdf, 0xf8, 0x36, 0x60, 0x66, 0x61, 0xf5, 0xe8, 0x02, 0x67,
+ 0xe2, 0xe8, 0x02, 0x67, 0xbf, 0xf3, 0x4f, 0x8f, 0x26, 0x69, 0x16, 0xf4,
+ 0x80, 0x3f, 0xfb, 0xd1, 0x16, 0xf0, 0xfa, 0x0f, 0x07, 0xd1, 0x8d, 0x42,
+ 0x28, 0xbf, 0x00, 0xf1, 0x08, 0x05, 0x45, 0x60, 0x01, 0x3b, 0x13, 0xb1,
+ 0xda, 0xe7, 0x00, 0x21, 0x41, 0x60, 0x30, 0x46, 0x00, 0xbe, 0x01, 0x00,
+ 0x00, 0x00
};
if (target_alloc_working_area(target, sizeof(stm32l4_flash_write_code),
&write_algorithm) != ERROR_OK) {
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
retval = target_write_buffer(target, write_algorithm->address,
sizeof(stm32l4_flash_write_code),
@@ -497,7 +500,7 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- };
+ }
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
armv7m_info.core_mode = ARM_MODE_THREAD;
@@ -600,6 +603,7 @@ static int stm32l4_probe(struct flash_bank *bank)
struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;
int i;
uint16_t flash_size_in_kb = 0xffff;
+ uint16_t max_flash_size_in_kb;
uint32_t device_id;
uint32_t options;
uint32_t base_address = 0x08000000;
@@ -614,7 +618,15 @@ static int stm32l4_probe(struct flash_bank *bank)
/* set max flash size depending on family */
switch (device_id & 0xfff) {
+ case 0x461:
case 0x415:
+ max_flash_size_in_kb = 1024;
+ break;
+ case 0x462:
+ max_flash_size_in_kb = 512;
+ break;
+ case 0x435:
+ max_flash_size_in_kb = 256;
break;
default:
LOG_WARNING("Cannot identify target as a STM32L4 family.");
@@ -624,6 +636,19 @@ static int stm32l4_probe(struct flash_bank *bank)
/* get flash size from target. */
retval = target_read_u16(target, FLASH_SIZE_REG, &flash_size_in_kb);
+ /* failed reading flash size or flash size invalid (early silicon),
+ * default to max target family */
+ if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {
+ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming %dk flash",
+ max_flash_size_in_kb);
+ flash_size_in_kb = max_flash_size_in_kb;
+ }
+
+ LOG_INFO("flash size = %dkbytes", flash_size_in_kb);
+
+ /* did we assign flash size? */
+ assert(flash_size_in_kb != 0xffff);
+
/* get options to for DUAL BANK. */
retval = target_read_u32(target, STM32_FLASH_OPTR, &options);
@@ -633,8 +658,6 @@ static int stm32l4_probe(struct flash_bank *bank)
else
stm32l4_info->option_bytes.bank_b_start = flash_size_in_kb << 9;
- LOG_INFO("flash size = %dkbytes", flash_size_in_kb);
-
/* did we assign flash size? */
assert((flash_size_in_kb != 0xffff) && flash_size_in_kb);
@@ -686,7 +709,7 @@ static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size)
if (retval != ERROR_OK)
return retval;
- uint16_t device_id = dbgmcu_idcode & 0xffff;
+ uint16_t device_id = dbgmcu_idcode & 0xfff;
uint8_t rev_id = dbgmcu_idcode >> 28;
uint8_t rev_minor = 0;
int i;
@@ -701,8 +724,20 @@ static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size)
const char *device_str;
switch (device_id) {
- case 0x6415:
- device_str = "STM32L4xx";
+ case 0x461:
+ device_str = "STM32L496/4A6";
+ break;
+
+ case 0x415:
+ device_str = "STM32L475/476/486";
+ break;
+
+ case 0x462:
+ device_str = "STM32L45x/46x";
+ break;
+
+ case 0x435:
+ device_str = "STM32L43x/44x";
break;
default:
diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c
index 7b0b0cc1d..e4f499d3c 100644
--- a/src/flash/nor/stm32lx.c
+++ b/src/flash/nor/stm32lx.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -103,8 +101,11 @@ static int stm32lx_lock_program_memory(struct flash_bank *bank);
static int stm32lx_enable_write_half_page(struct flash_bank *bank);
static int stm32lx_erase_sector(struct flash_bank *bank, int sector);
static int stm32lx_wait_until_bsy_clear(struct flash_bank *bank);
+static int stm32lx_lock(struct flash_bank *bank);
+static int stm32lx_unlock(struct flash_bank *bank);
static int stm32lx_mass_erase(struct flash_bank *bank);
static int stm32lx_wait_until_bsy_clear_timeout(struct flash_bank *bank, int timeout);
+static int stm32lx_update_part_info(struct flash_bank *bank, uint16_t flash_size_in_kb);
struct stm32lx_rev {
uint16_t rev;
@@ -132,14 +133,17 @@ struct stm32lx_flash_bank {
uint32_t user_bank_size;
uint32_t flash_base;
- const struct stm32lx_part_info *part_info;
+ struct stm32lx_part_info part_info;
};
static const struct stm32lx_rev stm32_416_revs[] = {
{ 0x1000, "A" }, { 0x1008, "Y" }, { 0x1038, "W" }, { 0x1078, "V" },
};
static const struct stm32lx_rev stm32_417_revs[] = {
- { 0x1000, "A" }, { 0x1008, "Z" },
+ { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" }, { 0x1038, "X" }
+};
+static const struct stm32lx_rev stm32_425_revs[] = {
+ { 0x1000, "A" }, { 0x2000, "B" }, { 0x2008, "Y" },
};
static const struct stm32lx_rev stm32_427_revs[] = {
{ 0x1000, "A" }, { 0x1018, "Y" }, { 0x1038, "X" },
@@ -153,6 +157,12 @@ static const struct stm32lx_rev stm32_436_revs[] = {
static const struct stm32lx_rev stm32_437_revs[] = {
{ 0x1000, "A" },
};
+static const struct stm32lx_rev stm32_447_revs[] = {
+ { 0x1000, "A" }, { 0x2000, "B" }, { 0x2008, "Z" },
+};
+static const struct stm32lx_rev stm32_457_revs[] = {
+ { 0x1000, "A" }, { 0x1008, "Z" },
+};
static const struct stm32lx_part_info stm32lx_parts[] = {
{
@@ -171,7 +181,7 @@ static const struct stm32lx_part_info stm32lx_parts[] = {
.id = 0x417,
.revs = stm32_417_revs,
.num_revs = ARRAY_SIZE(stm32_417_revs),
- .device_str = "STM32L0xx",
+ .device_str = "STM32L0xx (Cat. 3)",
.page_size = 128,
.pages_per_sector = 32,
.max_flash_size_kb = 64,
@@ -179,6 +189,18 @@ static const struct stm32lx_part_info stm32lx_parts[] = {
.flash_base = 0x40022000,
.fsize_base = 0x1FF8007C,
},
+ {
+ .id = 0x425,
+ .revs = stm32_425_revs,
+ .num_revs = ARRAY_SIZE(stm32_425_revs),
+ .device_str = "STM32L0xx (Cat. 2)",
+ .page_size = 128,
+ .pages_per_sector = 32,
+ .max_flash_size_kb = 32,
+ .has_dual_banks = false,
+ .flash_base = 0x40022000,
+ .fsize_base = 0x1FF8007C,
+ },
{
.id = 0x427,
.revs = stm32_427_revs,
@@ -187,8 +209,7 @@ static const struct stm32lx_part_info stm32lx_parts[] = {
.page_size = 256,
.pages_per_sector = 16,
.max_flash_size_kb = 256,
- .first_bank_size_kb = 192,
- .has_dual_banks = true,
+ .has_dual_banks = false,
.flash_base = 0x40023C00,
.fsize_base = 0x1FF800CC,
},
@@ -225,11 +246,36 @@ static const struct stm32lx_part_info stm32lx_parts[] = {
.page_size = 256,
.pages_per_sector = 16,
.max_flash_size_kb = 512,
- .first_bank_size_kb = 256,
+ .first_bank_size_kb = 0, /* determined in runtime */
.has_dual_banks = true,
.flash_base = 0x40023C00,
.fsize_base = 0x1FF800CC,
},
+ {
+ .id = 0x447,
+ .revs = stm32_447_revs,
+ .num_revs = ARRAY_SIZE(stm32_447_revs),
+ .device_str = "STM32L0xx (Cat.5)",
+ .page_size = 128,
+ .pages_per_sector = 32,
+ .max_flash_size_kb = 192,
+ .first_bank_size_kb = 0, /* determined in runtime */
+ .has_dual_banks = false, /* determined in runtime */
+ .flash_base = 0x40022000,
+ .fsize_base = 0x1FF8007C,
+ },
+ {
+ .id = 0x457,
+ .revs = stm32_457_revs,
+ .num_revs = ARRAY_SIZE(stm32_457_revs),
+ .device_str = "STM32L0xx (Cat.1)",
+ .page_size = 128,
+ .pages_per_sector = 32,
+ .max_flash_size_kb = 16,
+ .has_dual_banks = false,
+ .flash_base = 0x40022000,
+ .fsize_base = 0x1FF8007C,
+ },
};
/* flash bank stm32lx 0 0
@@ -255,7 +301,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32lx_flash_bank_command)
stm32lx_info->user_bank_size = bank->size;
/* the stm32l erased value is 0x00 */
- bank->default_padded_value = 0x00;
+ bank->default_padded_value = bank->erased_value = 0x00;
return ERROR_OK;
}
@@ -286,6 +332,46 @@ COMMAND_HANDLER(stm32lx_handle_mass_erase_command)
return retval;
}
+COMMAND_HANDLER(stm32lx_handle_lock_command)
+{
+ if (CMD_ARGC < 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct flash_bank *bank;
+ int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ retval = stm32lx_lock(bank);
+
+ if (retval == ERROR_OK)
+ command_print(CMD_CTX, "STM32Lx locked, takes effect after power cycle.");
+ else
+ command_print(CMD_CTX, "STM32Lx lock failed");
+
+ return retval;
+}
+
+COMMAND_HANDLER(stm32lx_handle_unlock_command)
+{
+ if (CMD_ARGC < 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct flash_bank *bank;
+ int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ retval = stm32lx_unlock(bank);
+
+ if (retval == ERROR_OK)
+ command_print(CMD_CTX, "STM32Lx unlocked, takes effect after power cycle.");
+ else
+ command_print(CMD_CTX, "STM32Lx unlock failed");
+
+ return retval;
+}
+
static int stm32lx_protect_check(struct flash_bank *bank)
{
int retval;
@@ -351,7 +437,7 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
struct target *target = bank->target;
struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;
- uint32_t hp_nb = stm32lx_info->part_info->page_size / 2;
+ uint32_t hp_nb = stm32lx_info->part_info.page_size / 2;
uint32_t buffer_size = 16384;
struct working_area *write_algorithm;
struct working_area *source;
@@ -365,19 +451,7 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
/* see contib/loaders/flash/stm32lx.S for src */
static const uint8_t stm32lx_flash_write_code[] = {
- /* write_word: */
- 0x00, 0x23, /* movs r3, #0 */
- 0x04, 0xe0, /* b test_done */
-
- /* write_word: */
- 0x51, 0xf8, 0x04, 0xcb, /* ldr ip, [r1], #4 */
- 0x40, 0xf8, 0x04, 0xcb, /* str ip, [r0], #4 */
- 0x01, 0x33, /* adds r3, #1 */
-
- /* test_done: */
- 0x93, 0x42, /* cmp r3, r2 */
- 0xf8, 0xd3, /* bcc write_word */
- 0x00, 0xbe, /* bkpt 0 */
+ 0x92, 0x00, 0x8A, 0x18, 0x01, 0xE0, 0x08, 0xC9, 0x08, 0xC0, 0x91, 0x42, 0xFB, 0xD1, 0x00, 0xBE
};
/* Make sure we're performing a half-page aligned write. */
@@ -391,7 +465,7 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
&write_algorithm) != ERROR_OK) {
LOG_DEBUG("no working area for block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
/* Write the flashing code */
retval = target_write_buffer(target,
@@ -410,7 +484,7 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
else
buffer_size /= 2;
- if (buffer_size <= stm32lx_info->part_info->page_size) {
+ if (buffer_size <= stm32lx_info->part_info.page_size) {
/* we already allocated the writing code, but failed to get a
* buffer, free the algorithm */
target_free_working_area(target, write_algorithm);
@@ -503,7 +577,7 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
* is reduced by 50% using this slower method.
*/
- LOG_WARNING("couldn't use loader, falling back to page memory writes");
+ LOG_WARNING("Couldn't use loader, falling back to page memory writes");
while (count > 0) {
uint32_t this_count;
@@ -544,7 +618,7 @@ static int stm32lx_write(struct flash_bank *bank, const uint8_t *buffer,
struct target *target = bank->target;
struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;
- uint32_t hp_nb = stm32lx_info->part_info->page_size / 2;
+ uint32_t hp_nb = stm32lx_info->part_info.page_size / 2;
uint32_t halfpages_number;
uint32_t bytes_remaining = 0;
uint32_t address = bank->base + offset;
@@ -674,9 +748,9 @@ static int stm32lx_probe(struct flash_bank *bank)
uint32_t device_id;
uint32_t base_address = FLASH_BANK0_ADDRESS;
uint32_t second_bank_base;
+ unsigned int n;
stm32lx_info->probed = 0;
- stm32lx_info->part_info = NULL;
int retval = stm32lx_read_id_code(bank->target, &device_id);
if (retval != ERROR_OK)
@@ -686,20 +760,24 @@ static int stm32lx_probe(struct flash_bank *bank)
LOG_DEBUG("device id = 0x%08" PRIx32 "", device_id);
- for (unsigned int n = 0; n < ARRAY_SIZE(stm32lx_parts); n++) {
- if ((device_id & 0xfff) == stm32lx_parts[n].id)
- stm32lx_info->part_info = &stm32lx_parts[n];
+ for (n = 0; n < ARRAY_SIZE(stm32lx_parts); n++) {
+ if ((device_id & 0xfff) == stm32lx_parts[n].id) {
+ stm32lx_info->part_info = stm32lx_parts[n];
+ break;
+ }
}
- if (!stm32lx_info->part_info) {
+ if (n == ARRAY_SIZE(stm32lx_parts)) {
LOG_WARNING("Cannot identify target as a STM32L family.");
return ERROR_FAIL;
+ } else {
+ LOG_INFO("Device: %s", stm32lx_info->part_info.device_str);
}
- stm32lx_info->flash_base = stm32lx_info->part_info->flash_base;
+ stm32lx_info->flash_base = stm32lx_info->part_info.flash_base;
/* Get the flash size from target. */
- retval = target_read_u16(target, stm32lx_info->part_info->fsize_base,
+ retval = target_read_u16(target, stm32lx_info->part_info.fsize_base,
&flash_size_in_kb);
/* 0x436 devices report their flash size as a 0 or 1 code indicating 384K
@@ -716,29 +794,34 @@ static int stm32lx_probe(struct flash_bank *bank)
* default to max target family */
if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {
LOG_WARNING("STM32L flash size failed, probe inaccurate - assuming %dk flash",
- stm32lx_info->part_info->max_flash_size_kb);
- flash_size_in_kb = stm32lx_info->part_info->max_flash_size_kb;
- } else if (flash_size_in_kb > stm32lx_info->part_info->max_flash_size_kb) {
+ stm32lx_info->part_info.max_flash_size_kb);
+ flash_size_in_kb = stm32lx_info->part_info.max_flash_size_kb;
+ } else if (flash_size_in_kb > stm32lx_info->part_info.max_flash_size_kb) {
LOG_WARNING("STM32L probed flash size assumed incorrect since FLASH_SIZE=%dk > %dk, - assuming %dk flash",
- flash_size_in_kb, stm32lx_info->part_info->max_flash_size_kb,
- stm32lx_info->part_info->max_flash_size_kb);
- flash_size_in_kb = stm32lx_info->part_info->max_flash_size_kb;
+ flash_size_in_kb, stm32lx_info->part_info.max_flash_size_kb,
+ stm32lx_info->part_info.max_flash_size_kb);
+ flash_size_in_kb = stm32lx_info->part_info.max_flash_size_kb;
}
- if (stm32lx_info->part_info->has_dual_banks) {
+ /* Overwrite default dual-bank configuration */
+ retval = stm32lx_update_part_info(bank, flash_size_in_kb);
+ if (retval != ERROR_OK)
+ return ERROR_FAIL;
+
+ if (stm32lx_info->part_info.has_dual_banks) {
/* Use the configured base address to determine if this is the first or second flash bank.
* Verify that the base address is reasonably correct and determine the flash bank size
*/
second_bank_base = base_address +
- stm32lx_info->part_info->first_bank_size_kb * 1024;
+ stm32lx_info->part_info.first_bank_size_kb * 1024;
if (bank->base == second_bank_base || !bank->base) {
/* This is the second bank */
base_address = second_bank_base;
flash_size_in_kb = flash_size_in_kb -
- stm32lx_info->part_info->first_bank_size_kb;
+ stm32lx_info->part_info.first_bank_size_kb;
} else if (bank->base == base_address) {
/* This is the first bank */
- flash_size_in_kb = stm32lx_info->part_info->first_bank_size_kb;
+ flash_size_in_kb = stm32lx_info->part_info.first_bank_size_kb;
} else {
LOG_WARNING("STM32L flash bank base address config is incorrect."
" 0x%" PRIx32 " but should rather be 0x%" PRIx32 " or 0x%" PRIx32,
@@ -797,60 +880,13 @@ static int stm32lx_auto_probe(struct flash_bank *bank)
return stm32lx_probe(bank);
}
-static int stm32lx_erase_check(struct flash_bank *bank)
-{
- struct target *target = bank->target;
- const int buffer_size = 4096;
- int i;
- uint32_t nBytes;
- int retval = ERROR_OK;
-
- if (bank->target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- uint8_t *buffer = malloc(buffer_size);
- if (buffer == NULL) {
- LOG_ERROR("failed to allocate read buffer");
- return ERROR_FAIL;
- }
-
- for (i = 0; i < bank->num_sectors; i++) {
- uint32_t j;
- bank->sectors[i].is_erased = 1;
-
- /* Loop chunk by chunk over the sector */
- for (j = 0; j < bank->sectors[i].size; j += buffer_size) {
- uint32_t chunk;
- chunk = buffer_size;
- if (chunk > (j - bank->sectors[i].size))
- chunk = (j - bank->sectors[i].size);
-
- retval = target_read_memory(target, bank->base
- + bank->sectors[i].offset + j, 4, chunk / 4, buffer);
- if (retval != ERROR_OK)
- break;
-
- for (nBytes = 0; nBytes < chunk; nBytes++) {
- if (buffer[nBytes] != 0x00) {
- bank->sectors[i].is_erased = 0;
- break;
- }
- }
- }
- if (retval != ERROR_OK)
- break;
- }
- free(buffer);
-
- return retval;
-}
-
/* This method must return a string displaying information about the bank */
static int stm32lx_get_info(struct flash_bank *bank, char *buf, int buf_size)
{
struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;
+ const struct stm32lx_part_info *info = &stm32lx_info->part_info;
+ uint16_t rev_id = stm32lx_info->idcode >> 16;
+ const char *rev_str = NULL;
if (!stm32lx_info->probed) {
int retval = stm32lx_probe(bank);
@@ -861,32 +897,21 @@ static int stm32lx_get_info(struct flash_bank *bank, char *buf, int buf_size)
}
}
- const struct stm32lx_part_info *info = stm32lx_info->part_info;
-
- if (info) {
- const char *rev_str = NULL;
- uint16_t rev_id = stm32lx_info->idcode >> 16;
-
- for (unsigned int i = 0; i < info->num_revs; i++)
- if (rev_id == info->revs[i].rev)
- rev_str = info->revs[i].str;
+ for (unsigned int i = 0; i < info->num_revs; i++)
+ if (rev_id == info->revs[i].rev)
+ rev_str = info->revs[i].str;
- if (rev_str != NULL) {
- snprintf(buf, buf_size,
- "%s - Rev: %s",
- stm32lx_info->part_info->device_str, rev_str);
- } else {
- snprintf(buf, buf_size,
- "%s - Rev: unknown (0x%04x)",
- stm32lx_info->part_info->device_str, rev_id);
- }
-
- return ERROR_OK;
+ if (rev_str != NULL) {
+ snprintf(buf, buf_size,
+ "%s - Rev: %s",
+ info->device_str, rev_str);
} else {
- snprintf(buf, buf_size, "Cannot identify target as a STM32Lx");
-
- return ERROR_FAIL;
+ snprintf(buf, buf_size,
+ "%s - Rev: unknown (0x%04x)",
+ info->device_str, rev_id);
}
+
+ return ERROR_OK;
}
static const struct command_registration stm32lx_exec_command_handlers[] = {
@@ -897,6 +922,20 @@ static const struct command_registration stm32lx_exec_command_handlers[] = {
.usage = "bank_id",
.help = "Erase entire flash device. including available EEPROM",
},
+ {
+ .name = "lock",
+ .handler = stm32lx_handle_lock_command,
+ .mode = COMMAND_EXEC,
+ .usage = "bank_id",
+ .help = "Increase the readout protection to Level 1.",
+ },
+ {
+ .name = "unlock",
+ .handler = stm32lx_handle_unlock_command,
+ .mode = COMMAND_EXEC,
+ .usage = "bank_id",
+ .help = "Lower the readout protection from Level 1 to 0.",
+ },
COMMAND_REGISTRATION_DONE
};
@@ -921,7 +960,7 @@ struct flash_driver stm32lx_flash = {
.read = default_flash_read,
.probe = stm32lx_probe,
.auto_probe = stm32lx_auto_probe,
- .erase_check = stm32lx_erase_check,
+ .erase_check = default_flash_blank_check,
.protect_check = stm32lx_protect_check,
.info = stm32lx_get_info,
};
@@ -1081,7 +1120,7 @@ static int stm32lx_erase_sector(struct flash_bank *bank, int sector)
if (retval != ERROR_OK)
return retval;
- for (int page = 0; page < (int)stm32lx_info->part_info->pages_per_sector;
+ for (int page = 0; page < (int)stm32lx_info->part_info.pages_per_sector;
page++) {
reg32 = FLASH_PECR__PROG | FLASH_PECR__ERASE;
retval = target_write_u32(target,
@@ -1094,7 +1133,7 @@ static int stm32lx_erase_sector(struct flash_bank *bank, int sector)
return retval;
uint32_t addr = bank->base + bank->sectors[sector].offset + (page
- * stm32lx_info->part_info->page_size);
+ * stm32lx_info->part_info.page_size);
retval = target_write_u32(target, addr, 0x0);
if (retval != ERROR_OK)
return retval;
@@ -1230,33 +1269,37 @@ static int stm32lx_obl_launch(struct flash_bank *bank)
return tries ? ERROR_OK : ERROR_FAIL;
}
-static int stm32lx_mass_erase(struct flash_bank *bank)
+static int stm32lx_lock(struct flash_bank *bank)
{
int retval;
struct target *target = bank->target;
- struct stm32lx_flash_bank *stm32lx_info = NULL;
- uint32_t reg32;
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
- stm32lx_info = bank->driver_priv;
-
retval = stm32lx_unlock_options_bytes(bank);
if (retval != ERROR_OK)
return retval;
- /* mass erase flash memory */
/* set the RDP protection level to 1 */
retval = target_write_u32(target, OPTION_BYTES_ADDRESS, OPTION_BYTE_0_PR1);
if (retval != ERROR_OK)
return retval;
- retval = stm32lx_obl_launch(bank);
- if (retval != ERROR_OK)
- return retval;
+ return ERROR_OK;
+}
+
+static int stm32lx_unlock(struct flash_bank *bank)
+{
+ int retval;
+ struct target *target = bank->target;
+
+ if (target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
retval = stm32lx_unlock_options_bytes(bank);
if (retval != ERROR_OK)
@@ -1271,6 +1314,35 @@ static int stm32lx_mass_erase(struct flash_bank *bank)
if (retval != ERROR_OK)
return retval;
+ return ERROR_OK;
+}
+
+static int stm32lx_mass_erase(struct flash_bank *bank)
+{
+ int retval;
+ struct target *target = bank->target;
+ struct stm32lx_flash_bank *stm32lx_info = NULL;
+ uint32_t reg32;
+
+ if (target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ stm32lx_info = bank->driver_priv;
+
+ retval = stm32lx_lock(bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = stm32lx_obl_launch(bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = stm32lx_unlock(bank);
+ if (retval != ERROR_OK)
+ return retval;
+
retval = stm32lx_obl_launch(bank);
if (retval != ERROR_OK)
return retval;
@@ -1285,3 +1357,22 @@ static int stm32lx_mass_erase(struct flash_bank *bank)
return ERROR_OK;
}
+
+static int stm32lx_update_part_info(struct flash_bank *bank, uint16_t flash_size_in_kb)
+{
+ struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;
+
+ switch (stm32lx_info->part_info.id) {
+ case 0x447: /* STM32L0xx (Cat.5) devices */
+ if (flash_size_in_kb == 192 || flash_size_in_kb == 128) {
+ stm32lx_info->part_info.first_bank_size_kb = flash_size_in_kb / 2;
+ stm32lx_info->part_info.has_dual_banks = true;
+ }
+ break;
+ case 0x437: /* STM32L1xx (Cat.5/Cat.6) */
+ stm32lx_info->part_info.first_bank_size_kb = flash_size_in_kb / 2;
+ break;
+ }
+
+ return ERROR_OK;
+}
diff --git a/src/flash/nor/stmsmi.c b/src/flash/nor/stmsmi.c
index 6f73c3684..781ea3b5b 100644
--- a/src/flash/nor/stmsmi.c
+++ b/src/flash/nor/stmsmi.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* STM Serial Memory Interface (SMI) controller is a SPI bus controller
@@ -162,7 +160,7 @@ FLASH_BANK_COMMAND_HANDLER(stmsmi_flash_bank_command)
/* timeout in ms */
static int poll_tff(struct target *target, uint32_t io_base, int timeout)
{
- long long endtime;
+ int64_t endtime;
if (SMI_READ_REG(SMI_SR) & SMI_TFF)
return ERROR_OK;
@@ -213,7 +211,7 @@ static int wait_till_ready(struct flash_bank *bank, int timeout)
{
uint32_t status;
int retval;
- long long endtime;
+ int64_t endtime;
endtime = timeval_ms() + timeout;
do {
diff --git a/src/flash/nor/str7x.c b/src/flash/nor/str7x.c
index 515b97512..11179f520 100644
--- a/src/flash/nor/str7x.c
+++ b/src/flash/nor/str7x.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -487,7 +485,7 @@ static int str7x_write_block(struct flash_bank *bank, const uint8_t *buffer,
if (target_alloc_working_area_try(target, sizeof(str7x_flash_write_code),
&write_algorithm) != ERROR_OK) {
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
uint8_t code[sizeof(str7x_flash_write_code)];
target_buffer_set_u32_array(target, code, ARRAY_SIZE(str7x_flash_write_code),
diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c
index 8b3c13714..3b7ca2aa7 100644
--- a/src/flash/nor/str9x.c
+++ b/src/flash/nor/str9x.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -390,7 +388,7 @@ static int str9x_write_block(struct flash_bank *bank,
&write_algorithm) != ERROR_OK) {
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
uint8_t code[sizeof(str9x_flash_write_code)];
target_buffer_set_u32_array(target, code, ARRAY_SIZE(str9x_flash_write_code),
diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c
index f0af53a41..eb391e8fb 100644
--- a/src/flash/nor/str9xpec.c
+++ b/src/flash/nor/str9xpec.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c
index 8a30e1cd9..b93d12694 100644
--- a/src/flash/nor/tcl.c
+++ b/src/flash/nor/tcl.c
@@ -15,9 +15,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -72,16 +70,27 @@ COMMAND_HANDLER(handle_flash_info_command)
struct flash_bank *p;
int j = 0;
int retval;
+ bool show_sectors = false;
+ bool prot_block_available;
- if (CMD_ARGC != 1)
+ if (CMD_ARGC < 1 || CMD_ARGC > 2)
return ERROR_COMMAND_SYNTAX_ERROR;
+ if (CMD_ARGC == 2) {
+ if (strcmp("sectors", CMD_ARGV[1]) == 0)
+ show_sectors = true;
+ else
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
if (retval != ERROR_OK)
return retval;
if (p != NULL) {
char buf[1024];
+ int num_blocks;
+ struct flash_sector *block_array;
/* attempt auto probe */
retval = p->driver->auto_probe(p);
@@ -102,22 +111,32 @@ COMMAND_HANDLER(handle_flash_info_command)
p->size,
p->bus_width,
p->chip_width);
- for (j = 0; j < p->num_sectors; j++) {
- char *protect_state;
- if (p->sectors[j].is_protected == 0)
+ prot_block_available = p->num_prot_blocks && p->prot_blocks;
+ if (!show_sectors && prot_block_available) {
+ block_array = p->prot_blocks;
+ num_blocks = p->num_prot_blocks;
+ } else {
+ block_array = p->sectors;
+ num_blocks = p->num_sectors;
+ }
+
+ for (j = 0; j < num_blocks; j++) {
+ char *protect_state = "";
+
+ if (block_array[j].is_protected == 0)
protect_state = "not protected";
- else if (p->sectors[j].is_protected == 1)
+ else if (block_array[j].is_protected == 1)
protect_state = "protected";
- else
+ else if (!show_sectors || !prot_block_available)
protect_state = "protection state unknown";
command_print(CMD_CTX,
"\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s",
j,
- p->sectors[j].offset,
- p->sectors[j].size,
- p->sectors[j].size >> 10,
+ block_array[j].offset,
+ block_array[j].size,
+ block_array[j].size >> 10,
protect_state);
}
@@ -162,6 +181,7 @@ COMMAND_HANDLER(handle_flash_probe_command)
COMMAND_HANDLER(handle_flash_erase_check_command)
{
+ bool blank = true;
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -187,10 +207,11 @@ COMMAND_HANDLER(handle_flash_erase_check_command)
if (p->sectors[j].is_erased == 0)
erase_state = "not erased";
else if (p->sectors[j].is_erased == 1)
- erase_state = "erased";
+ continue;
else
erase_state = "erase state unknown";
+ blank = false;
command_print(CMD_CTX,
"\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s",
j,
@@ -200,6 +221,8 @@ COMMAND_HANDLER(handle_flash_erase_check_command)
erase_state);
}
+ if (blank)
+ command_print(CMD_CTX, "\tBank is erased");
return retval;
}
@@ -274,8 +297,8 @@ static int flash_check_sector_parameters(struct command_context *cmd_ctx,
}
if (!(last <= (num_sectors - 1))) {
- command_print(cmd_ctx, "ERROR: last sector must be <= %d",
- (int) num_sectors - 1);
+ command_print(cmd_ctx, "ERROR: last sector must be <= %" PRIu32,
+ num_sectors - 1);
return ERROR_FAIL;
}
@@ -318,7 +341,7 @@ COMMAND_HANDLER(handle_flash_erase_command)
"in %fs", first, last, p->bank_number, duration_elapsed(&bench));
}
- return ERROR_OK;
+ return retval;
}
COMMAND_HANDLER(handle_flash_protect_command)
@@ -331,30 +354,35 @@ COMMAND_HANDLER(handle_flash_protect_command)
struct flash_bank *p;
int retval;
+ int num_blocks;
retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
if (retval != ERROR_OK)
return retval;
+ if (p->num_prot_blocks)
+ num_blocks = p->num_prot_blocks;
+ else
+ num_blocks = p->num_sectors;
+
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
if (strcmp(CMD_ARGV[2], "last") == 0)
- last = p->num_sectors - 1;
+ last = num_blocks - 1;
else
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
bool set;
COMMAND_PARSE_ON_OFF(CMD_ARGV[3], set);
- retval = flash_check_sector_parameters(CMD_CTX, first, last, p->num_sectors);
+ retval = flash_check_sector_parameters(CMD_CTX, first, last, num_blocks);
if (retval != ERROR_OK)
return retval;
retval = flash_driver_protect(p, set, first, last);
if (retval == ERROR_OK) {
- command_print(CMD_CTX, "%s protection for sectors %i "
- "through %i on flash bank %d",
- (set) ? "set" : "cleared", (int) first,
- (int) last, p->bank_number);
+ command_print(CMD_CTX, "%s protection for sectors %" PRIu32
+ " through %" PRIu32 " on flash bank %d",
+ (set) ? "set" : "cleared", first, last, p->bank_number);
}
return retval;
@@ -555,7 +583,7 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
{
uint32_t offset;
uint8_t *buffer;
- struct fileio fileio;
+ struct fileio *fileio;
if (CMD_ARGC != 3)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -571,26 +599,26 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
if (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
- return ERROR_OK;
+ return ERROR_FAIL;
size_t filesize;
- retval = fileio_size(&fileio, &filesize);
+ retval = fileio_size(fileio, &filesize);
if (retval != ERROR_OK) {
- fileio_close(&fileio);
+ fileio_close(fileio);
return retval;
}
buffer = malloc(filesize);
if (buffer == NULL) {
- fileio_close(&fileio);
+ fileio_close(fileio);
LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
size_t buf_cnt;
- if (fileio_read(&fileio, filesize, buffer, &buf_cnt) != ERROR_OK) {
+ if (fileio_read(fileio, filesize, buffer, &buf_cnt) != ERROR_OK) {
free(buffer);
- fileio_close(&fileio);
- return ERROR_OK;
+ fileio_close(fileio);
+ return ERROR_FAIL;
}
retval = flash_driver_write(p, buffer, offset, buf_cnt);
@@ -605,7 +633,7 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
duration_elapsed(&bench), duration_kbps(&bench, filesize));
}
- fileio_close(&fileio);
+ fileio_close(fileio);
return retval;
}
@@ -614,7 +642,7 @@ COMMAND_HANDLER(handle_flash_read_bank_command)
{
uint32_t offset;
uint8_t *buffer;
- struct fileio fileio;
+ struct fileio *fileio;
uint32_t length;
size_t written;
@@ -652,8 +680,8 @@ COMMAND_HANDLER(handle_flash_read_bank_command)
return retval;
}
- retval = fileio_write(&fileio, length, buffer, &written);
- fileio_close(&fileio);
+ retval = fileio_write(fileio, length, buffer, &written);
+ fileio_close(fileio);
free(buffer);
if (retval != ERROR_OK) {
LOG_ERROR("Could not write file");
@@ -661,9 +689,9 @@ COMMAND_HANDLER(handle_flash_read_bank_command)
}
if (duration_measure(&bench) == ERROR_OK)
- command_print(CMD_CTX, "wrote %ld bytes to file %s from flash bank %u"
+ command_print(CMD_CTX, "wrote %zd bytes to file %s from flash bank %u"
" at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
- (long)written, CMD_ARGV[1], p->bank_number, offset,
+ written, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, written));
return retval;
@@ -674,12 +702,12 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
{
uint32_t offset;
uint8_t *buffer_file, *buffer_flash;
- struct fileio fileio;
+ struct fileio *fileio;
size_t read_cnt;
size_t filesize;
int differ;
- if (CMD_ARGC != 3)
+ if (CMD_ARGC < 2 || CMD_ARGC > 3)
return ERROR_COMMAND_SYNTAX_ERROR;
struct duration bench;
@@ -690,7 +718,16 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
if (ERROR_OK != retval)
return retval;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
+ offset = 0;
+
+ if (CMD_ARGC > 2)
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
+
+ if (offset > p->size) {
+ LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
+ offset);
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);
if (retval != ERROR_OK) {
@@ -698,21 +735,21 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
return retval;
}
- retval = fileio_size(&fileio, &filesize);
+ retval = fileio_size(fileio, &filesize);
if (retval != ERROR_OK) {
- fileio_close(&fileio);
+ fileio_close(fileio);
return retval;
}
buffer_file = malloc(filesize);
if (buffer_file == NULL) {
LOG_ERROR("Out of memory");
- fileio_close(&fileio);
+ fileio_close(fileio);
return ERROR_FAIL;
}
- retval = fileio_read(&fileio, filesize, buffer_file, &read_cnt);
- fileio_close(&fileio);
+ retval = fileio_read(fileio, filesize, buffer_file, &read_cnt);
+ fileio_close(fileio);
if (retval != ERROR_OK) {
LOG_ERROR("File read failure");
free(buffer_file);
@@ -741,9 +778,9 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
}
if (duration_measure(&bench) == ERROR_OK)
- command_print(CMD_CTX, "read %ld bytes from file %s and flash bank %u"
+ command_print(CMD_CTX, "read %zd bytes from file %s and flash bank %u"
" at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
- (long)read_cnt, CMD_ARGV[1], p->bank_number, offset,
+ read_cnt, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, read_cnt));
differ = memcmp(buffer_file, buffer_flash, read_cnt);
@@ -811,7 +848,7 @@ static const struct command_registration flash_exec_command_handlers[] = {
.name = "info",
.handler = handle_flash_info_command,
.mode = COMMAND_EXEC,
- .usage = "bank_id",
+ .usage = "bank_id ['sectors']",
.help = "Print information about a flash bank.",
},
{
@@ -898,19 +935,20 @@ static const struct command_registration flash_exec_command_handlers[] = {
.name = "verify_bank",
.handler = handle_flash_verify_bank_command,
.mode = COMMAND_EXEC,
- .usage = "bank_id filename offset",
- .help = "Read binary data from flash bank and file, "
- "starting at specified byte offset from the "
- "beginning of the bank. Compare the contents.",
+ .usage = "bank_id filename [offset]",
+ .help = "Compare the contents of a file with the contents of the "
+ "flash bank. Allow optional offset from beginning of the bank "
+ "(defaults to zero).",
},
{
.name = "protect",
.handler = handle_flash_protect_command,
.mode = COMMAND_EXEC,
- .usage = "bank_id first_sector [last_sector|'last'] "
+ .usage = "bank_id first_block [last_block|'last'] "
"('on'|'off')",
- .help = "Turn protection on or off for a range of sectors "
- "in a given flash bank.",
+ .help = "Turn protection on or off for a range of protection "
+ "blocks or sectors in a given flash bank. "
+ "See 'flash info' output for a list of blocks.",
},
{
.name = "padded_value",
@@ -983,9 +1021,11 @@ COMMAND_HANDLER(handle_flash_bank_command)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], c->chip_width);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], c->bus_width);
- c->default_padded_value = 0xff;
+ c->default_padded_value = c->erased_value = 0xff;
c->num_sectors = 0;
c->sectors = NULL;
+ c->num_prot_blocks = 0;
+ c->prot_blocks = NULL;
c->next = NULL;
int retval;
diff --git a/src/flash/nor/tms470.c b/src/flash/nor/tms470.c
index 86858a84e..a70891e89 100644
--- a/src/flash/nor/tms470.c
+++ b/src/flash/nor/tms470.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/flash/nor/virtual.c b/src/flash/nor/virtual.c
index 599a9c09d..06981f4f4 100644
--- a/src/flash/nor/virtual.c
+++ b/src/flash/nor/virtual.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -46,6 +44,7 @@ static void virtual_update_bank_info(struct flash_bank *bank)
bank->size = master_bank->size;
bank->chip_width = master_bank->chip_width;
bank->bus_width = master_bank->bus_width;
+ bank->erased_value = master_bank->erased_value;
bank->default_padded_value = master_bank->default_padded_value;
bank->num_sectors = master_bank->num_sectors;
bank->sectors = master_bank->sectors;
diff --git a/src/flash/nor/xmc4xxx.c b/src/flash/nor/xmc4xxx.c
index 9212e43e2..02df46a3f 100644
--- a/src/flash/nor/xmc4xxx.c
+++ b/src/flash/nor/xmc4xxx.c
@@ -11,6 +11,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
+* You should have received a copy of the GNU General Public License *
+* along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -181,7 +183,7 @@
/* Flash controller configuration values */
#define FLASH_ID_XMC4500 0xA2
-#define FLASH_ID_XMC4800 0x92
+#define FLASH_ID_XMC4300_XMC4700_4800 0x92
#define FLASH_ID_XMC4100_4200 0x9C
#define FLASH_ID_XMC4400 0x9F
@@ -317,8 +319,8 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank)
}
/* This part doesn't follow the typical standard of 0xff
- * being the default padding value.*/
- bank->default_padded_value = 0x00;
+ * being the erased value.*/
+ bank->default_padded_value = bank->erased_value = 0x00;
return ERROR_OK;
}
@@ -381,9 +383,9 @@ static int xmc4xxx_probe(struct flash_bank *bank)
bank->num_sectors = 12;
LOG_DEBUG("XMC4xxx: XMC4500 detected.");
break;
- case FLASH_ID_XMC4800:
+ case FLASH_ID_XMC4300_XMC4700_4800:
bank->num_sectors = 16;
- LOG_DEBUG("XMC4xxx: XMC4800 detected.");
+ LOG_DEBUG("XMC4xxx: XMC4700/4800 detected.");
break;
default:
LOG_ERROR("XMC4xxx: Unexpected flash ID. got %02" PRIx8,
@@ -615,106 +617,6 @@ static int xmc4xxx_enter_page_mode(struct flash_bank *bank)
return res;
}
-/* The logical erase value of an xmc4xxx memory cell is 0x00,
- * therefore, we cannot use the built in flash blank check and must
- * implement our own */
-
-/** Checks whether a memory region is zeroed. */
-int xmc4xxx_blank_check_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *blank)
-{
- struct working_area *erase_check_algorithm;
- struct reg_param reg_params[3];
- struct armv7m_algorithm armv7m_info;
- int retval;
-
- /* see contrib/loaders/erase_check/armv7m_0_erase_check.s for src */
-
- static const uint8_t erase_check_code[] = {
- /* loop: */
- 0x03, 0x78, /* ldrb r3, [r0] */
- 0x01, 0x30, /* adds r0, #1 */
- 0x1A, 0x43, /* orrs r2, r2, r3 */
- 0x01, 0x39, /* subs r1, r1, #1 */
- 0xFA, 0xD1, /* bne loop */
- 0x00, 0xBE /* bkpt #0 */
- };
-
- /* make sure we have a working area */
- if (target_alloc_working_area(target, sizeof(erase_check_code),
- &erase_check_algorithm) != ERROR_OK)
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-
- retval = target_write_buffer(target, erase_check_algorithm->address,
- sizeof(erase_check_code), (uint8_t *)erase_check_code);
- if (retval != ERROR_OK)
- return retval;
-
- armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
- armv7m_info.core_mode = ARM_MODE_THREAD;
-
- init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
- buf_set_u32(reg_params[0].value, 0, 32, address);
-
- init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
- buf_set_u32(reg_params[1].value, 0, 32, count);
-
- init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT);
- buf_set_u32(reg_params[2].value, 0, 32, 0x00);
-
- retval = target_run_algorithm(target,
- 0,
- NULL,
- 3,
- reg_params,
- erase_check_algorithm->address,
- erase_check_algorithm->address + (sizeof(erase_check_code) - 2),
- 10000,
- &armv7m_info);
-
- if (retval == ERROR_OK)
- *blank = buf_get_u32(reg_params[2].value, 0, 32);
-
- destroy_reg_param(®_params[0]);
- destroy_reg_param(®_params[1]);
- destroy_reg_param(®_params[2]);
-
- target_free_working_area(target, erase_check_algorithm);
-
- return retval;
-}
-
-static int xmc4xxx_flash_blank_check(struct flash_bank *bank)
-{
- struct target *target = bank->target;
- int i;
- int retval;
- uint32_t blank;
-
- if (bank->target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- for (i = 0; i < bank->num_sectors; i++) {
- uint32_t address = bank->base + bank->sectors[i].offset;
- uint32_t size = bank->sectors[i].size;
-
- LOG_DEBUG("Erase checking 0x%08"PRIx32, address);
- retval = xmc4xxx_blank_check_memory(target, address, size, &blank);
-
- if (retval != ERROR_OK)
- break;
-
- if (blank == 0x00)
- bank->sectors[i].is_erased = 1;
- else
- bank->sectors[i].is_erased = 0;
- }
-
- return ERROR_OK;
-}
-
static int xmc4xxx_write_page(struct flash_bank *bank, const uint8_t *pg_buf,
uint32_t offset, bool user_config)
{
@@ -949,6 +851,14 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_
break;
}
break;
+ case 0x300:
+ dev_str = "XMC4300";
+
+ switch (rev_id) {
+ case 0x1:
+ rev_str = "AA";
+ }
+ break;
case 0x400:
dev_str = "XMC4400";
@@ -983,6 +893,15 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_
break;
}
break;
+ case 0x700:
+ dev_str = "XMC4700";
+
+ switch (rev_id) {
+ case 0x1:
+ rev_str = "EES-AA";
+ break;
+ }
+ break;
case 0x800:
dev_str = "XMC4800";
@@ -1087,11 +1006,6 @@ static int xmc4xxx_flash_unprotect(struct flash_bank *bank, int32_t level)
uint32_t addr;
int res;
- if ((level < 0) || (level > 1)) {
- LOG_ERROR("Invalid user level. Must be 0-1");
- return ERROR_FAIL;
- }
-
switch (level) {
case 0:
addr = UCB0_BASE;
@@ -1099,6 +1013,9 @@ static int xmc4xxx_flash_unprotect(struct flash_bank *bank, int32_t level)
case 1:
addr = UCB1_BASE;
break;
+ default:
+ LOG_ERROR("Invalid user level. Must be 0-1");
+ return ERROR_FAIL;
}
res = xmc4xxx_erase_sector(bank, addr, true);
@@ -1435,7 +1352,7 @@ struct flash_driver xmc4xxx_flash = {
.read = default_flash_read,
.probe = xmc4xxx_probe,
.auto_probe = xmc4xxx_probe,
- .erase_check = xmc4xxx_flash_blank_check,
+ .erase_check = default_flash_blank_check,
.info = xmc4xxx_get_info_command,
.protect_check = xmc4xxx_protect_check,
.protect = xmc4xxx_protect,
diff --git a/src/hello.c b/src/hello.c
index f103ed23c..25938bcf8 100644
--- a/src/hello.c
+++ b/src/hello.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/hello.h b/src/hello.h
index d06695124..c88c89ddf 100644
--- a/src/hello.h
+++ b/src/hello.h
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef OPENOCD_HELLO_H
@@ -28,4 +26,4 @@ struct command_registration;
*/
extern const struct command_registration hello_command_handlers[];
-#endif /* OPENOCD_HELLO_H */
+#endif /* OPENOCD_HELLO_H */
diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am
index 9477267f6..e0f7f49bb 100644
--- a/src/helper/Makefile.am
+++ b/src/helper/Makefile.am
@@ -1,52 +1,49 @@
-include $(top_srcdir)/common.mk
-
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libhelper.la
-
-CONFIGFILES = options.c time_support_common.c
-
-libhelper_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS)
-
-libhelper_la_SOURCES = \
- binarybuffer.c \
- $(CONFIGFILES) \
- configuration.c \
- log.c \
- command.c \
- time_support.c \
- replacements.c \
- fileio.c \
- util.c \
- jim-nvp.c
+noinst_LTLIBRARIES += %D%/libhelper.la
+
+%C%_libhelper_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS)
+
+%C%_libhelper_la_SOURCES = \
+ %D%/binarybuffer.c \
+ %D%/options.c \
+ %D%/time_support_common.c \
+ %D%/configuration.c \
+ %D%/log.c \
+ %D%/command.c \
+ %D%/time_support.c \
+ %D%/replacements.c \
+ %D%/fileio.c \
+ %D%/util.c \
+ %D%/jep106.c \
+ %D%/jim-nvp.c \
+ %D%/binarybuffer.h \
+ %D%/configuration.h \
+ %D%/ioutil.h \
+ %D%/list.h \
+ %D%/util.h \
+ %D%/types.h \
+ %D%/log.h \
+ %D%/command.h \
+ %D%/time_support.h \
+ %D%/replacements.h \
+ %D%/fileio.h \
+ %D%/system.h \
+ %D%/jep106.h \
+ %D%/jep106.inc \
+ %D%/jim-nvp.h
if IOUTIL
-libhelper_la_SOURCES += ioutil.c
+%C%_libhelper_la_SOURCES += %D%/ioutil.c
else
-libhelper_la_SOURCES += ioutil_stubs.c
+%C%_libhelper_la_SOURCES += %D%/ioutil_stubs.c
endif
-libhelper_la_CFLAGS =
+%C%_libhelper_la_CFLAGS = $(AM_CFLAGS)
if IS_MINGW
# FD_* macros are sloppy with their signs on MinGW32 platform
-libhelper_la_CFLAGS += -Wno-sign-compare
+%C%_libhelper_la_CFLAGS += -Wno-sign-compare
endif
-noinst_HEADERS = \
- binarybuffer.h \
- configuration.h \
- ioutil.h \
- list.h \
- util.h \
- types.h \
- log.h \
- command.h \
- time_support.h \
- replacements.h \
- fileio.h \
- system.h \
- bin2char.sh \
- jim-nvp.h
-
-EXTRA_DIST = startup.tcl
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+STARTUP_TCL_SRCS += %D%/startup.tcl
+EXTRA_DIST += \
+ %D%/bin2char.sh \
+ %D%/update_jep106.pl
diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c
index 3cadabdb1..76f657f8d 100644
--- a/src/helper/binarybuffer.c
+++ b/src/helper/binarybuffer.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -47,6 +45,11 @@ static const unsigned char bit_reverse_table256[] = {
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
+static const char hex_digits[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f'
+};
+
void *buf_cpy(const void *from, void *_to, unsigned size)
{
if (NULL == from || NULL == _to)
@@ -371,31 +374,72 @@ void bit_copy_discard(struct bit_copy_queue *q)
}
}
-int unhexify(char *bin, const char *hex, int count)
+/**
+ * Convert a string of hexadecimal pairs into its binary
+ * representation.
+ *
+ * @param[out] bin Buffer to store binary representation. The buffer size must
+ * be at least @p count.
+ * @param[in] hex String with hexadecimal pairs to convert into its binary
+ * representation.
+ * @param[in] count Number of hexadecimal pairs to convert.
+ *
+ * @return The number of converted hexadecimal pairs.
+ */
+size_t unhexify(uint8_t *bin, const char *hex, size_t count)
{
- int i, tmp;
+ size_t i;
+ char tmp;
+
+ if (!bin || !hex)
+ return 0;
+
+ memset(bin, 0, count);
+
+ for (i = 0; i < 2 * count; i++) {
+ if (hex[i] >= 'a' && hex[i] <= 'f')
+ tmp = hex[i] - 'a' + 10;
+ else if (hex[i] >= 'A' && hex[i] <= 'F')
+ tmp = hex[i] - 'A' + 10;
+ else if (hex[i] >= '0' && hex[i] <= '9')
+ tmp = hex[i] - '0';
+ else
+ return i / 2;
- for (i = 0; i < count; i++) {
- if (sscanf(hex + (2 * i), "%02x", &tmp) != 1)
- return i;
- bin[i] = tmp;
+ bin[i / 2] |= tmp << (4 * ((i + 1) % 2));
}
- return i;
+ return i / 2;
}
-int hexify(char *hex, const char *bin, int count, int out_maxlen)
+/**
+ * Convert binary data into a string of hexadecimal pairs.
+ *
+ * @param[out] hex Buffer to store string of hexadecimal pairs. The buffer size
+ * must be at least @p length.
+ * @param[in] bin Buffer with binary data to convert into hexadecimal pairs.
+ * @param[in] count Number of bytes to convert.
+ * @param[in] length Maximum number of characters, including null-terminator,
+ * to store into @p hex.
+ *
+ * @returns The length of the converted string excluding null-terminator.
+ */
+size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)
{
- int i, cmd_len = 0;
+ size_t i;
+ uint8_t tmp;
+
+ if (!length)
+ return 0;
- /* May use a length, or a null-terminated string as input. */
- if (count == 0)
- count = strlen(bin);
+ for (i = 0; i < length - 1 && i < 2 * count; i++) {
+ tmp = (bin[i / 2] >> (4 * ((i + 1) % 2))) & 0x0f;
+ hex[i] = hex_digits[tmp];
+ }
- for (i = 0; i < count; i++)
- cmd_len += snprintf(hex + cmd_len, out_maxlen - cmd_len, "%02x", bin[i] & 0xff);
+ hex[i] = 0;
- return cmd_len;
+ return i;
}
void buffer_shr(void *_buf, unsigned buf_len, unsigned count)
diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h
index eaa8c5263..f1da8c4aa 100644
--- a/src/helper/binarybuffer.h
+++ b/src/helper/binarybuffer.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef BINARYBUFFER_H
-#define BINARYBUFFER_H
+#ifndef OPENOCD_HELPER_BINARYBUFFER_H
+#define OPENOCD_HELPER_BINARYBUFFER_H
#include "list.h"
@@ -236,8 +234,8 @@ void bit_copy_discard(struct bit_copy_queue *q);
/* functions to convert to/from hex encoded buffer
* used in ti-icdi driver and gdb server */
-int unhexify(char *bin, const char *hex, int count);
-int hexify(char *hex, const char *bin, int count, int out_maxlen);
+size_t unhexify(uint8_t *bin, const char *hex, size_t count);
+size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t out_maxlen);
void buffer_shr(void *_buf, unsigned buf_len, unsigned count);
-#endif /* BINARYBUFFER_H */
+#endif /* OPENOCD_HELPER_BINARYBUFFER_H */
diff --git a/src/helper/command.c b/src/helper/command.c
index a0aa9e857..5deaee859 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -22,9 +22,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -1175,8 +1173,8 @@ COMMAND_HANDLER(handle_sleep_command)
return retval;
if (!busy) {
- long long then = timeval_ms();
- while (timeval_ms() - then < (long long)duration) {
+ int64_t then = timeval_ms();
+ while (timeval_ms() - then < (int64_t)duration) {
target_call_timer_callbacks_now();
usleep(1000);
}
@@ -1412,6 +1410,8 @@ DEFINE_PARSE_ULONGLONG(_u32, uint32_t, 0, UINT32_MAX)
DEFINE_PARSE_ULONGLONG(_u16, uint16_t, 0, UINT16_MAX)
DEFINE_PARSE_ULONGLONG(_u8, uint8_t, 0, UINT8_MAX)
+DEFINE_PARSE_ULONGLONG(_target_addr, target_addr_t, 0, TARGET_ADDR_MAX)
+
#define DEFINE_PARSE_LONGLONG(name, type, min, max) \
DEFINE_PARSE_WRAPPER(name, type, min, max, long long, _llong)
DEFINE_PARSE_LONGLONG(_int, int, n < INT_MIN, INT_MAX)
diff --git a/src/helper/command.h b/src/helper/command.h
index 0eda5b5e7..bd24156e3 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef COMMAND_H
-#define COMMAND_H
+#ifndef OPENOCD_HELPER_COMMAND_H
+#define OPENOCD_HELPER_COMMAND_H
#include
@@ -359,10 +357,13 @@ DECLARE_PARSE_WRAPPER(_u16, uint16_t);
DECLARE_PARSE_WRAPPER(_u8, uint8_t);
DECLARE_PARSE_WRAPPER(_int, int);
+DECLARE_PARSE_WRAPPER(_s64, int64_t);
DECLARE_PARSE_WRAPPER(_s32, int32_t);
DECLARE_PARSE_WRAPPER(_s16, int16_t);
DECLARE_PARSE_WRAPPER(_s8, int8_t);
+DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t);
+
/**
* @brief parses the string @a in into @a out as a @a type, or prints
* a command error and passes the error code to the caller. If an error
@@ -384,6 +385,9 @@ DECLARE_PARSE_WRAPPER(_s8, int8_t);
} \
} while (0)
+#define COMMAND_PARSE_ADDRESS(in, out) \
+ COMMAND_PARSE_NUMBER(target_addr, in, out)
+
/**
* Parse the string @c as a binary parameter, storing the boolean value
* in @c out. The strings @c on and @c off are used to match different
@@ -417,4 +421,4 @@ COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label);
void script_debug(Jim_Interp *interp, const char *cmd,
unsigned argc, Jim_Obj * const *argv);
-#endif /* COMMAND_H */
+#endif /* OPENOCD_HELPER_COMMAND_H */
diff --git a/src/helper/configuration.c b/src/helper/configuration.c
index dde1491ad..2a278838d 100644
--- a/src/helper/configuration.c
+++ b/src/helper/configuration.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/helper/configuration.h b/src/helper/configuration.h
index 7b9f7119a..3cbcd41f6 100644
--- a/src/helper/configuration.h
+++ b/src/helper/configuration.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef CONFIGURATION_H
-#define CONFIGURATION_H
+#ifndef OPENOCD_HELPER_CONFIGURATION_H
+#define OPENOCD_HELPER_CONFIGURATION_H
#include
@@ -42,4 +40,4 @@ FILE *open_file_from_path(const char *file, const char *mode);
char *find_file(const char *name);
char *get_home_dir(const char *append_path);
-#endif /* CONFIGURATION_H */
+#endif /* OPENOCD_HELPER_CONFIGURATION_H */
diff --git a/src/helper/fileio.c b/src/helper/fileio.c
index 2664bfa11..47494dfcd 100644
--- a/src/helper/fileio.c
+++ b/src/helper/fileio.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -32,7 +30,7 @@
#include "configuration.h"
#include "fileio.h"
-struct fileio_internal {
+struct fileio {
char *url;
size_t size;
enum fileio_type type;
@@ -40,8 +38,22 @@ struct fileio_internal {
FILE *file;
};
-static inline int fileio_close_local(struct fileio_internal *fileio);
-static inline int fileio_open_local(struct fileio_internal *fileio)
+static inline int fileio_close_local(struct fileio *fileio)
+{
+ int retval = fclose(fileio->file);
+ if (retval != 0) {
+ if (retval == EBADF)
+ LOG_ERROR("BUG: fileio->file not a valid file descriptor");
+ else
+ LOG_ERROR("couldn't close %s: %s", fileio->url, strerror(errno));
+
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
+ return ERROR_OK;
+}
+
+static inline int fileio_open_local(struct fileio *fileio)
{
char file_access[4];
ssize_t file_size;
@@ -104,69 +116,49 @@ static inline int fileio_open_local(struct fileio_internal *fileio)
return ERROR_OK;
}
-int fileio_open(struct fileio *fileio_p,
- const char *url,
- enum fileio_access access_type,
- enum fileio_type type)
+int fileio_open(struct fileio **fileio, const char *url,
+ enum fileio_access access_type, enum fileio_type type)
{
int retval;
- struct fileio_internal *fileio;
+ struct fileio *tmp;
- fileio = malloc(sizeof(struct fileio_internal));
+ tmp = malloc(sizeof(struct fileio));
- fileio->type = type;
- fileio->access = access_type;
- fileio->url = strdup(url);
+ tmp->type = type;
+ tmp->access = access_type;
+ tmp->url = strdup(url);
- retval = fileio_open_local(fileio);
+ retval = fileio_open_local(tmp);
if (retval != ERROR_OK) {
- free(fileio->url);
- free(fileio);
+ free(tmp->url);
+ free(tmp);
return retval;
}
- fileio_p->fp = fileio;
-
- return ERROR_OK;
-}
-
-static inline int fileio_close_local(struct fileio_internal *fileio)
-{
- int retval = fclose(fileio->file);
- if (retval != 0) {
- if (retval == EBADF)
- LOG_ERROR("BUG: fileio_local->file not a valid file descriptor");
- else
- LOG_ERROR("couldn't close %s: %s", fileio->url, strerror(errno));
-
- return ERROR_FILEIO_OPERATION_FAILED;
- }
+ *fileio = tmp;
return ERROR_OK;
}
-int fileio_close(struct fileio *fileio_p)
+int fileio_close(struct fileio *fileio)
{
int retval;
- struct fileio_internal *fileio = fileio_p->fp;
retval = fileio_close_local(fileio);
free(fileio->url);
- fileio->url = NULL;
-
free(fileio);
- fileio_p->fp = NULL;
return retval;
}
-int fileio_seek(struct fileio *fileio_p, size_t position)
+int fileio_seek(struct fileio *fileio, size_t position)
{
int retval;
- struct fileio_internal *fileio = fileio_p->fp;
+
retval = fseek(fileio->file, position, SEEK_SET);
+
if (retval != 0) {
LOG_ERROR("couldn't seek file %s: %s", fileio->url, strerror(errno));
return ERROR_FILEIO_OPERATION_FAILED;
@@ -175,36 +167,40 @@ int fileio_seek(struct fileio *fileio_p, size_t position)
return ERROR_OK;
}
-static int fileio_local_read(struct fileio_internal *fileio,
- size_t size, void *buffer, size_t *size_read)
+static int fileio_local_read(struct fileio *fileio, size_t size, void *buffer,
+ size_t *size_read)
{
- ssize_t retval = fread(buffer, 1, size, fileio->file);
+ ssize_t retval;
+
+ retval = fread(buffer, 1, size, fileio->file);
*size_read = (retval >= 0) ? retval : 0;
+
return (retval < 0) ? retval : ERROR_OK;
}
-int fileio_read(struct fileio *fileio_p, size_t size, void *buffer,
- size_t *size_read)
+int fileio_read(struct fileio *fileio, size_t size, void *buffer,
+ size_t *size_read)
{
- struct fileio_internal *fileio = fileio_p->fp;
return fileio_local_read(fileio, size, buffer, size_read);
}
-int fileio_read_u32(struct fileio *fileio_p, uint32_t *data)
+int fileio_read_u32(struct fileio *fileio, uint32_t *data)
{
+ int retval;
uint8_t buf[4];
size_t size_read;
- struct fileio_internal *fileio = fileio_p->fp;
- int retval = fileio_local_read(fileio, sizeof(uint32_t), buf, &size_read);
+
+ retval = fileio_local_read(fileio, sizeof(uint32_t), buf, &size_read);
+
if (ERROR_OK == retval && sizeof(uint32_t) != size_read)
retval = -EIO;
if (ERROR_OK == retval)
*data = be_to_h_u32(buf);
+
return retval;
}
-static int fileio_local_fgets(struct fileio_internal *fileio,
- size_t size, void *buffer)
+static int fileio_local_fgets(struct fileio *fileio, size_t size, void *buffer)
{
if (fgets(buffer, size, fileio->file) == NULL)
return ERROR_FILEIO_OPERATION_FAILED;
@@ -212,36 +208,44 @@ static int fileio_local_fgets(struct fileio_internal *fileio,
return ERROR_OK;
}
-int fileio_fgets(struct fileio *fileio_p, size_t size, void *buffer)
+int fileio_fgets(struct fileio *fileio, size_t size, void *buffer)
{
- struct fileio_internal *fileio = fileio_p->fp;
return fileio_local_fgets(fileio, size, buffer);
}
-static int fileio_local_write(struct fileio_internal *fileio,
- size_t size, const void *buffer, size_t *size_written)
+static int fileio_local_write(struct fileio *fileio, size_t size,
+ const void *buffer, size_t *size_written)
{
- ssize_t retval = fwrite(buffer, 1, size, fileio->file);
+ ssize_t retval;
+
+ retval = fwrite(buffer, 1, size, fileio->file);
*size_written = (retval >= 0) ? retval : 0;
+
return (retval < 0) ? retval : ERROR_OK;
}
-int fileio_write(struct fileio *fileio_p,
- size_t size, const void *buffer, size_t *size_written)
+int fileio_write(struct fileio *fileio, size_t size, const void *buffer,
+ size_t *size_written)
{
- struct fileio_internal *fileio = fileio_p->fp;
- int retval = fileio_local_write(fileio, size, buffer, size_written);
+ int retval;
+
+ retval = fileio_local_write(fileio, size, buffer, size_written);
+
if (retval == ERROR_OK)
fileio->size += *size_written;
+
return retval;
}
-int fileio_write_u32(struct fileio *fileio_p, uint32_t data)
+int fileio_write_u32(struct fileio *fileio, uint32_t data)
{
+ int retval;
uint8_t buf[4];
h_u32_to_be(buf, data);
size_t size_written;
- int retval = fileio_write(fileio_p, 4, buf, &size_written);
+
+ retval = fileio_write(fileio, 4, buf, &size_written);
+
if (ERROR_OK == retval && size_written != sizeof(uint32_t))
retval = -EIO;
@@ -257,9 +261,8 @@ int fileio_write_u32(struct fileio *fileio_p, uint32_t data)
* Avoiding the seek on startup opens up for using streams.
*
*/
-int fileio_size(struct fileio *fileio_p, size_t *size)
+int fileio_size(struct fileio *fileio, size_t *size)
{
- struct fileio_internal *fileio = fileio_p->fp;
*size = fileio->size;
return ERROR_OK;
diff --git a/src/helper/fileio.h b/src/helper/fileio.h
index c3824ff8f..ae4a3ecfc 100644
--- a/src/helper/fileio.h
+++ b/src/helper/fileio.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef FILEIO_H
-#define FILEIO_H
+#ifndef OPENOCD_HELPER_FILEIO_H
+#define OPENOCD_HELPER_FILEIO_H
#define FILEIO_MAX_ERROR_STRING (128)
@@ -43,13 +41,10 @@ enum fileio_access {
FILEIO_APPENDREAD, /* open for writing, position at end, allow reading */
};
-struct fileio {
- /* The structure is opaque */
- struct fileio_internal *fp;
-};
+struct fileio;
-int fileio_open(struct fileio *fileio,
- const char *url, enum fileio_access access_type, enum fileio_type type);
+int fileio_open(struct fileio **fileio, const char *url,
+ enum fileio_access access_type, enum fileio_type type);
int fileio_close(struct fileio *fileio);
int fileio_seek(struct fileio *fileio, size_t position);
@@ -71,4 +66,4 @@ int fileio_size(struct fileio *fileio, size_t *size);
#define ERROR_FILEIO_RESOURCE_TYPE_UNKNOWN (-1204)
#define ERROR_FILEIO_OPERATION_NOT_SUPPORTED (-1205)
-#endif /* FILEIO_H */
+#endif /* OPENOCD_HELPER_FILEIO_H */
diff --git a/src/helper/ioutil.c b/src/helper/ioutil.c
index 166256c7d..f1123cd82 100644
--- a/src/helper/ioutil.c
+++ b/src/helper/ioutil.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* this file contains various functionality useful to standalone systems */
@@ -243,117 +241,6 @@ COMMAND_HANDLER(handle_cp_command)
return retval;
}
-#define SHOW_RESULT(a, b) LOG_ERROR(# a " failed %d\n", (int)b)
-
-#define IOSIZE 512
-void copyfile(char *name2, char *name1)
-{
-
- int err;
- char buf[IOSIZE];
- int fd1, fd2;
- ssize_t done, wrote;
-
- fd1 = open(name1, O_WRONLY | O_CREAT, 0664);
- if (fd1 < 0)
- SHOW_RESULT(open, fd1);
-
- fd2 = open(name2, O_RDONLY);
- if (fd2 < 0)
- SHOW_RESULT(open, fd2);
-
- for (;; ) {
- done = read(fd2, buf, IOSIZE);
- if (done < 0) {
- SHOW_RESULT(read, done);
- break;
- }
-
- if (done == 0)
- break;
-
- wrote = write(fd1, buf, done);
- if (wrote != done)
- SHOW_RESULT(write, wrote);
-
- if (wrote != done)
- break;
- }
-
- err = close(fd1);
- if (err < 0)
- SHOW_RESULT(close, err);
-
- err = close(fd2);
- if (err < 0)
- SHOW_RESULT(close, err);
-}
-
-/* utility fn to copy a directory */
-void copydir(char *name, char *destdir)
-{
- int err;
- DIR *dirp;
-
- dirp = opendir(destdir);
- if (dirp == NULL)
- mkdir(destdir, 0777);
- else
- err = closedir(dirp);
-
- dirp = opendir(name);
- if (dirp == NULL)
- SHOW_RESULT(opendir, -1);
-
- for (;; ) {
- struct dirent *entry = readdir(dirp);
-
- if (entry == NULL)
- break;
-
- if (strcmp(entry->d_name, ".") == 0)
- continue;
- if (strcmp(entry->d_name, "..") == 0)
- continue;
-
- int isDir = 0;
- struct stat buf;
- char fullPath[PATH_MAX];
- strncpy(fullPath, name, PATH_MAX);
- strcat(fullPath, "/");
- strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));
-
- if (stat(fullPath, &buf) == -1) {
- LOG_ERROR("unable to read status from %s", fullPath);
- break;
- }
- isDir = S_ISDIR(buf.st_mode) != 0;
-
- if (isDir)
- continue;
-
- /* diag_printf(": entry %14s",entry->d_name); */
- char fullname[PATH_MAX];
- char fullname2[PATH_MAX];
-
- strcpy(fullname, name);
- strcat(fullname, "/");
- strcat(fullname, entry->d_name);
-
- strcpy(fullname2, destdir);
- strcat(fullname2, "/");
- strcat(fullname2, entry->d_name);
- /* diag_printf("from %s to %s\n", fullname, fullname2); */
- copyfile(fullname, fullname2);
-
- /* diag_printf("\n"); */
- }
-
- err = closedir(dirp);
- if (err < 0)
- SHOW_RESULT(stat, err);
-}
-
COMMAND_HANDLER(handle_rm_command)
{
if (CMD_ARGC != 1)
diff --git a/src/helper/ioutil.h b/src/helper/ioutil.h
index 8cd9157b7..f060aab09 100644
--- a/src/helper/ioutil.h
+++ b/src/helper/ioutil.h
@@ -12,16 +12,14 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef HELPER_IOUTILS_H
-#define HELPER_IOUTILS_H
+#ifndef OPENOCD_HELPER_IOUTIL_H
+#define OPENOCD_HELPER_IOUTIL_H
struct command_context;
int ioutil_init(struct command_context *cmd_ctx);
-#endif /* HELPER_IOUTILS_H */
+#endif /* OPENOCD_HELPER_IOUTIL_H */
diff --git a/src/helper/ioutil_stubs.c b/src/helper/ioutil_stubs.c
index a87f1b6e4..0d81fe665 100644
--- a/src/helper/ioutil_stubs.c
+++ b/src/helper/ioutil_stubs.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/helper/jim-nvp.c b/src/helper/jim-nvp.c
index 4602a8db9..d13bdfba4 100644
--- a/src/helper/jim-nvp.c
+++ b/src/helper/jim-nvp.c
@@ -205,7 +205,7 @@ int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere)
return JIM_ERR;
}
-int Jim_GetOpt_String(Jim_GetOptInfo *goi, char **puthere, int *len)
+int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len)
{
int r;
Jim_Obj *o;
@@ -215,8 +215,7 @@ int Jim_GetOpt_String(Jim_GetOptInfo *goi, char **puthere, int *len)
if (r == JIM_OK) {
cp = Jim_GetString(o, len);
if (puthere) {
- /* remove const */
- *puthere = (char *)(cp);
+ *puthere = cp;
}
}
return r;
diff --git a/src/helper/jim-nvp.h b/src/helper/jim-nvp.h
index 05d79c4a7..7b4a491d3 100644
--- a/src/helper/jim-nvp.h
+++ b/src/helper/jim-nvp.h
@@ -41,8 +41,8 @@
* official policies, either expressed or implied, of the Jim Tcl Project.
*/
-#ifndef JIM_NVP_H
-#define JIM_NVP_H
+#ifndef OPENOCD_HELPER_JIM_NVP_H
+#define OPENOCD_HELPER_JIM_NVP_H
#include
@@ -245,7 +245,7 @@ int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere);
* \param puthere - where param is put
* \param len - return its length
*/
-int Jim_GetOpt_String(Jim_GetOptInfo *goi, char **puthere, int *len);
+int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len);
/** Remove argv[0] as double.
*
@@ -326,4 +326,4 @@ void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, int hadpr
*/
int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere);
-#endif
+#endif /* OPENOCD_HELPER_JIM_NVP_H */
diff --git a/src/helper/list.h b/src/helper/list.h
index 302b91097..6fd0e7ca7 100644
--- a/src/helper/list.h
+++ b/src/helper/list.h
@@ -1,5 +1,5 @@
-#ifndef _LINUX_LIST_H
-#define _LINUX_LIST_H
+#ifndef OPENOCD_HELPER_LIST_H
+#define OPENOCD_HELPER_LIST_H
/* begin local changes */
#include
@@ -734,4 +734,4 @@ static inline void hlist_move_list(struct hlist_head *old,
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
pos = n)
-#endif
+#endif /* OPENOCD_HELPER_LIST_H */
diff --git a/src/helper/log.c b/src/helper/log.c
index 0bea1c50c..d4e87f662 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -47,10 +45,10 @@ int debug_level = -1;
static FILE *log_output;
static struct log_callback *log_callbacks;
-static long long last_time;
-static long long current_time;
+static int64_t last_time;
+static int64_t current_time;
-static long long start;
+static int64_t start;
static const char * const log_strings[5] = {
"User : ",
@@ -105,7 +103,7 @@ static void log_forward(const char *file, unsigned line, const char *function, c
}
}
-/* The log_puts() serves to somewhat different goals:
+/* The log_puts() serves two somewhat different goals:
*
* - logging
* - feeding low-level info to the user in GDB or Telnet
@@ -136,12 +134,12 @@ static void log_puts(enum log_levels level,
if (strlen(string) > 0) {
if (debug_level >= LOG_LVL_DEBUG) {
/* print with count and time information */
- int t = (int)(timeval_ms()-start);
+ int64_t t = timeval_ms() - start;
#ifdef _DEBUG_FREE_SPACE_
struct mallinfo info;
info = mallinfo();
#endif
- fprintf(log_output, "%s%d %d %s:%d %s()"
+ fprintf(log_output, "%s%d %" PRId64 " %s:%d %s()"
#ifdef _DEBUG_FREE_SPACE_
" %d"
#endif
@@ -193,6 +191,30 @@ void log_printf(enum log_levels level,
va_end(ap);
}
+void log_vprintf_lf(enum log_levels level, const char *file, unsigned line,
+ const char *function, const char *format, va_list args)
+{
+ char *tmp;
+
+ count++;
+
+ if (level > debug_level)
+ return;
+
+ tmp = alloc_vprintf(format, args);
+
+ if (!tmp)
+ return;
+
+ /*
+ * Note: alloc_vprintf() guarantees that the buffer is at least one
+ * character longer.
+ */
+ strcat(tmp, "\n");
+ log_puts(level, file, line, function, tmp);
+ free(tmp);
+}
+
void log_printf_lf(enum log_levels level,
const char *file,
unsigned line,
@@ -200,23 +222,10 @@ void log_printf_lf(enum log_levels level,
const char *format,
...)
{
- char *string;
va_list ap;
- count++;
- if (level > debug_level)
- return;
-
va_start(ap, format);
-
- string = alloc_vprintf(format, ap);
- if (string != NULL) {
- strcat(string, "\n"); /* alloc_vprintf guaranteed the buffer to be at least one
- *char longer */
- log_puts(level, file, line, function, string);
- free(string);
- }
-
+ log_vprintf_lf(level, file, line, function, format, ap);
va_end(ap);
}
@@ -242,9 +251,15 @@ COMMAND_HANDLER(handle_log_output_command)
{
if (CMD_ARGC == 1) {
FILE *file = fopen(CMD_ARGV[0], "w");
-
- if (file)
- log_output = file;
+ if (file == NULL) {
+ LOG_ERROR("failed to open output log '%s'", CMD_ARGV[0]);
+ return ERROR_FAIL;
+ }
+ if (log_output != stderr && log_output != NULL) {
+ /* Close previous log file, if it was open and wasn't stderr. */
+ fclose(log_output);
+ }
+ log_output = file;
}
return ERROR_OK;
@@ -412,12 +427,12 @@ void keep_alive()
if (gdb_actual_connections)
LOG_WARNING("keep_alive() was not invoked in the "
"1000ms timelimit. GDB alive packet not "
- "sent! (%lld). Workaround: increase "
+ "sent! (%" PRId64 "). Workaround: increase "
"\"set remotetimeout\" in GDB",
current_time-last_time);
else
LOG_DEBUG("keep_alive() was not invoked in the "
- "1000ms timelimit (%lld). This may cause "
+ "1000ms timelimit (%" PRId64 "). This may cause "
"trouble with GDB connections.",
current_time-last_time);
}
diff --git a/src/helper/log.h b/src/helper/log.h
index 7f9f32c59..6b938165b 100644
--- a/src/helper/log.h
+++ b/src/helper/log.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ERROR_H
-#define ERROR_H
+#ifndef OPENOCD_HELPER_LOG_H
+#define OPENOCD_HELPER_LOG_H
#include
@@ -62,6 +60,8 @@ enum log_levels {
void log_printf(enum log_levels level, const char *file, unsigned line,
const char *function, const char *format, ...)
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6)));
+void log_vprintf_lf(enum log_levels level, const char *file, unsigned line,
+ const char *function, const char *format, va_list args);
void log_printf_lf(enum log_levels level, const char *file, unsigned line,
const char *function, const char *format, ...)
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6)));
@@ -141,4 +141,4 @@ extern int debug_level;
#define ERROR_WAIT (-5)
-#endif /* LOG_H */
+#endif /* OPENOCD_HELPER_LOG_H */
diff --git a/src/helper/options.c b/src/helper/options.c
index 35bdae299..1cfa55376 100644
--- a/src/helper/options.c
+++ b/src/helper/options.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -31,6 +29,15 @@
#include
+#include
+#include
+#if IS_DARWIN
+#include
+#endif
+#ifdef HAVE_SYS_SYSCTL_H
+#include
+#endif
+
static int help_flag, version_flag;
static const struct option long_options[] = {
@@ -52,84 +59,129 @@ int configuration_output_handler(struct command_context *context, const char *li
return ERROR_OK;
}
-// #ifdef _WIN32
-static char *find_suffix(const char *text, const char *suffix)
+/* Return the canonical path to the directory the openocd executable is in.
+ * The path should be absolute, use / as path separator and have all symlinks
+ * resolved. The returned string is malloc'd. */
+static char *find_exe_path(void)
{
- size_t text_len = strlen(text);
- size_t suffix_len = strlen(suffix);
+ char *exepath = NULL;
- if (suffix_len == 0)
- return (char *)text + text_len;
+ do {
+#if IS_WIN32 && !IS_CYGWIN
+ exepath = malloc(MAX_PATH);
+ if (exepath == NULL)
+ break;
+ GetModuleFileName(NULL, exepath, MAX_PATH);
- if (suffix_len > text_len || strncmp(text + text_len - suffix_len, suffix, suffix_len) != 0)
- return NULL; /* Not a suffix of text */
+ /* Convert path separators to UNIX style, should work on Windows also. */
+ for (char *p = exepath; *p; p++) {
+ if (*p == '\\')
+ *p = '/';
+ }
- return (char *)text + text_len - suffix_len;
-}
-// #endif
+#elif IS_DARWIN
+ exepath = malloc(PROC_PIDPATHINFO_MAXSIZE);
+ if (exepath == NULL)
+ break;
+ if (proc_pidpath(getpid(), exepath, PROC_PIDPATHINFO_MAXSIZE) <= 0) {
+ free(exepath);
+ exepath = NULL;
+ }
-static void add_default_dirs(char* argv0)
-{
- const char *run_prefix;
- char *path;
+#elif defined(CTL_KERN) && defined(KERN_PROC) && defined(KERN_PROC_PATHNAME) /* *BSD */
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+ char *path = malloc(PATH_MAX);
+ if (path == NULL)
+ break;
+ int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+ size_t size = PATH_MAX;
-#ifdef _WIN32
- char strExePath[MAX_PATH];
- GetModuleFileName(NULL, strExePath, MAX_PATH);
+ if (sysctl(mib, (u_int)ARRAY_SIZE(mib), path, &size, NULL, 0) != 0)
+ break;
- /* Strip executable file name, leaving path */
- *strrchr(strExePath, '\\') = '\0';
+#ifdef HAVE_REALPATH
+ exepath = realpath(path, NULL);
+ free(path);
+#else
+ exepath = path;
+#endif
- /* Convert path separators to UNIX style, should work on Windows also. */
- for (char *p = strExePath; *p; p++) {
- if (*p == '\\')
- *p = '/';
+#elif defined(HAVE_REALPATH) /* Assume POSIX.1-2008 */
+ /* Try Unices in order of likelihood. */
+ exepath = realpath("/proc/self/exe", NULL); /* Linux/Cygwin */
+ if (exepath == NULL)
+ exepath = realpath("/proc/self/path/a.out", NULL); /* Solaris */
+ if (exepath == NULL)
+ exepath = realpath("/proc/curproc/file", NULL); /* FreeBSD (Should be covered above) */
+#endif
+ } while (0);
+
+ if (exepath != NULL) {
+ /* Strip executable file name, leaving path */
+ *strrchr(exepath, '/') = '\0';
+ } else {
+ LOG_WARNING("Could not determine executable path, using configured BINDIR.");
+ LOG_DEBUG("BINDIR = %s", BINDIR);
+#ifdef HAVE_REALPATH
+ exepath = realpath(BINDIR, NULL);
+#else
+ exepath = strdup(BINDIR);
+#endif
}
- char *end_of_prefix = find_suffix(strExePath, BINDIR);
- if (end_of_prefix != NULL)
- *end_of_prefix = '\0';
+ return exepath;
+}
- run_prefix = strExePath;
-#else
- char strElfPath[PATH_MAX];
- char strElfRealPath[PATH_MAX];
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-result"
- if (strchr(argv0, '/') == NULL) {
- /* If the name has no path separators, use default logic */
- run_prefix = "";
- } else {
- if (*argv0 != '/') {
- /* Relative path must be appended to current directory */
- getcwd(strElfPath, PATH_MAX);
- if (strElfPath[strlen(strElfPath)-1] != '/') {
- strcat(strElfPath, "/");
- }
- strcat(strElfPath, argv0);
- } else {
- /* Absolute folder is used as is */
- strncpy(strElfPath, argv0, PATH_MAX);
- }
- /* Convert to canonical path */
- realpath(strElfPath, strElfRealPath);
-#pragma GCC diagnostic pop
-
- /* Strip executable file name, leaving path (there always is a '/' */
- *strrchr(strElfRealPath, '/') = '\0';
-
- char *end_of_prefix = find_suffix(strElfRealPath, BINDIR);
- if (end_of_prefix != NULL)
- *end_of_prefix = '\0';
-
- run_prefix = strElfRealPath;
- }
-#endif
+static char *find_relative_path(const char *from, const char *to)
+{
+ size_t i;
+
+ /* Skip common /-separated parts of from and to */
+ i = 0;
+ for (size_t n = 0; from[n] == to[n]; n++) {
+ if (from[n] == '\0') {
+ i = n;
+ break;
+ }
+ if (from[n] == '/')
+ i = n + 1;
+ }
+ from += i;
+ to += i;
+
+ /* Count number of /-separated non-empty parts of from */
+ i = 0;
+ while (from[0] != '\0') {
+ if (from[0] != '/')
+ i++;
+ char *next = strchr(from, '/');
+ if (next == NULL)
+ break;
+ from = next + 1;
+ }
+
+ /* Prepend that number of ../ in front of to */
+ char *relpath = malloc(i * 3 + strlen(to) + 1);
+ relpath[0] = '\0';
+ for (size_t n = 0; n < i; n++)
+ strcat(relpath, "../");
+ strcat(relpath, to);
+
+ return relpath;
+}
+
+static void add_default_dirs(void)
+{
+ char *path;
+ char *exepath = find_exe_path();
+ char *bin2data = find_relative_path(BINDIR, PKGDATADIR);
LOG_DEBUG("bindir=%s", BINDIR);
LOG_DEBUG("pkgdatadir=%s", PKGDATADIR);
- LOG_DEBUG("run_prefix=%s", run_prefix);
+ LOG_DEBUG("exepath=%s", exepath);
+ LOG_DEBUG("bin2data=%s", bin2data);
/*
* The directory containing OpenOCD-supplied scripts should be
@@ -163,17 +215,20 @@ static void add_default_dirs(char* argv0)
}
#endif
- path = alloc_printf("%s%s%s", run_prefix, PKGDATADIR, "/site");
+ path = alloc_printf("%s/%s/%s", exepath, bin2data, "site");
if (path) {
add_script_search_dir(path);
free(path);
}
- path = alloc_printf("%s%s%s", run_prefix, PKGDATADIR, "/scripts");
+ path = alloc_printf("%s/%s/%s", exepath, bin2data, "scripts");
if (path) {
add_script_search_dir(path);
free(path);
}
+
+ free(exepath);
+ free(bin2data);
}
int parse_cmdline_args(struct command_context *cmd_ctx, int argc, char *argv[])
@@ -212,8 +267,10 @@ int parse_cmdline_args(struct command_context *cmd_ctx, int argc, char *argv[])
case 'd': /* --debug | -d */
{
char *command = alloc_printf("debug_level %s", optarg ? optarg : "3");
- command_run_line(cmd_ctx, command);
+ int retval = command_run_line(cmd_ctx, command);
free(command);
+ if (retval != ERROR_OK)
+ return retval;
break;
}
case 'l': /* --log_output | -l */
@@ -234,16 +291,26 @@ int parse_cmdline_args(struct command_context *cmd_ctx, int argc, char *argv[])
LOG_WARNING("deprecated option: -p/--pipe. Use '-c \"gdb_port pipe; "
"log_output openocd.log\"' instead.");
break;
+ default: /* '?' */
+ /* getopt will emit an error message, all we have to do is bail. */
+ return ERROR_FAIL;
}
}
+ if (optind < argc) {
+ /* Catch extra arguments on the command line. */
+ LOG_OUTPUT("Unexpected command line argument: %s\n", argv[optind]);
+ return ERROR_FAIL;
+ }
+
if (help_flag) {
LOG_OUTPUT("Open On-Chip Debugger\nLicensed under GNU GPL v2\n");
LOG_OUTPUT("--help | -h\tdisplay this help\n");
LOG_OUTPUT("--version | -v\tdisplay OpenOCD version\n");
LOG_OUTPUT("--file | -f\tuse configuration file \n");
LOG_OUTPUT("--search | -s\tdir to search for config files and scripts\n");
- LOG_OUTPUT("--debug | -d\tset debug level <0-3>\n");
+ LOG_OUTPUT("--debug | -d\tset debug level to 3\n");
+ LOG_OUTPUT(" | -d\tset debug level to \n");
LOG_OUTPUT("--log_output | -l\tredirect log output to file \n");
LOG_OUTPUT("--command | -c\trun \n");
exit(-1);
@@ -258,7 +325,7 @@ int parse_cmdline_args(struct command_context *cmd_ctx, int argc, char *argv[])
/* paths specified on the command line take precedence over these
* built-in paths
*/
- add_default_dirs(argv[0]);
+ add_default_dirs();
return ERROR_OK;
}
diff --git a/src/helper/replacements.c b/src/helper/replacements.c
index bb23dd92b..b4bb94f06 100644
--- a/src/helper/replacements.c
+++ b/src/helper/replacements.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* 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 277660228..1e2fbf20f 100644
--- a/src/helper/replacements.h
+++ b/src/helper/replacements.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef REPLACEMENTS_H
-#define REPLACEMENTS_H
+#ifndef OPENOCD_HELPER_REPLACEMENTS_H
+#define OPENOCD_HELPER_REPLACEMENTS_H
/* MIN,MAX macros */
#ifndef MIN
@@ -282,4 +280,4 @@ typedef struct {
const char *libusb_error_name(int error_code);
#endif /* defined HAVE_LIBUSB1 && !defined HAVE_LIBUSB_ERROR_NAME */
-#endif /* REPLACEMENTS_H */
+#endif /* OPENOCD_HELPER_REPLACEMENTS_H */
diff --git a/src/helper/system.h b/src/helper/system.h
index a6dfd7ec1..97b3443be 100644
--- a/src/helper/system.h
+++ b/src/helper/system.h
@@ -15,13 +15,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef SYSTEM_H
-#define SYSTEM_H
+#ifndef OPENOCD_HELPER_SYSTEM_H
+#define OPENOCD_HELPER_SYSTEM_H
/* standard C library header files */
#include
@@ -88,4 +86,4 @@
#define false 0
#endif
-#endif /* SYSTEM_H */
+#endif /* OPENOCD_HELPER_SYSTEM_H */
diff --git a/src/helper/time_support.c b/src/helper/time_support.c
index c5978b423..8337e73ba 100644
--- a/src/helper/time_support.c
+++ b/src/helper/time_support.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -78,14 +76,14 @@ int duration_measure(struct duration *duration)
return retval;
}
-float duration_elapsed(struct duration *duration)
+float duration_elapsed(const struct duration *duration)
{
float t = duration->elapsed.tv_sec;
t += (float)duration->elapsed.tv_usec / 1000000.0;
return t;
}
-float duration_kbps(struct duration *duration, size_t count)
+float duration_kbps(const struct duration *duration, size_t count)
{
return count / (1024.0 * duration_elapsed(duration));
}
diff --git a/src/helper/time_support.h b/src/helper/time_support.h
index ab839826b..58c8c48bb 100644
--- a/src/helper/time_support.h
+++ b/src/helper/time_support.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef TIME_SUPPORT_H
-#define TIME_SUPPORT_H
+#ifndef OPENOCD_HELPER_TIME_SUPPORT_H
+#define OPENOCD_HELPER_TIME_SUPPORT_H
#ifdef TIME_WITH_SYS_TIME
# include
@@ -55,8 +53,8 @@ int duration_start(struct duration *duration);
int duration_measure(struct duration *duration);
/** @returns Elapsed time in seconds. */
-float duration_elapsed(struct duration *duration);
+float duration_elapsed(const struct duration *duration);
/** @returns KB/sec for the elapsed @a duration and @a count bytes. */
-float duration_kbps(struct duration *duration, size_t count);
+float duration_kbps(const struct duration *duration, size_t count);
-#endif /* TIME_SUPPORT_H */
+#endif /* OPENOCD_HELPER_TIME_SUPPORT_H */
diff --git a/src/helper/time_support_common.c b/src/helper/time_support_common.c
index fd564e337..b733c270e 100644
--- a/src/helper/time_support_common.c
+++ b/src/helper/time_support_common.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -33,7 +31,7 @@
/* simple and low overhead fetching of ms counter. Use only
* the difference between ms counters returned from this fn.
*/
-int64_t timeval_ms()
+int64_t timeval_ms(void)
{
struct timeval now;
int retval = gettimeofday(&now, NULL);
diff --git a/src/helper/types.h b/src/helper/types.h
index 3f0724c3a..58c9e7245 100644
--- a/src/helper/types.h
+++ b/src/helper/types.h
@@ -16,12 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef TYPES_H
-#define TYPES_H
+
+#ifndef OPENOCD_HELPER_TYPES_H
+#define OPENOCD_HELPER_TYPES_H
#include
#ifdef HAVE_SYS_TYPES_H
@@ -297,14 +296,21 @@ static inline int parity_u32(uint32_t x)
*/
#if !defined(_STDINT_H)
-#define PRIx32 "x"
#define PRId32 "d"
-#define SCNx32 "x"
#define PRIi32 "i"
+#define PRIo32 "o"
#define PRIu32 "u"
+#define PRIx32 "x"
+#define PRIX32 "X"
+#define SCNx32 "x"
#define PRId8 PRId32
#define SCNx64 "llx"
+#define PRId64 "lld"
+#define PRIi64 "lli"
+#define PRIo64 "llo"
+#define PRIu64 "llu"
#define PRIx64 "llx"
+#define PRIX64 "llX"
typedef CYG_ADDRWORD intptr_t;
typedef int64_t intmax_t;
@@ -338,4 +344,23 @@ typedef uint64_t uintmax_t;
#endif
-#endif /* TYPES_H */
+#if BUILD_TARGET64
+typedef uint64_t target_addr_t;
+#define TARGET_ADDR_MAX UINT64_MAX
+#define TARGET_PRIdADDR PRId64
+#define TARGET_PRIuADDR PRIu64
+#define TARGET_PRIoADDR PRIo64
+#define TARGET_PRIxADDR PRIx64
+#define TARGET_PRIXADDR PRIX64
+#else
+typedef uint32_t target_addr_t;
+#define TARGET_ADDR_MAX UINT32_MAX
+#define TARGET_PRIdADDR PRId32
+#define TARGET_PRIuADDR PRIu32
+#define TARGET_PRIoADDR PRIo32
+#define TARGET_PRIxADDR PRIx32
+#define TARGET_PRIXADDR PRIX32
+#endif
+#define TARGET_ADDR_FMT "0x%8.8" TARGET_PRIxADDR
+
+#endif /* OPENOCD_HELPER_TYPES_H */
diff --git a/src/helper/util.c b/src/helper/util.c
index 55b92a755..56baf95d1 100644
--- a/src/helper/util.c
+++ b/src/helper/util.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* this file contains various functionality useful to standalone systems */
diff --git a/src/helper/util.h b/src/helper/util.h
index 48db725cf..c9a11ddac 100644
--- a/src/helper/util.h
+++ b/src/helper/util.h
@@ -12,16 +12,14 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef HELPER_UTILS_H
-#define HELPER_UTILS_H
+#ifndef OPENOCD_HELPER_UTIL_H
+#define OPENOCD_HELPER_UTIL_H
struct command_context;
int util_init(struct command_context *cmd_ctx);
-#endif /* HELPER_UTILS_H */
+#endif /* OPENOCD_HELPER_UTIL_H */
diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am
index db3e6ff2a..50ee263d0 100644
--- a/src/jtag/Makefile.am
+++ b/src/jtag/Makefile.am
@@ -1,86 +1,72 @@
-include $(top_srcdir)/common.mk
+noinst_LTLIBRARIES += %D%/libjtag.la
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libjtag.la
+JTAG_SRCS =
+%C%_libjtag_la_LIBADD =
-SUBDIRS =
-DRIVERFILES =
-libjtag_la_LIBADD =
-
-CLEANFILES =
-
-BUILT_SOURCES =
-
-BUILT_SOURCES += minidriver_imp.h
-CLEANFILES += minidriver_imp.h
+BUILT_SOURCES += %D%/minidriver_imp.h
+CLEANFILES += %D%/minidriver_imp.h
if MINIDRIVER
if ZY1000
-DRIVERFILES += zy1000/zy1000.c
-JTAG_MINIDRIVER_DIR = $(srcdir)/zy1000
+JTAG_SRCS += %D%/zy1000/zy1000.c
+JTAG_MINIDRIVER_DIR = %D%/zy1000
endif
if MINIDRIVER_DUMMY
-DRIVERFILES += minidummy/minidummy.c commands.c
-JTAG_MINIDRIVER_DIR = $(srcdir)/minidummy
+JTAG_SRCS += %D%/minidummy/minidummy.c %D%/commands.c
+JTAG_MINIDRIVER_DIR = %D%/minidummy
endif
-MINIDRIVER_IMP_DIR = $(srcdir)/minidriver
+MINIDRIVER_IMP_DIR = %D%/minidriver
-jtag_minidriver.h: $(JTAG_MINIDRIVER_DIR)/jtag_minidriver.h
+%D%/jtag_minidriver.h: $(JTAG_MINIDRIVER_DIR)/jtag_minidriver.h
cp $< $@
-BUILT_SOURCES += jtag_minidriver.h
+BUILT_SOURCES += %D%/jtag_minidriver.h
-CLEANFILES += jtag_minidriver.h
+CLEANFILES += %D%/jtag_minidriver.h
else
-MINIDRIVER_IMP_DIR = $(srcdir)/drivers
-DRIVERFILES += commands.c
+MINIDRIVER_IMP_DIR = %D%/drivers
+JTAG_SRCS += %D%/commands.c
if HLADAPTER
-SUBDIRS += hla
-libjtag_la_LIBADD += $(top_builddir)/src/jtag/hla/libocdhla.la
+include %D%/hla/Makefile.am
+%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/hla/libocdhla.la
endif
if AICE
-SUBDIRS += aice
-libjtag_la_LIBADD += $(top_builddir)/src/jtag/aice/libocdaice.la
+include %D%/aice/Makefile.am
+%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/aice/libocdaice.la
endif
-SUBDIRS += drivers
-libjtag_la_LIBADD += $(top_builddir)/src/jtag/drivers/libocdjtagdrivers.la
-
+include %D%/drivers/Makefile.am
+%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/drivers/libocdjtagdrivers.la
endif
-
# endif // MINIDRIVER
-minidriver_imp.h: $(MINIDRIVER_IMP_DIR)/minidriver_imp.h
+%D%/minidriver_imp.h: $(MINIDRIVER_IMP_DIR)/minidriver_imp.h
cp $< $@
-libjtag_la_SOURCES = \
- adapter.c \
- core.c \
- interface.c \
- interfaces.c \
- tcl.c \
- $(DRIVERFILES)
-
-noinst_HEADERS = \
- commands.h \
- driver.h \
- interface.h \
- interfaces.h \
- minidriver.h \
- jtag.h \
- minidriver/minidriver_imp.h \
- minidummy/jtag_minidriver.h \
- swd.h \
- tcl.h
-
-EXTRA_DIST = startup.tcl
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+%C%_libjtag_la_SOURCES = \
+ %D%/adapter.c \
+ %D%/core.c \
+ %D%/interface.c \
+ %D%/interfaces.c \
+ %D%/tcl.c \
+ %D%/commands.h \
+ %D%/driver.h \
+ %D%/interface.h \
+ %D%/interfaces.h \
+ %D%/minidriver.h \
+ %D%/jtag.h \
+ %D%/minidriver/minidriver_imp.h \
+ %D%/minidummy/jtag_minidriver.h \
+ %D%/swd.h \
+ %D%/tcl.h \
+ $(JTAG_SRCS)
+
+STARTUP_TCL_SRCS += %D%/startup.tcl
diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c
index 2f5f6b436..5953de7e5 100644
--- a/src/jtag/adapter.c
+++ b/src/jtag/adapter.c
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/aice/Makefile.am b/src/jtag/aice/Makefile.am
index 7b9469d86..97e38258a 100644
--- a/src/jtag/aice/Makefile.am
+++ b/src/jtag/aice/Makefile.am
@@ -1,27 +1,14 @@
-include $(top_srcdir)/common.mk
-
-AM_CPPFLAGS += -I$(top_srcdir)/src/jtag/drivers $(LIBUSB1_CFLAGS) $(LIBUSB0_CFLAGS)
-
-noinst_LTLIBRARIES = libocdaice.la
-
-libocdaice_la_SOURCES = \
- $(AICEFILES)
-
-AICEFILES =
-
-if AICE
-AICEFILES += aice_transport.c
-AICEFILES += aice_interface.c
-AICEFILES += aice_port.c
-AICEFILES += aice_usb.c
-AICEFILES += aice_pipe.c
-endif
-
-noinst_HEADERS = \
- aice_transport.h \
- aice_interface.h \
- aice_port.h \
- aice_usb.h \
- aice_pipe.h
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+noinst_LTLIBRARIES += %D%/libocdaice.la
+
+%C%_libocdaice_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) $(LIBUSB0_CFLAGS)
+%C%_libocdaice_la_SOURCES = \
+ %D%/aice_transport.c \
+ %D%/aice_interface.c \
+ %D%/aice_port.c \
+ %D%/aice_usb.c \
+ %D%/aice_pipe.c \
+ %D%/aice_transport.h \
+ %D%/aice_interface.h \
+ %D%/aice_port.h \
+ %D%/aice_usb.h \
+ %D%/aice_pipe.h
diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c
index 363b208a3..20f1f07f9 100644
--- a/src/jtag/aice/aice_interface.c
+++ b/src/jtag/aice/aice_interface.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/aice/aice_interface.h b/src/jtag/aice/aice_interface.h
index ddb6ad419..0e3f10836 100644
--- a/src/jtag/aice/aice_interface.h
+++ b/src/jtag/aice/aice_interface.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __AICE_INTERFACE_H__
-#define __AICE_INTERFACE_H__
+
+#ifndef OPENOCD_JTAG_AICE_AICE_INTERFACE_H
+#define OPENOCD_JTAG_AICE_AICE_INTERFACE_H
struct aice_interface_param_s {
/** */
@@ -33,4 +32,4 @@ struct aice_interface_param_s {
int aice_init_targets(void);
-#endif
+#endif /* OPENOCD_JTAG_AICE_AICE_INTERFACE_H */
diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c
index 3180ad008..bdc8c090a 100644
--- a/src/jtag/aice/aice_pipe.c
+++ b/src/jtag/aice/aice_pipe.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -176,7 +174,7 @@ static int aice_pipe_write(const void *buffer, int count)
static int aice_pipe_read(void *buffer, int count)
{
int n;
- long long then, cur;
+ int64_t then, cur;
then = timeval_ms();
@@ -788,8 +786,8 @@ static int aice_pipe_memory_mode(uint32_t coreid, enum nds_memory_select mem_sel
return ERROR_FAIL;
}
-static int aice_pipe_read_tlb(uint32_t coreid, uint32_t virtual_address,
- uint32_t *physical_address)
+static int aice_pipe_read_tlb(uint32_t coreid, target_addr_t virtual_address,
+ target_addr_t *physical_address)
{
char line[AICE_PIPE_MAXLINE];
char command[AICE_PIPE_MAXLINE];
diff --git a/src/jtag/aice/aice_pipe.h b/src/jtag/aice/aice_pipe.h
index 48b0c4912..467ad0ad5 100644
--- a/src/jtag/aice/aice_pipe.h
+++ b/src/jtag/aice/aice_pipe.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _AICE_PIPE_H_
-#define _AICE_PIPE_H_
+
+#ifndef OPENOCD_JTAG_AICE_AICE_PIPE_H
+#define OPENOCD_JTAG_AICE_AICE_PIPE_H
#include
@@ -29,4 +28,4 @@
extern struct aice_port_api_s aice_pipe;
-#endif
+#endif /* OPENOCD_JTAG_AICE_AICE_PIPE_H */
diff --git a/src/jtag/aice/aice_port.c b/src/jtag/aice/aice_port.c
index b61275c8b..2fa346ca0 100644
--- a/src/jtag/aice/aice_port.c
+++ b/src/jtag/aice/aice_port.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/jtag/aice/aice_port.h b/src/jtag/aice/aice_port.h
index d29e9e142..d3d6a1a2c 100644
--- a/src/jtag/aice/aice_port.h
+++ b/src/jtag/aice/aice_port.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _AICE_PORT_H_
-#define _AICE_PORT_H_
+
+#ifndef OPENOCD_JTAG_AICE_AICE_PORT_H
+#define OPENOCD_JTAG_AICE_AICE_PORT_H
#include
@@ -181,7 +180,7 @@ struct aice_port_api_s {
int (*memory_mode)(uint32_t coreid, enum nds_memory_select mem_select);
/** */
- int (*read_tlb)(uint32_t coreid, uint32_t virtual_address, uint32_t *physical_address);
+ int (*read_tlb)(uint32_t coreid, target_addr_t virtual_address, target_addr_t *physical_address);
/** */
int (*cache_ctl)(uint32_t coreid, uint32_t subtype, uint32_t address);
@@ -235,4 +234,4 @@ struct aice_port {
/** */
const struct aice_port *aice_port_get_list(void);
-#endif
+#endif /* OPENOCD_JTAG_AICE_AICE_PORT_H */
diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c
index f3012bb22..9f079468c 100644
--- a/src/jtag/aice/aice_transport.c
+++ b/src/jtag/aice/aice_transport.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -90,11 +88,13 @@ static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi)
free(pTap);
return JIM_ERR;
}
- Jim_GetOpt_String(goi, &cp, NULL);
- pTap->chip = strdup(cp);
- Jim_GetOpt_String(goi, &cp, NULL);
- pTap->tapname = strdup(cp);
+ const char *tmp;
+ Jim_GetOpt_String(goi, &tmp, NULL);
+ pTap->chip = strdup(tmp);
+
+ Jim_GetOpt_String(goi, &tmp, NULL);
+ pTap->tapname = strdup(tmp);
/* name + dot + name + null */
x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
diff --git a/src/jtag/aice/aice_transport.h b/src/jtag/aice/aice_transport.h
index e93d13127..3af8bc2ee 100644
--- a/src/jtag/aice/aice_transport.h
+++ b/src/jtag/aice/aice_transport.h
@@ -13,14 +13,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _AICE_TRANSPORT_
-#define _AICE_TRANSPORT_
+#ifndef OPENOCD_JTAG_AICE_AICE_TRANSPORT_H
+#define OPENOCD_JTAG_AICE_AICE_TRANSPORT_H
extern const char *aice_transports[];
-#endif
+#endif /* OPENOCD_JTAG_AICE_AICE_TRANSPORT_H */
diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c
index 50b3b9a22..50468f375 100644
--- a/src/jtag/aice/aice_usb.c
+++ b/src/jtag/aice/aice_usb.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -1858,7 +1856,7 @@ static int aice_check_dbger(uint32_t coreid, uint32_t expect_status)
if ((i % 30) == 0)
keep_alive();
- long long then = 0;
+ int64_t then = 0;
if (i == aice_count_to_check_dbger)
then = timeval_ms();
if (i >= aice_count_to_check_dbger) {
@@ -2137,10 +2135,16 @@ static int aice_usb_open(struct aice_port_param_s *param)
/* usb_set_configuration required under win32 */
jtag_libusb_set_configuration(devh, 0);
+ jtag_libusb_claim_interface(devh, 0);
unsigned int aice_read_ep;
unsigned int aice_write_ep;
- jtag_libusb_choose_interface(devh, &aice_read_ep, &aice_write_ep, -1, -1, -1);
+#ifdef HAVE_LIBUSB1
+ jtag_libusb_choose_interface(devh, &aice_read_ep, &aice_write_ep, -1, -1, -1, LIBUSB_TRANSFER_TYPE_BULK);
+#else
+ jtag_libusb_choose_interface(devh, &aice_read_ep, &aice_write_ep, -1, -1, -1, USB_ENDPOINT_TYPE_BULK);
+#endif
+ LOG_DEBUG("aice_read_ep=0x%x, aice_write_ep=0x%x", aice_read_ep, aice_write_ep);
aice_handler.usb_read_ep = aice_read_ep;
aice_handler.usb_write_ep = aice_write_ep;
@@ -2999,7 +3003,7 @@ static int aice_usb_step(uint32_t coreid)
if (AICE_TARGET_HALTED == state)
break;
- long long then = 0;
+ int64_t then = 0;
if (i == 30)
then = timeval_ms();
@@ -3426,10 +3430,10 @@ static int aice_usb_memory_mode(uint32_t coreid, enum nds_memory_select mem_sele
return ERROR_OK;
}
-static int aice_usb_read_tlb(uint32_t coreid, uint32_t virtual_address,
- uint32_t *physical_address)
+static int aice_usb_read_tlb(uint32_t coreid, target_addr_t virtual_address,
+ target_addr_t *physical_address)
{
- LOG_DEBUG("aice_usb_read_tlb, virtual address: 0x%08" PRIx32, virtual_address);
+ LOG_DEBUG("aice_usb_read_tlb, virtual address: 0x%08" TARGET_PRIxADDR, virtual_address);
uint32_t instructions[4];
uint32_t probe_result;
diff --git a/src/jtag/aice/aice_usb.h b/src/jtag/aice/aice_usb.h
index adb027eaa..2911ae56b 100644
--- a/src/jtag/aice/aice_usb.h
+++ b/src/jtag/aice/aice_usb.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __AICE_USB_H__
-#define __AICE_USB_H__
+
+#ifndef OPENOCD_JTAG_AICE_AICE_USB_H
+#define OPENOCD_JTAG_AICE_AICE_USB_H
#include "aice_port.h"
@@ -130,4 +129,4 @@ extern struct aice_port_api_s aice_usb_api;
int aice_read_ctrl(uint32_t address, uint32_t *data);
int aice_write_ctrl(uint32_t address, uint32_t data);
-#endif
+#endif /* OPENOCD_JTAG_AICE_AICE_USB_H */
diff --git a/src/jtag/commands.c b/src/jtag/commands.c
index 750ebab0d..ed40755b7 100644
--- a/src/jtag/commands.c
+++ b/src/jtag/commands.c
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/commands.h b/src/jtag/commands.h
index 06ec24837..947c94725 100644
--- a/src/jtag/commands.h
+++ b/src/jtag/commands.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef JTAG_COMMANDS_H
-#define JTAG_COMMANDS_H
+#ifndef OPENOCD_JTAG_COMMANDS_H
+#define OPENOCD_JTAG_COMMANDS_H
/**
* The inferred type of a scan_command_s structure, indicating whether
@@ -175,4 +173,4 @@ int jtag_scan_size(const struct scan_command *cmd);
int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd);
int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer);
-#endif /* JTAG_COMMANDS_H */
+#endif /* OPENOCD_JTAG_COMMANDS_H */
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 74c2731c2..5e297b8e9 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -36,6 +34,7 @@
#include "swd.h"
#include "interface.h"
#include
+#include
#ifdef HAVE_STRINGS_H
#include
@@ -837,7 +836,124 @@ int default_interface_jtag_execute_queue(void)
return ERROR_FAIL;
}
+#if BUILD_RISCV == 1
+ int result = jtag->execute_queue();
+
+#if 0
+ // TODO: I like these better than some of the other JTAG debug statements,
+ // but having both is silly.
+ struct jtag_command *cmd = jtag_command_queue;
+ while (debug_level >= LOG_LVL_DEBUG && cmd) {
+ switch (cmd->type) {
+ case JTAG_SCAN:
+#if 0
+ LOG_DEBUG("JTAG %s SCAN to %s",
+ cmd->cmd.scan->ir_scan ? "IR" : "DR",
+ tap_state_name(cmd->cmd.scan->end_state));
+ for (int i = 0; i < cmd->cmd.scan->num_fields; i++) {
+ struct scan_field *field = cmd->cmd.scan->fields + i;
+ if (field->out_value) {
+ char *str = buf_to_str(field->out_value, field->num_bits, 16);
+ LOG_DEBUG(" %db out: %s", field->num_bits, str);
+ free(str);
+ }
+ if (field->in_value) {
+ char *str = buf_to_str(field->in_value, field->num_bits, 16);
+ LOG_DEBUG(" %db in: %s", field->num_bits, str);
+ free(str);
+ }
+ if (field->check_value) {
+ char *str = buf_to_str(field->check_value, field->num_bits, 16);
+ LOG_DEBUG(" %db check: %s", field->num_bits, str);
+ free(str);
+ }
+ if (field->check_mask) {
+ char *str = buf_to_str(field->check_mask, field->num_bits, 16);
+ LOG_DEBUG(" %db mask: %s", field->num_bits, str);
+ free(str);
+ }
+ }
+#endif
+ {
+ uint8_t *buf = NULL;
+ int scan_bits = jtag_build_buffer(cmd->cmd.scan, &buf);
+ char *str_out = buf_to_str(buf, scan_bits, 16);
+ free(buf);
+ LOG_DEBUG("vvv jtag_scan(%d, %d, %d'h%s, %d); // %s",
+ cmd->cmd.scan->ir_scan,
+ scan_bits,
+ scan_bits, str_out,
+ cmd->cmd.scan->end_state, tap_state_name(cmd->cmd.scan->end_state));
+ free(str_out);
+
+ struct scan_field *last_field = cmd->cmd.scan->fields + cmd->cmd.scan->num_fields - 1;
+ if (last_field->in_value) {
+ char *str_in = buf_to_str(last_field->in_value, last_field->num_bits, 16);
+ LOG_DEBUG("vvv jtag_check_tdo(%d, %d'h%s);",
+ last_field->num_bits,
+ last_field->num_bits, str_in);
+ free(str_in);
+ }
+ }
+ break;
+ case JTAG_TLR_RESET:
+#if 0
+ LOG_DEBUG("JTAG TLR RESET to %s",
+ tap_state_name(cmd->cmd.statemove->end_state));
+#endif
+ LOG_DEBUG("vvv jtag_tlr_reset(%d); // %s",
+ cmd->cmd.statemove->end_state,
+ tap_state_name(cmd->cmd.statemove->end_state));
+ break;
+ case JTAG_RUNTEST:
+#if 0
+ LOG_DEBUG("JTAG RUNTEST %d cycles to %s",
+ cmd->cmd.runtest->num_cycles,
+ tap_state_name(cmd->cmd.runtest->end_state));
+#endif
+ LOG_DEBUG("vvv jtag_runtest(%d, %d); // %s",
+ cmd->cmd.runtest->num_cycles,
+ cmd->cmd.runtest->end_state,
+ tap_state_name(cmd->cmd.runtest->end_state));
+ break;
+ case JTAG_RESET:
+ {
+#if 0
+ const char *reset_str[3] = {
+ "leave", "deassert", "assert"
+ };
+ LOG_DEBUG("JTAG RESET %s TRST, %s SRST",
+ reset_str[cmd->cmd.reset->trst + 1],
+ reset_str[cmd->cmd.reset->srst + 1]);
+#endif
+ LOG_DEBUG("vvv jtag_reset(%d, %d);",
+ cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+ }
+ break;
+ case JTAG_PATHMOVE:
+ LOG_DEBUG("JTAG PATHMOVE (TODO)");
+ break;
+ case JTAG_SLEEP:
+ LOG_DEBUG("JTAG SLEEP (TODO)");
+ break;
+ case JTAG_STABLECLOCKS:
+ LOG_DEBUG("JTAG STABLECLOCKS (TODO)");
+ break;
+ case JTAG_TMS:
+ LOG_DEBUG("JTAG STABLECLOCKS (TODO)");
+ break;
+ default:
+ LOG_ERROR("Unknown JTAG command: %d", cmd->type);
+ break;
+ }
+ cmd = cmd->next;
+ }
+#endif
+
+ return result;
+#else
return jtag->execute_queue();
+#endif
}
void jtag_execute_queue_noclear(void)
@@ -894,6 +1010,8 @@ void jtag_sleep(uint32_t us)
#define JTAG_MAX_AUTO_TAPS 20
+#define EXTRACT_JEP106_BANK(X) (((X) & 0xf00) >> 8)
+#define EXTRACT_JEP106_ID(X) (((X) & 0xfe) >> 1)
#define EXTRACT_MFG(X) (((X) & 0xffe) >> 1)
#define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)
#define EXTRACT_VER(X) (((X) & 0xf0000000) >> 28)
@@ -957,10 +1075,11 @@ static void jtag_examine_chain_display(enum log_levels level, const char *msg,
{
log_printf_lf(level, __FILE__, __LINE__, __func__,
"JTAG tap: %s %16.16s: 0x%08x "
- "(mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x)",
+ "(mfg: 0x%3.3x (%s), part: 0x%4.4x, ver: 0x%1.1x)",
name, msg,
(unsigned int)idcode,
(unsigned int)EXTRACT_MFG(idcode),
+ jep106_manufacturer(EXTRACT_JEP106_BANK(idcode), EXTRACT_JEP106_ID(idcode)),
(unsigned int)EXTRACT_PART(idcode),
(unsigned int)EXTRACT_VER(idcode));
}
@@ -1105,7 +1224,12 @@ static int jtag_examine_chain(void)
if ((idcode & 1) == 0) {
/* Zero for LSB indicates a device in bypass */
+#if BUILD_RISCV == 1
+ LOG_INFO("TAP %s does not have valid IDCODE (idcode=0x%x)",
+ tap->dotted_name, idcode);
+#else
LOG_INFO("TAP %s does not have IDCODE", tap->dotted_name);
+#endif
tap->hasidcode = false;
tap->idcode = 0;
@@ -1715,11 +1839,11 @@ void jtag_set_reset_config(enum reset_types type)
int jtag_get_trst(void)
{
- return jtag_trst;
+ return jtag_trst == 1;
}
int jtag_get_srst(void)
{
- return jtag_srst;
+ return jtag_srst == 1;
}
void jtag_set_nsrst_delay(unsigned delay)
diff --git a/src/jtag/driver.h b/src/jtag/driver.h
index 5a7b4edf4..ae00414c4 100644
--- a/src/jtag/driver.h
+++ b/src/jtag/driver.h
@@ -13,16 +13,14 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef JTAG_DRIVER_H
-#define JTAG_DRIVER_H
+#ifndef OPENOCD_JTAG_DRIVER_H
+#define OPENOCD_JTAG_DRIVER_H
struct command_context;
int interface_register_commands(struct command_context *ctx);
-#endif /* JTAG_DRIVER_H */
+#endif /* OPENOCD_JTAG_DRIVER_H */
diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am
index bbb15dd1e..7c79cc8b9 100644
--- a/src/jtag/drivers/Makefile.am
+++ b/src/jtag/drivers/Makefile.am
@@ -1,176 +1,182 @@
-include $(top_srcdir)/common.mk
+noinst_LTLIBRARIES += %D%/libocdjtagdrivers.la
+%C%_libocdjtagdrivers_la_LIBADD =
-noinst_LTLIBRARIES = libocdjtagdrivers.la
-libocdjtagdrivers_la_LIBADD =
+%C%_libocdjtagdrivers_la_SOURCES = \
+ $(DRIVERFILES) \
+ $(DRIVERHEADERS)
-libocdjtagdrivers_la_SOURCES = \
- $(DRIVERFILES)
+%C%_libocdjtagdrivers_la_CPPFLAGS = $(AM_CPPFLAGS)
-libocdjtagdrivers_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) \
- $(LIBUSB0_CFLAGS) $(HIDAPI_CFLAGS) $(LIBFTDI_CFLAGS)
+ULINK_FIRMWARE = %D%/OpenULINK
-ULINK_FIRMWARE = $(srcdir)/OpenULINK
-
-EXTRA_DIST = $(ULINK_FIRMWARE) \
- usb_blaster/README.CheapClone \
- Makefile.rlink \
- rlink_call.m4 \
- rlink_init.m4
+EXTRA_DIST += $(ULINK_FIRMWARE) \
+ %D%/usb_blaster/README.CheapClone \
+ %D%/Makefile.rlink \
+ %D%/rlink_call.m4 \
+ %D%/rlink_init.m4
DRIVERFILES =
-SUBDIRS=
-if JLINK
-if INTERNAL_LIBJAYLINK
-SUBDIRS += libjaylink
+# Standard Driver: common files
+DRIVERFILES += %D%/driver.c
-libjaylink_internal_la_SOURCES = jlink.c
-libjaylink_internal_la_LIBADD = libjaylink/libjaylink/libjaylink.la
-libjaylink_internal_la_CPPFLAGS = -I$(builddir)/libjaylink/libjaylink \
- -I$(srcdir)/libjaylink $(AM_CPPFLAGS)
+if USE_LIBUSB1
+DRIVERFILES += %D%/libusb1_common.c
+%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBUSB1_CFLAGS)
+%C%_libocdjtagdrivers_la_LIBADD += $(LIBUSB1_LIBS)
+endif
-noinst_LTLIBRARIES += libjaylink_internal.la
-libocdjtagdrivers_la_LIBADD += libjaylink_internal.la
-else
-DRIVERFILES += jlink.c
+if USE_LIBUSB0
+DRIVERFILES += %D%/usb_common.c
+%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBUSB0_CFLAGS)
+%C%_libocdjtagdrivers_la_LIBADD += $(LIBUSB0_LIBS)
+if !USE_LIBUSB1
+DRIVERFILES += %D%/libusb0_common.c
endif
endif
-# Standard Driver: common files
-DRIVERFILES += driver.c
+if USE_LIBFTDI
+%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBFTDI_CFLAGS)
+%C%_libocdjtagdrivers_la_LIBADD += $(LIBFTDI_LIBS)
+endif
-if USE_LIBUSB1
-DRIVERFILES += libusb1_common.c
+if USE_HIDAPI
+%C%_libocdjtagdrivers_la_CPPFLAGS += $(HIDAPI_CFLAGS)
+%C%_libocdjtagdrivers_la_LIBADD += $(HIDAPI_LIBS)
endif
-if USE_LIBUSB0
-DRIVERFILES += usb_common.c
-if !USE_LIBUSB1
-DRIVERFILES += libusb0_common.c
+if USE_LIBJAYLINK
+%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBJAYLINK_CFLAGS)
+%C%_libocdjtagdrivers_la_LIBADD += $(LIBJAYLINK_LIBS)
+endif
+
+if JLINK
+DRIVERFILES += %D%/jlink.c
+if INTERNAL_LIBJAYLINK
+SUBDIRS += %D%/libjaylink
+DIST_SUBDIRS += %D%/libjaylink
+
+%C%_libocdjtagdrivers_la_LIBADD += %D%/libjaylink/libjaylink/libjaylink.la
+%C%_libocdjtagdrivers_la_CPPFLAGS += -I$(builddir)/%D%/libjaylink/libjaylink -I$(srcdir)/%D%/libjaylink
endif
endif
if BITBANG
-DRIVERFILES += bitbang.c
+DRIVERFILES += %D%/bitbang.c
endif
if PARPORT
-DRIVERFILES += parport.c
+DRIVERFILES += %D%/parport.c
endif
if DUMMY
-DRIVERFILES += dummy.c
-endif
-if FT2232_DRIVER
-DRIVERFILES += ft2232.c
+DRIVERFILES += %D%/dummy.c
endif
if FTDI
-DRIVERFILES += ftdi.c mpsse.c
+DRIVERFILES += %D%/ftdi.c %D%/mpsse.c
endif
if W_JTAG_SJ
-DRIVERFILES += w_jtag_sj.c w_jtag_sj_io.c
+DRIVERFILES += %D%/w_jtag_sj.c %D%/w_jtag_sj_io.c
endif
if JTAG_VPI
-DRIVERFILES += jtag_vpi.c
+DRIVERFILES += %D%/jtag_vpi.c
endif
if USB_BLASTER_DRIVER
-SUBDIRS += usb_blaster
-libocdjtagdrivers_la_LIBADD += $(top_builddir)/src/jtag/drivers/usb_blaster/libocdusbblaster.la
+%C%_libocdjtagdrivers_la_LIBADD += %D%/usb_blaster/libocdusbblaster.la
+include %D%/usb_blaster/Makefile.am
endif
if AMTJTAGACCEL
-DRIVERFILES += amt_jtagaccel.c
+DRIVERFILES += %D%/amt_jtagaccel.c
endif
if EP93XX
-DRIVERFILES += ep93xx.c
+DRIVERFILES += %D%/ep93xx.c
endif
if AT91RM9200
-DRIVERFILES += at91rm9200.c
+DRIVERFILES += %D%/at91rm9200.c
endif
if GW16012
-DRIVERFILES += gw16012.c
+DRIVERFILES += %D%/gw16012.c
endif
if BITQ
-DRIVERFILES += bitq.c
+DRIVERFILES += %D%/bitq.c
endif
-if PRESTO_DRIVER
-DRIVERFILES += presto.c
+if PRESTO
+DRIVERFILES += %D%/presto.c
endif
if USBPROG
-DRIVERFILES += usbprog.c
+DRIVERFILES += %D%/usbprog.c
endif
if RLINK
-DRIVERFILES += rlink.c rlink_speed_table.c
+DRIVERFILES += %D%/rlink.c %D%/rlink_speed_table.c
endif
if ULINK
-DRIVERFILES += ulink.c
+DRIVERFILES += %D%/ulink.c
ulinkdir = $(pkgdatadir)/OpenULINK
dist_ulink_DATA = $(ULINK_FIRMWARE)/ulink_firmware.hex
+%C%_libocdjtagdrivers_la_LIBADD += -lm
endif
if VSLLINK
-DRIVERFILES += versaloon/usbtoxxx/usbtogpio.c
-DRIVERFILES += versaloon/usbtoxxx/usbtojtagraw.c
-DRIVERFILES += versaloon/usbtoxxx/usbtoswd.c
-DRIVERFILES += versaloon/usbtoxxx/usbtopwr.c
-DRIVERFILES += versaloon/usbtoxxx/usbtoxxx.c
-DRIVERFILES += versaloon/versaloon.c
-DRIVERFILES += vsllink.c
+DRIVERFILES += %D%/versaloon/usbtoxxx/usbtogpio.c
+DRIVERFILES += %D%/versaloon/usbtoxxx/usbtojtagraw.c
+DRIVERFILES += %D%/versaloon/usbtoxxx/usbtoswd.c
+DRIVERFILES += %D%/versaloon/usbtoxxx/usbtopwr.c
+DRIVERFILES += %D%/versaloon/usbtoxxx/usbtoxxx.c
+DRIVERFILES += %D%/versaloon/versaloon.c
+DRIVERFILES += %D%/vsllink.c
endif
if ARMJTAGEW
-DRIVERFILES += arm-jtag-ew.c
+DRIVERFILES += %D%/arm-jtag-ew.c
endif
if BUSPIRATE
-DRIVERFILES += buspirate.c
+DRIVERFILES += %D%/buspirate.c
endif
if REMOTE_BITBANG
-DRIVERFILES += remote_bitbang.c
+DRIVERFILES += %D%/remote_bitbang.c
endif
if HLADAPTER
-DRIVERFILES += stlink_usb.c
-DRIVERFILES += ti_icdi_usb.c
+DRIVERFILES += %D%/stlink_usb.c
+DRIVERFILES += %D%/ti_icdi_usb.c
endif
if OSBDM
-DRIVERFILES += osbdm.c
+DRIVERFILES += %D%/osbdm.c
endif
if OPENDOUS
-DRIVERFILES += opendous.c
+DRIVERFILES += %D%/opendous.c
endif
if SYSFSGPIO
-DRIVERFILES += sysfsgpio.c
+DRIVERFILES += %D%/sysfsgpio.c
endif
if BCM2835GPIO
-DRIVERFILES += bcm2835gpio.c
+DRIVERFILES += %D%/bcm2835gpio.c
endif
-
if OPENJTAG
-DRIVERFILES += openjtag.c
+DRIVERFILES += %D%/openjtag.c
endif
-
if CMSIS_DAP
-DRIVERFILES += cmsis_dap_usb.c
-endif
-
-noinst_HEADERS = \
- bitbang.h \
- bitq.h \
- ftd2xx_common.h \
- libusb0_common.h \
- libusb1_common.h \
- libusb_common.h \
- minidriver_imp.h \
- mpsse.h \
- rlink.h \
- rlink_dtc_cmd.h \
- rlink_ep1_cmd.h \
- rlink_st7.h \
- usb_common.h \
- versaloon/usbtoxxx/usbtoxxx.h \
- versaloon/usbtoxxx/usbtoxxx_internal.h \
- versaloon/versaloon.h \
- versaloon/versaloon_include.h \
- versaloon/versaloon_internal.h
-
-DIST_SUBDIRS = usb_blaster
-
-if INTERNAL_LIBJAYLINK
-DIST_SUBDIRS += libjaylink
-endif
+DRIVERFILES += %D%/cmsis_dap_usb.c
+endif
+if IMX_GPIO
+DRIVERFILES += %D%/imx_gpio.c
+endif
+
+if KITPROG
+DRIVERFILES += %D%/kitprog.c
+endif
+
+DRIVERHEADERS = \
+ %D%/bitbang.h \
+ %D%/bitq.h \
+ %D%/libusb0_common.h \
+ %D%/libusb1_common.h \
+ %D%/libusb_common.h \
+ %D%/minidriver_imp.h \
+ %D%/mpsse.h \
+ %D%/rlink.h \
+ %D%/rlink_dtc_cmd.h \
+ %D%/rlink_ep1_cmd.h \
+ %D%/rlink_st7.h \
+ %D%/usb_common.h \
+ %D%/versaloon/usbtoxxx/usbtoxxx.h \
+ %D%/versaloon/usbtoxxx/usbtoxxx_internal.h \
+ %D%/versaloon/versaloon.h \
+ %D%/versaloon/versaloon_include.h \
+ %D%/versaloon/versaloon_internal.h
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
diff --git a/src/jtag/drivers/Makefile.rlink b/src/jtag/drivers/Makefile.rlink
index 6a7638e7a..6168332c8 100644
--- a/src/jtag/drivers/Makefile.rlink
+++ b/src/jtag/drivers/Makefile.rlink
@@ -13,9 +13,7 @@
#* GNU 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., *
-#* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+#* along with this program. If not, see . *
#***************************************************************************
TOP = ../../..
diff --git a/src/jtag/drivers/OpenULINK/Makefile b/src/jtag/drivers/OpenULINK/Makefile
index 8ef2d03f9..9f6acc660 100644
--- a/src/jtag/drivers/OpenULINK/Makefile
+++ b/src/jtag/drivers/OpenULINK/Makefile
@@ -13,9 +13,7 @@
# GNU 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., #
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #
+# along with this program. If not, see . #
############################################################################
# Define the name of our tools. Some distributions (e. g. Fedora) prefix
diff --git a/src/jtag/drivers/OpenULINK/include/common.h b/src/jtag/drivers/OpenULINK/include/common.h
index b4f6df9ab..56222fe6c 100644
--- a/src/jtag/drivers/OpenULINK/include/common.h
+++ b/src/jtag/drivers/OpenULINK/include/common.h
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef __COMMON_H
diff --git a/src/jtag/drivers/OpenULINK/include/delay.h b/src/jtag/drivers/OpenULINK/include/delay.h
index 59fb49fa9..ed454be9b 100644
--- a/src/jtag/drivers/OpenULINK/include/delay.h
+++ b/src/jtag/drivers/OpenULINK/include/delay.h
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef __DELAY_H
diff --git a/src/jtag/drivers/OpenULINK/include/io.h b/src/jtag/drivers/OpenULINK/include/io.h
index 8077d325f..a4a8b8acd 100644
--- a/src/jtag/drivers/OpenULINK/include/io.h
+++ b/src/jtag/drivers/OpenULINK/include/io.h
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef __IO_H
diff --git a/src/jtag/drivers/OpenULINK/include/jtag.h b/src/jtag/drivers/OpenULINK/include/jtag.h
index ee2457e1b..fa492b9ed 100644
--- a/src/jtag/drivers/OpenULINK/include/jtag.h
+++ b/src/jtag/drivers/OpenULINK/include/jtag.h
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef __JTAG_H
diff --git a/src/jtag/drivers/OpenULINK/include/main.h b/src/jtag/drivers/OpenULINK/include/main.h
index 5f7418f6c..9e7dd5a86 100644
--- a/src/jtag/drivers/OpenULINK/include/main.h
+++ b/src/jtag/drivers/OpenULINK/include/main.h
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef __MAIN_H
diff --git a/src/jtag/drivers/OpenULINK/include/msgtypes.h b/src/jtag/drivers/OpenULINK/include/msgtypes.h
index 9dbbeddde..f761a845f 100644
--- a/src/jtag/drivers/OpenULINK/include/msgtypes.h
+++ b/src/jtag/drivers/OpenULINK/include/msgtypes.h
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/**
diff --git a/src/jtag/drivers/OpenULINK/include/protocol.h b/src/jtag/drivers/OpenULINK/include/protocol.h
index fbc1996d0..0b6a7d67d 100644
--- a/src/jtag/drivers/OpenULINK/include/protocol.h
+++ b/src/jtag/drivers/OpenULINK/include/protocol.h
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef __PROTOCOL_H
diff --git a/src/jtag/drivers/OpenULINK/include/reg_ezusb.h b/src/jtag/drivers/OpenULINK/include/reg_ezusb.h
index 82f9451ef..4988367db 100644
--- a/src/jtag/drivers/OpenULINK/include/reg_ezusb.h
+++ b/src/jtag/drivers/OpenULINK/include/reg_ezusb.h
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef REG_EZUSB_H
diff --git a/src/jtag/drivers/OpenULINK/include/usb.h b/src/jtag/drivers/OpenULINK/include/usb.h
index 182b79042..9a261fed0 100644
--- a/src/jtag/drivers/OpenULINK/include/usb.h
+++ b/src/jtag/drivers/OpenULINK/include/usb.h
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef __USB_H
diff --git a/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 b/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51
index 8ddd6801b..f10ad484f 100644
--- a/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51
+++ b/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51
@@ -13,9 +13,7 @@
; GNU 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., ;
-; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ;
+; along with this program. If not, see . ;
;--------------------------------------------------------------------------;
.module JUMPTABLE
diff --git a/src/jtag/drivers/OpenULINK/src/delay.c b/src/jtag/drivers/OpenULINK/src/delay.c
index 82569e295..326056768 100644
--- a/src/jtag/drivers/OpenULINK/src/delay.c
+++ b/src/jtag/drivers/OpenULINK/src/delay.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#include "delay.h"
diff --git a/src/jtag/drivers/OpenULINK/src/jtag.c b/src/jtag/drivers/OpenULINK/src/jtag.c
index 9f45ea78e..413945566 100644
--- a/src/jtag/drivers/OpenULINK/src/jtag.c
+++ b/src/jtag/drivers/OpenULINK/src/jtag.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#include "jtag.h"
diff --git a/src/jtag/drivers/OpenULINK/src/main.c b/src/jtag/drivers/OpenULINK/src/main.c
index e4865f8a9..f331c9ebf 100644
--- a/src/jtag/drivers/OpenULINK/src/main.c
+++ b/src/jtag/drivers/OpenULINK/src/main.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#include "main.h"
diff --git a/src/jtag/drivers/OpenULINK/src/protocol.c b/src/jtag/drivers/OpenULINK/src/protocol.c
index 5f7f98428..901f52482 100644
--- a/src/jtag/drivers/OpenULINK/src/protocol.c
+++ b/src/jtag/drivers/OpenULINK/src/protocol.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#include "protocol.h"
diff --git a/src/jtag/drivers/OpenULINK/src/usb.c b/src/jtag/drivers/OpenULINK/src/usb.c
index 98ae67f70..fb77f6482 100644
--- a/src/jtag/drivers/OpenULINK/src/usb.c
+++ b/src/jtag/drivers/OpenULINK/src/usb.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/**
diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c
index 5aacead4b..57c0ce600 100644
--- a/src/jtag/drivers/amt_jtagaccel.c
+++ b/src/jtag/drivers/amt_jtagaccel.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c
index 4c4cc6de1..d9ea367ce 100644
--- a/src/jtag/drivers/arm-jtag-ew.c
+++ b/src/jtag/drivers/arm-jtag-ew.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/at91rm9200.c b/src/jtag/drivers/at91rm9200.c
index d7e11df24..8f65413a2 100644
--- a/src/jtag/drivers/at91rm9200.c
+++ b/src/jtag/drivers/at91rm9200.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c
index e1cc56c24..a41caf073 100644
--- a/src/jtag/drivers/bcm2835gpio.c
+++ b/src/jtag/drivers/bcm2835gpio.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -470,8 +468,8 @@ static int bcm2835gpio_init(void)
return ERROR_JTAG_INIT_FAILED;
}
- /* set 16mA drive strength */
- pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000018 + 7;
+ /* set 4mA drive strength, slew rate limited, hysteresis on */
+ pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
tdo_gpio_mode = MODE_GPIO(tdo_gpio);
tdi_gpio_mode = MODE_GPIO(tdi_gpio);
diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c
index 1a0fa1c9d..c9ec9c9d6 100644
--- a/src/jtag/drivers/bitbang.c
+++ b/src/jtag/drivers/bitbang.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* 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 1bdb8f5fc..c5b44bfd5 100644
--- a/src/jtag/drivers/bitbang.h
+++ b/src/jtag/drivers/bitbang.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef BITBANG_H
-#define BITBANG_H
+#ifndef OPENOCD_JTAG_DRIVERS_BITBANG_H
+#define OPENOCD_JTAG_DRIVERS_BITBANG_H
#include
@@ -47,4 +45,4 @@ extern struct bitbang_interface *bitbang_interface;
void bitbang_switch_to_swd(void);
int bitbang_swd_switch_seq(enum swd_special_seq seq);
-#endif /* BITBANG_H */
+#endif /* OPENOCD_JTAG_DRIVERS_BITBANG_H */
diff --git a/src/jtag/drivers/bitq.c b/src/jtag/drivers/bitq.c
index 1d0ff09b6..66285f700 100644
--- a/src/jtag/drivers/bitq.c
+++ b/src/jtag/drivers/bitq.c
@@ -13,9 +13,7 @@
* GNU 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., *
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+* along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/bitq.h b/src/jtag/drivers/bitq.h
index f54de951f..df6a08d44 100644
--- a/src/jtag/drivers/bitq.h
+++ b/src/jtag/drivers/bitq.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef BITQ_H
-#define BITQ_H
+#ifndef OPENOCD_JTAG_DRIVERS_BITQ_H
+#define OPENOCD_JTAG_DRIVERS_BITQ_H
#include
@@ -44,4 +42,4 @@ int bitq_execute_queue(void);
void bitq_cleanup(void);
-#endif /* BITQ_H */
+#endif /* OPENOCD_JTAG_DRIVERS_BITQ_H */
diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c
index 554d3e0ef..aa0d8cc3f 100644
--- a/src/jtag/drivers/buspirate.c
+++ b/src/jtag/drivers/buspirate.c
@@ -14,9 +14,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c
index ff8b8ffaf..86f796877 100644
--- a/src/jtag/drivers/cmsis_dap_usb.c
+++ b/src/jtag/drivers/cmsis_dap_usb.c
@@ -1,4 +1,10 @@
/***************************************************************************
+ * Copyright (C) 2016 by Maksym Hilliaka *
+ * oter@frozen-team.com *
+ * *
+ * Copyright (C) 2016 by Phillip Pearson *
+ * pp@myelin.co.nz *
+ * *
* Copyright (C) 2014 by Paul Fertser *
* fercerpav@gmail.com *
* *
@@ -19,9 +25,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -114,6 +118,13 @@ static bool swd_mode;
* Bit 7: nRESET
*/
+#define SWJ_PIN_TCK (1<<0)
+#define SWJ_PIN_TMS (1<<1)
+#define SWJ_PIN_TDI (1<<2)
+#define SWJ_PIN_TDO (1<<3)
+#define SWJ_PIN_TRST (1<<5)
+#define SWJ_PIN_SRST (1<<7)
+
/* CMSIS-DAP SWD Commands */
#define CMD_DAP_SWD_CONFIGURE 0x13
@@ -122,6 +133,15 @@ static bool swd_mode;
#define CMD_DAP_JTAG_CONFIGURE 0x15
#define CMD_DAP_JTAG_IDCODE 0x16
+/* CMSIS-DAP JTAG sequence info masks */
+/* Number of bits to clock through (0 means 64) */
+#define DAP_JTAG_SEQ_TCK 0x3F
+/* TMS will be set during the sequence if this bit is set */
+#define DAP_JTAG_SEQ_TMS 0x40
+/* TDO output will be captured if this bit is set */
+#define DAP_JTAG_SEQ_TDO 0x80
+
+
/* CMSIS-DAP Transfer Commands */
#define CMD_DAP_TFER_CONFIGURE 0x04
#define CMD_DAP_TFER 0x05
@@ -158,9 +178,32 @@ struct pending_transfer_result {
void *buffer;
};
+struct pending_scan_result {
+ /** Offset in bytes in the CMD_DAP_JTAG_SEQ response buffer. */
+ unsigned first;
+ /** Number of bits to read. */
+ unsigned length;
+ /** Location to store the result */
+ uint8_t *buffer;
+ /** Offset in the destination buffer */
+ unsigned buffer_offset;
+};
+
static int pending_transfer_count, pending_queue_len;
static struct pending_transfer_result *pending_transfers;
+/* pointers to buffers that will receive jtag scan results on the next flush */
+#define MAX_PENDING_SCAN_RESULTS 256
+static int pending_scan_result_count;
+static struct pending_scan_result pending_scan_results[MAX_PENDING_SCAN_RESULTS];
+
+/* queued JTAG sequences that will be executed on the next flush */
+#define QUEUED_SEQ_BUF_LEN (cmsis_dap_handle->packet_size - 3)
+static int queued_seq_count;
+static int queued_seq_buf_end;
+static int queued_seq_tdo_ptr;
+static uint8_t queued_seq_buf[1024]; /* TODO: make dynamic / move into cmsis object */
+
static int queued_retval;
static struct cmsis_dap *cmsis_dap_handle;
@@ -214,12 +257,14 @@ static int cmsis_dap_usb_open(void)
/* we have found an adapter, so exit further checks */
/* check serial number matches if given */
if (cmsis_dap_serial != NULL) {
- if (wcscmp(cmsis_dap_serial, cur_dev->serial_number) == 0) {
+ if ((cur_dev->serial_number != NULL) && wcscmp(cmsis_dap_serial, cur_dev->serial_number) == 0) {
serial_found = true;
break;
}
} else
break;
+
+ found = false;
}
cur_dev = cur_dev->next;
@@ -271,9 +316,11 @@ static int cmsis_dap_usb_open(void)
int packet_size = PACKET_SIZE;
/* atmel cmsis-dap uses 512 byte reports */
+ /* except when it doesn't e.g. with mEDBG on SAMD10 Xplained
+ * board */
/* TODO: HID report descriptor should be parsed instead of
* hardcoding a match by VID */
- if (target_vid == 0x03eb)
+ if (target_vid == 0x03eb && target_pid != 0x2145)
packet_size = 512 + 1;
cmsis_dap_handle->packet_buffer = malloc(packet_size);
@@ -306,6 +353,9 @@ static void cmsis_dap_usb_close(struct cmsis_dap *dap)
/* Send a message and receive the reply */
static int cmsis_dap_usb_xfer(struct cmsis_dap *dap, int txlen)
{
+#ifdef CMSIS_DAP_JTAG_DEBUG
+ LOG_DEBUG("cmsis-dap usb xfer cmd=%02X", dap->packet_buffer[1]);
+#endif
/* Pad the rest of the TX buffer with 0's */
memset(dap->packet_buffer + txlen, 0, dap->packet_size - txlen);
@@ -375,6 +425,33 @@ static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock)
return ERROR_OK;
}
+/* clock a sequence of bits out on TMS, to change JTAG states */
+static int cmsis_dap_cmd_DAP_SWJ_Sequence(uint8_t s_len, const uint8_t *sequence)
+{
+ int retval;
+ uint8_t *buffer = cmsis_dap_handle->packet_buffer;
+
+#ifdef CMSIS_DAP_JTAG_DEBUG
+ LOG_DEBUG("cmsis-dap TMS sequence: len=%d", s_len);
+ for (int i = 0; i < DIV_ROUND_UP(s_len, 8); ++i)
+ printf("%02X ", sequence[i]);
+
+ printf("\n");
+#endif
+
+ buffer[0] = 0; /* report number */
+ buffer[1] = CMD_DAP_SWJ_SEQ;
+ buffer[2] = s_len;
+ bit_copy(&buffer[3], 0, sequence, 0, s_len);
+
+ retval = cmsis_dap_usb_xfer(cmsis_dap_handle, DIV_ROUND_UP(s_len, 8) + 3);
+
+ if (retval != ERROR_OK || buffer[1] != DAP_OK)
+ return ERROR_FAIL;
+
+ return ERROR_OK;
+}
+
static int cmsis_dap_cmd_DAP_Info(uint8_t info, uint8_t **data)
{
int retval;
@@ -696,12 +773,12 @@ static int cmsis_dap_get_status(void)
if (retval == ERROR_OK) {
LOG_INFO("SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d",
- (d & (0x01 << 0)) ? 1 : 0, /* Bit 0: SWCLK/TCK */
- (d & (0x01 << 1)) ? 1 : 0, /* Bit 1: SWDIO/TMS */
- (d & (0x01 << 2)) ? 1 : 0, /* Bit 2: TDI */
- (d & (0x01 << 3)) ? 1 : 0, /* Bit 3: TDO */
- (d & (0x01 << 5)) ? 1 : 0, /* Bit 5: nTRST */
- (d & (0x01 << 7)) ? 1 : 0); /* Bit 7: nRESET */
+ (d & SWJ_PIN_TCK) ? 1 : 0,
+ (d & SWJ_PIN_TMS) ? 1 : 0,
+ (d & SWJ_PIN_TDI) ? 1 : 0,
+ (d & SWJ_PIN_TDO) ? 1 : 0,
+ (d & SWJ_PIN_TRST) ? 1 : 0,
+ (d & SWJ_PIN_SRST) ? 1 : 0);
}
return retval;
@@ -709,7 +786,6 @@ static int cmsis_dap_get_status(void)
static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
{
- uint8_t *buffer = cmsis_dap_handle->packet_buffer;
const uint8_t *s;
unsigned int s_len;
int retval;
@@ -745,17 +821,13 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
return ERROR_FAIL;
}
- buffer[0] = 0; /* report number */
- buffer[1] = CMD_DAP_SWJ_SEQ;
- buffer[2] = s_len;
- bit_copy(&buffer[3], 0, s, 0, s_len);
-
- retval = cmsis_dap_usb_xfer(cmsis_dap_handle, DIV_ROUND_UP(s_len, 8) + 3);
-
- if (retval != ERROR_OK || buffer[1] != DAP_OK)
- return ERROR_FAIL;
+ retval = cmsis_dap_cmd_DAP_SWJ_Sequence(s_len, s);
+ if (retval != ERROR_OK)
+ return retval;
- return ERROR_OK;
+ /* Atmel EDBG needs renew clock setting after SWJ_Sequence
+ * otherwise default frequency is used */
+ return cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz());
}
static int cmsis_dap_swd_open(void)
@@ -933,8 +1005,17 @@ static int cmsis_dap_quit(void)
static void cmsis_dap_execute_reset(struct jtag_command *cmd)
{
- int retval = cmsis_dap_cmd_DAP_SWJ_Pins(cmd->cmd.reset->srst ? 0 : (1 << 7), \
- (1 << 7), 0, NULL);
+ /* Set both TRST and SRST even if they're not enabled as
+ * there's no way to tristate them */
+ uint8_t pins = 0;
+
+ if (!cmd->cmd.reset->srst)
+ pins |= SWJ_PIN_SRST;
+ if (!cmd->cmd.reset->trst)
+ pins |= SWJ_PIN_TRST;
+
+ int retval = cmsis_dap_cmd_DAP_SWJ_Pins(pins,
+ SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL);
if (retval != ERROR_OK)
LOG_ERROR("CMSIS-DAP: Interface reset failed");
}
@@ -948,17 +1029,456 @@ static void cmsis_dap_execute_sleep(struct jtag_command *cmd)
jtag_sleep(cmd->cmd.sleep->us);
}
+/* Set TMS high for five TCK clocks, to move the TAP to the Test-Logic-Reset state */
+static int cmsis_dap_execute_tlr_reset(struct jtag_command *cmd)
+{
+ LOG_INFO("cmsis-dap JTAG TLR_RESET");
+ uint8_t seq = 0xff;
+ int ret = cmsis_dap_cmd_DAP_SWJ_Sequence(8, &seq);
+ if (ret == ERROR_OK)
+ tap_set_state(TAP_RESET);
+ return ret;
+}
+
+/* Set new end state */
+static void cmsis_dap_end_state(tap_state_t state)
+{
+ if (tap_is_state_stable(state))
+ tap_set_end_state(state);
+ else {
+ LOG_ERROR("BUG: %i is not a valid end state", state);
+ exit(-1);
+ }
+}
+
+#ifdef SPRINT_BINARY
+static void sprint_binary(char *s, const uint8_t *buf, int offset, int len)
+{
+ if (!len)
+ return;
+
+ /*
+ buf = { 0x18 } len=5 should result in: 11000
+ buf = { 0xff 0x18 } len=13 should result in: 11111111 11000
+ buf = { 0xc0 0x18 } offset=3 len=10 should result in: 11000 11000
+ i=3 there means i/8 = 0 so c = 0xFF, and
+ */
+ for (int i = offset; i < offset + len; ++i) {
+ uint8_t c = buf[i / 8], mask = 1 << (i % 8);
+ if ((i != offset) && !(i % 8))
+ putchar(' ');
+ *s++ = (c & mask) ? '1' : '0';
+ }
+ *s = 0;
+}
+#endif
+
+#ifdef CMSIS_DAP_JTAG_DEBUG
+static void debug_parse_cmsis_buf(const uint8_t *cmd, int cmdlen)
+{
+ /* cmd is a usb packet to go to the cmsis-dap interface */
+ printf("cmsis-dap buffer (%d b): ", cmdlen);
+ for (int i = 0; i < cmdlen; ++i)
+ printf(" %02x", cmd[i]);
+ printf("\n");
+ switch (cmd[1]) {
+ case CMD_DAP_JTAG_SEQ: {
+ printf("cmsis-dap jtag sequence command %02x (n=%d)\n", cmd[1], cmd[2]);
+ /*
+ * #2 = number of sequences
+ * #3 = sequence info 1
+ * #4...4+n_bytes-1 = sequence 1
+ * #4+n_bytes = sequence info 2
+ * #5+n_bytes = sequence 2 (single bit)
+ */
+ int pos = 3;
+ for (int seq = 0; seq < cmd[2]; ++seq) {
+ uint8_t info = cmd[pos++];
+ int len = info & DAP_JTAG_SEQ_TCK;
+ if (len == 0)
+ len = 64;
+ printf(" sequence %d starting %d: info %02x (len=%d tms=%d read_tdo=%d): ",
+ seq, pos, info, len, info & DAP_JTAG_SEQ_TMS, info & DAP_JTAG_SEQ_TDO);
+ for (int i = 0; i < DIV_ROUND_UP(len, 8); ++i)
+ printf(" %02x", cmd[pos+i]);
+ pos += DIV_ROUND_UP(len, 8);
+ printf("\n");
+ }
+ if (pos != cmdlen) {
+ printf("BUFFER LENGTH MISMATCH looks like %d but %d specified", pos, cmdlen);
+ exit(-1);
+ }
+
+ break;
+ }
+ default:
+ LOG_DEBUG("unknown cmsis-dap command %02x", cmd[1]);
+ break;
+ }
+}
+#endif
+
+static void cmsis_dap_flush(void)
+{
+ if (!queued_seq_count)
+ return;
+
+ DEBUG_JTAG_IO("Flushing %d queued sequences (%d bytes) with %d pending scan results to capture",
+ queued_seq_count, queued_seq_buf_end, pending_scan_result_count);
+
+ /* prep CMSIS-DAP packet */
+ uint8_t *buffer = cmsis_dap_handle->packet_buffer;
+ buffer[0] = 0; /* report number */
+ buffer[1] = CMD_DAP_JTAG_SEQ;
+ buffer[2] = queued_seq_count;
+ memcpy(buffer + 3, queued_seq_buf, queued_seq_buf_end);
+
+#ifdef CMSIS_DAP_JTAG_DEBUG
+ debug_parse_cmsis_buf(buffer, queued_seq_buf_end + 3);
+#endif
+
+ /* send command to USB device */
+ int retval = cmsis_dap_usb_xfer(cmsis_dap_handle, queued_seq_buf_end + 3);
+ if (retval != ERROR_OK || buffer[1] != DAP_OK) {
+ LOG_ERROR("CMSIS-DAP command CMD_DAP_JTAG_SEQ failed.");
+ exit(-1);
+ }
+
+#ifdef CMSIS_DAP_JTAG_DEBUG
+ DEBUG_JTAG_IO("USB response buf:");
+ for (int c = 0; c < queued_seq_buf_end + 3; ++c)
+ printf("%02X ", buffer[c]);
+ printf("\n");
+#endif
+
+ /* copy scan results into client buffers */
+ for (int i = 0; i < pending_scan_result_count; ++i) {
+ struct pending_scan_result *scan = &pending_scan_results[i];
+ DEBUG_JTAG_IO("Copying pending_scan_result %d/%d: %d bits from byte %d -> buffer + %d bits",
+ i, pending_scan_result_count, scan->length, scan->first + 2, scan->buffer_offset);
+#ifdef CMSIS_DAP_JTAG_DEBUG
+ for (uint32_t b = 0; b < DIV_ROUND_UP(scan->length, 8); ++b)
+ printf("%02X ", buffer[2+scan->first+b]);
+ printf("\n");
+#endif
+ bit_copy(scan->buffer, scan->buffer_offset, buffer + 2 + scan->first, 0, scan->length);
+ }
+
+ /* reset */
+ queued_seq_count = 0;
+ queued_seq_buf_end = 0;
+ queued_seq_tdo_ptr = 0;
+ pending_scan_result_count = 0;
+}
+
+/* queue a sequence of bits to clock out TDI / in TDO, executing if the buffer is full.
+ *
+ * sequence=NULL means clock out zeros on TDI
+ * tdo_buffer=NULL means don't capture TDO
+ */
+static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int s_offset,
+ bool tms, uint8_t *tdo_buffer, int tdo_buffer_offset)
+{
+ DEBUG_JTAG_IO("[at %d] %d bits, tms %s, seq offset %d, tdo buf %p, tdo offset %d",
+ queued_seq_buf_end,
+ s_len, tms ? "HIGH" : "LOW", s_offset, tdo_buffer, tdo_buffer_offset);
+
+ if (s_len == 0)
+ return;
+
+ if (s_len > 64) {
+ DEBUG_JTAG_IO("START JTAG SEQ SPLIT");
+ for (int offset = 0; offset < s_len; offset += 64) {
+ int len = s_len - offset;
+ if (len > 64)
+ len = 64;
+ DEBUG_JTAG_IO("Splitting long jtag sequence: %d-bit chunk starting at offset %d", len, offset);
+ cmsis_dap_add_jtag_sequence(
+ len,
+ sequence,
+ s_offset + offset,
+ tms,
+ tdo_buffer,
+ tdo_buffer == NULL ? 0 : (tdo_buffer_offset + offset)
+ );
+ }
+ DEBUG_JTAG_IO("END JTAG SEQ SPLIT");
+ return;
+ }
+
+ int cmd_len = 1 + DIV_ROUND_UP(s_len, 8);
+ if (queued_seq_count >= 255 || queued_seq_buf_end + cmd_len > QUEUED_SEQ_BUF_LEN)
+ /* empty out the buffer */
+ cmsis_dap_flush();
+
+ ++queued_seq_count;
+
+ /* control byte */
+ queued_seq_buf[queued_seq_buf_end] =
+ (tms ? DAP_JTAG_SEQ_TMS : 0) |
+ (tdo_buffer != NULL ? DAP_JTAG_SEQ_TDO : 0) |
+ (s_len == 64 ? 0 : s_len);
+
+ if (sequence != NULL)
+ bit_copy(&queued_seq_buf[queued_seq_buf_end + 1], 0, sequence, s_offset, s_len);
+ else
+ memset(&queued_seq_buf[queued_seq_buf_end + 1], 0, DIV_ROUND_UP(s_len, 8));
+
+ queued_seq_buf_end += cmd_len;
+
+ if (tdo_buffer != NULL) {
+ struct pending_scan_result *scan = &pending_scan_results[pending_scan_result_count++];
+ scan->first = queued_seq_tdo_ptr;
+ queued_seq_tdo_ptr += DIV_ROUND_UP(s_len, 8);
+ scan->length = s_len;
+ scan->buffer = tdo_buffer;
+ scan->buffer_offset = tdo_buffer_offset;
+ }
+}
+
+/* queue a sequence of bits to clock out TMS, executing if the buffer is full */
+static void cmsis_dap_add_tms_sequence(const uint8_t *sequence, int s_len)
+{
+ DEBUG_JTAG_IO("%d bits: %02X", s_len, *sequence);
+ /* we use a series of CMD_DAP_JTAG_SEQ commands to toggle TMS,
+ because even though it seems ridiculously inefficient, it
+ allows us to combine TMS and scan sequences into the same
+ USB packet. */
+ /* TODO: combine runs of the same tms value */
+ for (int i = 0; i < s_len; ++i) {
+ bool bit = (sequence[i / 8] & (1 << (i % 8))) != 0;
+ cmsis_dap_add_jtag_sequence(1, NULL, 0, bit, NULL, 0);
+ }
+}
+
+/* Move to the end state by queuing a sequence to clock into TMS */
+static void cmsis_dap_state_move(void)
+{
+ uint8_t tms_scan;
+ uint8_t tms_scan_bits;
+
+ tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
+ tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
+
+ DEBUG_JTAG_IO("state move from %s to %s: %d clocks, %02X on tms",
+ tap_state_name(tap_get_state()), tap_state_name(tap_get_end_state()),
+ tms_scan_bits, tms_scan);
+ cmsis_dap_add_tms_sequence(&tms_scan, tms_scan_bits);
+
+ tap_set_state(tap_get_end_state());
+}
+
+
+/* Execute a JTAG scan operation by queueing TMS and TDI/TDO sequences */
+static void cmsis_dap_execute_scan(struct jtag_command *cmd)
+{
+ DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN",
+ jtag_scan_type(cmd->cmd.scan));
+
+ /* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */
+ while (cmd->cmd.scan->num_fields > 0
+ && cmd->cmd.scan->fields[cmd->cmd.scan->num_fields - 1].num_bits == 0) {
+ cmd->cmd.scan->num_fields--;
+ LOG_DEBUG("discarding trailing empty field");
+ }
+
+ if (cmd->cmd.scan->num_fields == 0) {
+ LOG_DEBUG("empty scan, doing nothing");
+ return;
+ }
+
+ if (cmd->cmd.scan->ir_scan) {
+ if (tap_get_state() != TAP_IRSHIFT) {
+ cmsis_dap_end_state(TAP_IRSHIFT);
+ cmsis_dap_state_move();
+ }
+ } else {
+ if (tap_get_state() != TAP_DRSHIFT) {
+ cmsis_dap_end_state(TAP_DRSHIFT);
+ cmsis_dap_state_move();
+ }
+ }
+
+ cmsis_dap_end_state(cmd->cmd.scan->end_state);
+
+ struct scan_field *field = cmd->cmd.scan->fields;
+ unsigned scan_size = 0;
+
+ for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
+ scan_size += field->num_bits;
+ DEBUG_JTAG_IO("%s%s field %d/%d %d bits",
+ field->in_value ? "in" : "",
+ field->out_value ? "out" : "",
+ i,
+ cmd->cmd.scan->num_fields,
+ field->num_bits);
+
+ if (i == cmd->cmd.scan->num_fields - 1 && tap_get_state() != tap_get_end_state()) {
+ DEBUG_JTAG_IO("Last field and have to move out of SHIFT state");
+ /* Last field, and we're leaving IRSHIFT/DRSHIFT. Clock last bit during tap
+ * movement. This last field can't have length zero, it was checked above. */
+ cmsis_dap_add_jtag_sequence(
+ field->num_bits - 1, /* number of bits to clock */
+ field->out_value, /* output sequence */
+ 0, /* output offset */
+ false, /* TMS low */
+ field->in_value,
+ 0);
+
+ /* Clock the last bit out, with TMS high */
+ uint8_t last_bit = 0;
+ if (field->out_value)
+ bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);
+ cmsis_dap_add_jtag_sequence(
+ 1,
+ &last_bit,
+ 0,
+ true,
+ field->in_value,
+ field->num_bits - 1);
+ tap_set_state(tap_state_transition(tap_get_state(), 1));
+
+ /* Now clock one more cycle, with TMS low, to get us into a PAUSE state */
+ cmsis_dap_add_jtag_sequence(
+ 1,
+ &last_bit,
+ 0,
+ false,
+ NULL,
+ 0);
+ tap_set_state(tap_state_transition(tap_get_state(), 0));
+ } else {
+ DEBUG_JTAG_IO("Internal field, staying in SHIFT state afterwards");
+ /* Clocking part of a sequence into DR or IR with TMS=0,
+ leaving TMS=0 at the end so we can continue later */
+ cmsis_dap_add_jtag_sequence(
+ field->num_bits,
+ field->out_value,
+ 0,
+ false,
+ field->in_value,
+ 0);
+ }
+ }
+
+ if (tap_get_state() != tap_get_end_state()) {
+ cmsis_dap_end_state(tap_get_end_state());
+ cmsis_dap_state_move();
+ }
+
+ DEBUG_JTAG_IO("%s scan, %i bits, end in %s",
+ (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
+ tap_state_name(tap_get_end_state()));
+}
+
+static void cmsis_dap_pathmove(int num_states, tap_state_t *path)
+{
+ int i;
+ uint8_t tms0 = 0x00;
+ uint8_t tms1 = 0xff;
+
+ for (i = 0; i < num_states; i++) {
+ if (path[i] == tap_state_transition(tap_get_state(), false))
+ cmsis_dap_add_tms_sequence(&tms0, 1);
+ else if (path[i] == tap_state_transition(tap_get_state(), true))
+ cmsis_dap_add_tms_sequence(&tms1, 1);
+ else {
+ LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition.",
+ tap_state_name(tap_get_state()), tap_state_name(path[i]));
+ exit(-1);
+ }
+
+ tap_set_state(path[i]);
+ }
+
+ cmsis_dap_end_state(tap_get_state());
+}
+
+static void cmsis_dap_execute_pathmove(struct jtag_command *cmd)
+{
+ DEBUG_JTAG_IO("pathmove: %i states, end in %i",
+ cmd->cmd.pathmove->num_states,
+ cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
+
+ cmsis_dap_pathmove(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
+}
+
+static void cmsis_dap_stableclocks(int num_cycles)
+{
+ int i;
+
+ uint8_t tms = tap_get_state() == TAP_RESET;
+ /* TODO: Perform optimizations? */
+ /* Execute num_cycles. */
+ for (i = 0; i < num_cycles; i++)
+ cmsis_dap_add_tms_sequence(&tms, 1);
+}
+
+static void cmsis_dap_runtest(int num_cycles)
+{
+ tap_state_t saved_end_state = tap_get_end_state();
+
+ /* Only do a state_move when we're not already in IDLE. */
+ if (tap_get_state() != TAP_IDLE) {
+ cmsis_dap_end_state(TAP_IDLE);
+ cmsis_dap_state_move();
+ }
+ cmsis_dap_stableclocks(num_cycles);
+
+ /* Finish in end_state. */
+ cmsis_dap_end_state(saved_end_state);
+
+ if (tap_get_state() != tap_get_end_state())
+ cmsis_dap_state_move();
+}
+
+static void cmsis_dap_execute_runtest(struct jtag_command *cmd)
+{
+ DEBUG_JTAG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
+ cmd->cmd.runtest->end_state);
+
+ cmsis_dap_end_state(cmd->cmd.runtest->end_state);
+ cmsis_dap_runtest(cmd->cmd.runtest->num_cycles);
+}
+
+static void cmsis_dap_execute_stableclocks(struct jtag_command *cmd)
+{
+ DEBUG_JTAG_IO("stableclocks %i cycles", cmd->cmd.runtest->num_cycles);
+ cmsis_dap_stableclocks(cmd->cmd.runtest->num_cycles);
+}
+
+/* TODO: Is there need to call cmsis_dap_flush() for the JTAG_PATHMOVE,
+ * JTAG_RUNTEST, JTAG_STABLECLOCKS? */
static void cmsis_dap_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
case JTAG_RESET:
+ cmsis_dap_flush();
cmsis_dap_execute_reset(cmd);
break;
case JTAG_SLEEP:
+ cmsis_dap_flush();
cmsis_dap_execute_sleep(cmd);
break;
+ case JTAG_TLR_RESET:
+ cmsis_dap_flush();
+ cmsis_dap_execute_tlr_reset(cmd);
+ break;
+ case JTAG_SCAN:
+ cmsis_dap_execute_scan(cmd);
+ break;
+ case JTAG_PATHMOVE:
+ cmsis_dap_execute_pathmove(cmd);
+ break;
+ case JTAG_RUNTEST:
+ cmsis_dap_execute_runtest(cmd);
+ break;
+ case JTAG_STABLECLOCKS:
+ cmsis_dap_execute_stableclocks(cmd);
+ break;
+ case JTAG_TMS:
default:
- LOG_ERROR("BUG: unknown JTAG command type encountered");
+ LOG_ERROR("BUG: unknown JTAG command type 0x%X encountered", cmd->type);
exit(-1);
}
}
@@ -972,18 +1492,18 @@ static int cmsis_dap_execute_queue(void)
cmd = cmd->next;
}
+ cmsis_dap_flush();
+
return ERROR_OK;
}
static int cmsis_dap_speed(int speed)
{
- if (speed > DAP_MAX_CLOCK) {
- LOG_INFO("reduce speed request: %dkHz to %dkHz maximum", speed, DAP_MAX_CLOCK);
- speed = DAP_MAX_CLOCK;
- }
+ if (speed > DAP_MAX_CLOCK)
+ LOG_INFO("High speed (adapter_khz %d) may be limited by adapter firmware.", speed);
if (speed == 0) {
- LOG_INFO("RTCK not supported");
+ LOG_ERROR("RTCK not supported. Set nonzero adapter_khz.");
return ERROR_JTAG_NOT_IMPLEMENTED;
}
@@ -1010,6 +1530,7 @@ static int_least32_t cmsis_dap_swd_frequency(int_least32_t hz)
return hz;
}
+
COMMAND_HANDLER(cmsis_dap_handle_info_command)
{
if (cmsis_dap_get_version_info() == ERROR_OK)
@@ -1114,7 +1635,7 @@ static const struct swd_driver cmsis_dap_swd_driver = {
.run = cmsis_dap_swd_run_queue,
};
-static const char * const cmsis_dap_transport[] = { "swd", NULL };
+static const char * const cmsis_dap_transport[] = { "swd", "jtag", NULL };
struct jtag_interface cmsis_dap_interface = {
.name = "cmsis-dap",
diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c
index 75ec115ed..daf7cd426 100644
--- a/src/jtag/drivers/driver.c
+++ b/src/jtag/drivers/driver.c
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c
index ddba976d0..0f7c12dd4 100644
--- a/src/jtag/drivers/dummy.c
+++ b/src/jtag/drivers/dummy.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/ep93xx.c b/src/jtag/drivers/ep93xx.c
index 8e12e1728..ccd979502 100644
--- a/src/jtag/drivers/ep93xx.c
+++ b/src/jtag/drivers/ep93xx.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c
index d8c7d6422..26bc53d54 100644
--- a/src/jtag/drivers/ftdi.c
+++ b/src/jtag/drivers/ftdi.c
@@ -13,9 +13,7 @@
* GNU 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., *
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+* along with this program. If not, see . *
***************************************************************************/
/**
@@ -86,11 +84,14 @@
#include "mpsse.h"
#define JTAG_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
+#define JTAG_MODE_ALT (LSB_FIRST | NEG_EDGE_IN | NEG_EDGE_OUT)
#define SWD_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
static char *ftdi_device_desc;
static char *ftdi_serial;
+static char *ftdi_location;
static uint8_t ftdi_channel;
+static uint8_t ftdi_jtag_mode = JTAG_MODE;
static bool swd_mode;
@@ -104,8 +105,10 @@ static struct mpsse_ctx *mpsse_ctx;
struct signal {
const char *name;
uint16_t data_mask;
+ uint16_t input_mask;
uint16_t oe_mask;
bool invert_data;
+ bool invert_input;
bool invert_oe;
struct signal *next;
};
@@ -210,6 +213,32 @@ static int ftdi_set_signal(const struct signal *s, char value)
return ERROR_OK;
}
+static int ftdi_get_signal(const struct signal *s, uint16_t * value_out)
+{
+ uint8_t data_low = 0;
+ uint8_t data_high = 0;
+
+ if (s->input_mask == 0) {
+ LOG_ERROR("interface doesn't provide signal '%s'", s->name);
+ return ERROR_FAIL;
+ }
+
+ if (s->input_mask & 0xff)
+ mpsse_read_data_bits_low_byte(mpsse_ctx, &data_low);
+ if (s->input_mask >> 8)
+ mpsse_read_data_bits_high_byte(mpsse_ctx, &data_high);
+
+ mpsse_flush(mpsse_ctx);
+
+ *value_out = (((uint16_t)data_high) << 8) | data_low;
+
+ if (s->invert_input)
+ *value_out = ~(*value_out);
+
+ *value_out &= s->input_mask;
+
+ return ERROR_OK;
+}
/**
* Function move_to_state
@@ -244,7 +273,7 @@ static void move_to_state(tap_state_t goal_state)
0,
tms_count,
false,
- JTAG_MODE);
+ ftdi_jtag_mode);
}
static int ftdi_speed(int speed)
@@ -257,6 +286,9 @@ static int ftdi_speed(int speed)
return retval;
}
+ if (!swd_mode && speed >= 10000000 && ftdi_jtag_mode != JTAG_MODE_ALT)
+ LOG_INFO("ftdi: if you experience problems at higher adapter clocks, try "
+ "the command \"ftdi_tdo_sample_edge falling\"");
return ERROR_OK;
}
@@ -304,7 +336,7 @@ static void ftdi_execute_runtest(struct jtag_command *cmd)
while (i > 0) {
/* there are no state transitions in this code, so omit state tracking */
unsigned this_len = i > 7 ? 7 : i;
- mpsse_clock_tms_cs_out(mpsse_ctx, &zero, 0, this_len, false, JTAG_MODE);
+ mpsse_clock_tms_cs_out(mpsse_ctx, &zero, 0, this_len, false, ftdi_jtag_mode);
i -= this_len;
}
@@ -344,7 +376,7 @@ static void ftdi_execute_tms(struct jtag_command *cmd)
0,
cmd->cmd.tms->num_bits,
false,
- JTAG_MODE);
+ ftdi_jtag_mode);
}
static void ftdi_execute_pathmove(struct jtag_command *cmd)
@@ -391,17 +423,51 @@ static void ftdi_execute_pathmove(struct jtag_command *cmd)
0,
bit_count,
false,
- JTAG_MODE);
+ ftdi_jtag_mode);
bit_count = 0;
}
}
tap_set_end_state(tap_get_state());
}
+#if BUILD_RISCV == 1
+#ifdef _DEBUG_JTAG_IO_
+static void debug_jtag_io_value(const char *prefix, const uint8_t *value,
+ unsigned int num_bits)
+{
+ if (!value) {
+ return;
+ }
+
+ char buf[33];
+ char *bufp = buf;
+ unsigned int chars = (num_bits + 3) / 4;
+ for (unsigned int i = 0; i < chars; i++) {
+ if (i && (i % 32) == 0) {
+ DEBUG_JTAG_IO(" %s%s", prefix, buf);
+ bufp = buf;
+ }
+ int start_bit = 4 * (chars - i - 1);
+ sprintf(bufp, "%01x", buf_get_u32(value, start_bit, 4));
+ bufp++;
+ }
+ if (bufp != buf) {
+ DEBUG_JTAG_IO(" %s%s", prefix, buf);
+ }
+}
+#endif
+#endif
+
static void ftdi_execute_scan(struct jtag_command *cmd)
{
DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN",
jtag_scan_type(cmd->cmd.scan));
+#if BUILD_RISCV == 1
+#ifdef _DEBUG_JTAG_IO_
+ debug_jtag_io_value(" out=", cmd->cmd.scan->fields->out_value,
+ cmd->cmd.scan->fields->num_bits);
+#endif
+#endif
/* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */
while (cmd->cmd.scan->num_fields > 0
@@ -446,7 +512,7 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
field->in_value,
0,
field->num_bits - 1,
- JTAG_MODE);
+ ftdi_jtag_mode);
uint8_t last_bit = 0;
if (field->out_value)
bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);
@@ -458,14 +524,14 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
field->num_bits - 1,
1,
last_bit,
- JTAG_MODE);
+ ftdi_jtag_mode);
tap_set_state(tap_state_transition(tap_get_state(), 1));
mpsse_clock_tms_cs_out(mpsse_ctx,
&tms_bits,
1,
1,
last_bit,
- JTAG_MODE);
+ ftdi_jtag_mode);
tap_set_state(tap_state_transition(tap_get_state(), 0));
} else
mpsse_clock_data(mpsse_ctx,
@@ -474,7 +540,7 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
field->in_value,
0,
field->num_bits,
- JTAG_MODE);
+ ftdi_jtag_mode);
}
if (tap_get_state() != tap_get_end_state())
@@ -483,6 +549,13 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
DEBUG_JTAG_IO("%s scan, %i bits, end in %s",
(cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
tap_state_name(tap_get_end_state()));
+
+#if BUILD_RISCV == 1
+#ifdef _DEBUG_JTAG_IO_
+ debug_jtag_io_value(" in=", cmd->cmd.scan->fields->in_value,
+ cmd->cmd.scan->fields->num_bits);
+#endif
+#endif
}
static void ftdi_execute_reset(struct jtag_command *cmd)
@@ -553,7 +626,7 @@ static void ftdi_execute_stableclocks(struct jtag_command *cmd)
while (num_cycles > 0) {
/* there are no state transitions in this code, so omit state tracking */
unsigned this_len = num_cycles > 7 ? 7 : num_cycles;
- mpsse_clock_tms_cs_out(mpsse_ctx, &tms, 0, this_len, false, JTAG_MODE);
+ mpsse_clock_tms_cs_out(mpsse_ctx, &tms, 0, this_len, false, ftdi_jtag_mode);
num_cycles -= this_len;
}
@@ -626,7 +699,7 @@ static int ftdi_initialize(void)
for (int i = 0; ftdi_vid[i] || ftdi_pid[i]; i++) {
mpsse_ctx = mpsse_open(&ftdi_vid[i], &ftdi_pid[i], ftdi_device_desc,
- ftdi_serial, ftdi_channel);
+ ftdi_serial, ftdi_location, ftdi_channel);
if (mpsse_ctx)
break;
}
@@ -693,6 +766,21 @@ COMMAND_HANDLER(ftdi_handle_serial_command)
return ERROR_OK;
}
+#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
+COMMAND_HANDLER(ftdi_handle_location_command)
+{
+ if (CMD_ARGC == 1) {
+ if (ftdi_location)
+ free(ftdi_location);
+ ftdi_location = strdup(CMD_ARGV[0]);
+ } else {
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ return ERROR_OK;
+}
+#endif
+
COMMAND_HANDLER(ftdi_handle_channel_command)
{
if (CMD_ARGC == 1)
@@ -721,6 +809,8 @@ COMMAND_HANDLER(ftdi_handle_layout_signal_command)
bool invert_data = false;
uint16_t data_mask = 0;
+ bool invert_input = false;
+ uint16_t input_mask = 0;
bool invert_oe = false;
uint16_t oe_mask = 0;
for (unsigned i = 1; i < CMD_ARGC; i += 2) {
@@ -730,6 +820,12 @@ COMMAND_HANDLER(ftdi_handle_layout_signal_command)
} else if (strcmp("-ndata", CMD_ARGV[i]) == 0) {
invert_data = true;
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], data_mask);
+ } else if (strcmp("-input", CMD_ARGV[i]) == 0) {
+ invert_input = false;
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], input_mask);
+ } else if (strcmp("-ninput", CMD_ARGV[i]) == 0) {
+ invert_input = true;
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], input_mask);
} else if (strcmp("-oe", CMD_ARGV[i]) == 0) {
invert_oe = false;
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], oe_mask);
@@ -738,15 +834,19 @@ COMMAND_HANDLER(ftdi_handle_layout_signal_command)
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], oe_mask);
} else if (!strcmp("-alias", CMD_ARGV[i]) ||
!strcmp("-nalias", CMD_ARGV[i])) {
- if (!strcmp("-nalias", CMD_ARGV[i]))
+ if (!strcmp("-nalias", CMD_ARGV[i])) {
invert_data = true;
+ invert_input = true;
+ }
struct signal *sig = find_signal_by_name(CMD_ARGV[i + 1]);
if (!sig) {
LOG_ERROR("signal %s is not defined", CMD_ARGV[i + 1]);
return ERROR_FAIL;
}
data_mask = sig->data_mask;
+ input_mask = sig->input_mask;
oe_mask = sig->oe_mask;
+ invert_input ^= sig->invert_input;
invert_oe = sig->invert_oe;
invert_data ^= sig->invert_data;
} else {
@@ -766,6 +866,8 @@ COMMAND_HANDLER(ftdi_handle_layout_signal_command)
sig->invert_data = invert_data;
sig->data_mask = data_mask;
+ sig->invert_input = invert_input;
+ sig->input_mask = input_mask;
sig->invert_oe = invert_oe;
sig->oe_mask = oe_mask;
@@ -802,6 +904,28 @@ COMMAND_HANDLER(ftdi_handle_set_signal_command)
return mpsse_flush(mpsse_ctx);
}
+COMMAND_HANDLER(ftdi_handle_get_signal_command)
+{
+ if (CMD_ARGC < 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct signal *sig;
+ uint16_t sig_data = 0;
+ sig = find_signal_by_name(CMD_ARGV[0]);
+ if (!sig) {
+ LOG_ERROR("interface configuration doesn't define signal '%s'", CMD_ARGV[0]);
+ return ERROR_FAIL;
+ }
+
+ int ret = ftdi_get_signal(sig, &sig_data);
+ if (ret != ERROR_OK)
+ return ret;
+
+ LOG_USER("Signal %s = %#06x", sig->name, sig_data);
+
+ return ERROR_OK;
+}
+
COMMAND_HANDLER(ftdi_handle_vid_pid_command)
{
if (CMD_ARGC > MAX_USB_IDS * 2) {
@@ -832,6 +956,29 @@ COMMAND_HANDLER(ftdi_handle_vid_pid_command)
return ERROR_OK;
}
+COMMAND_HANDLER(ftdi_handle_tdo_sample_edge_command)
+{
+ Jim_Nvp *n;
+ static const Jim_Nvp nvp_ftdi_jtag_modes[] = {
+ { .name = "rising", .value = JTAG_MODE },
+ { .name = "falling", .value = JTAG_MODE_ALT },
+ { .name = NULL, .value = -1 },
+ };
+
+ if (CMD_ARGC > 0) {
+ n = Jim_Nvp_name2value_simple(nvp_ftdi_jtag_modes, CMD_ARGV[0]);
+ if (n->name == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ ftdi_jtag_mode = n->value;
+
+ }
+
+ n = Jim_Nvp_value2name_simple(nvp_ftdi_jtag_modes, ftdi_jtag_mode);
+ command_print(CMD_CTX, "ftdi samples TDO on %s edge of TCK", n->name);
+
+ return ERROR_OK;
+}
+
static const struct command_registration ftdi_command_handlers[] = {
{
.name = "ftdi_device_desc",
@@ -847,6 +994,15 @@ static const struct command_registration ftdi_command_handlers[] = {
.help = "set the serial number of the FTDI device",
.usage = "serial_string",
},
+#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
+ {
+ .name = "ftdi_location",
+ .handler = &ftdi_handle_location_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the USB bus location of the FTDI device",
+ .usage = ":port[,port]...",
+ },
+#endif
{
.name = "ftdi_channel",
.handler = &ftdi_handle_channel_command,
@@ -877,6 +1033,13 @@ static const struct command_registration ftdi_command_handlers[] = {
.help = "control a layout-specific signal",
.usage = "name (1|0|z)",
},
+ {
+ .name = "ftdi_get_signal",
+ .handler = &ftdi_handle_get_signal_command,
+ .mode = COMMAND_EXEC,
+ .help = "read the value of a layout-specific signal",
+ .usage = "name",
+ },
{
.name = "ftdi_vid_pid",
.handler = &ftdi_handle_vid_pid_command,
@@ -884,6 +1047,15 @@ static const struct command_registration ftdi_command_handlers[] = {
.help = "the vendor ID and product ID of the FTDI device",
.usage = "(vid pid)* ",
},
+ {
+ .name = "ftdi_tdo_sample_edge",
+ .handler = &ftdi_handle_tdo_sample_edge_command,
+ .mode = COMMAND_ANY,
+ .help = "set which TCK clock edge is used for sampling TDO "
+ "- default is rising-edge (Setting to falling-edge may "
+ "allow signalling speed increase)",
+ .usage = "(rising|falling)",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c
index 6f79f0cce..f6689969a 100644
--- a/src/jtag/drivers/gw16012.c
+++ b/src/jtag/drivers/gw16012.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c
index 84127ab54..bd3c5e03c 100644
--- a/src/jtag/drivers/jlink.c
+++ b/src/jtag/drivers/jlink.c
@@ -11,6 +11,9 @@
* Copyright (C) 2015 by Marc Schink *
* openocd-dev@marcschink.de *
* *
+ * 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 *
@@ -22,8 +25,7 @@
* GNU 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., *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -48,9 +50,9 @@ static uint8_t caps[JAYLINK_DEV_EXT_CAPS_SIZE];
static uint32_t serial_number;
static bool use_serial_number;
-static uint8_t usb_address;
+static enum jaylink_usb_address usb_address;
static bool use_usb_address;
-static uint8_t iface = JAYLINK_TIF_JTAG;
+static enum jaylink_target_interface iface = JAYLINK_TIF_JTAG;
static bool trace_enabled;
#define JLINK_MAX_SPEED 12000
@@ -83,9 +85,8 @@ static struct device_config tmp_config;
static void jlink_end_state(tap_state_t state);
static void jlink_state_move(void);
static void jlink_path_move(int num_states, tap_state_t *path);
+static void jlink_stableclocks(int num_cycles);
static void jlink_runtest(int num_cycles);
-static void jlink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
- int scan_size, struct scan_command *command);
static void jlink_reset(int trst, int srst);
static int jlink_swd_run_queue(void);
static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk);
@@ -93,11 +94,25 @@ static int jlink_swd_switch_seq(enum swd_special_seq seq);
/* J-Link tap buffer functions */
static void jlink_tap_init(void);
-static int jlink_tap_execute(void);
-static void jlink_tap_ensure_space(int scans, int bits);
-static void jlink_tap_append_step(int tms, int tdi);
-static void jlink_tap_append_scan(int length, uint8_t *buffer,
- struct scan_command *command);
+static int jlink_flush(void);
+/**
+ * Queue data to go out and in, flushing the queue as many times as
+ * necessary.
+ *
+ * @param out A pointer to TDI data, if NULL, old stale data will be used.
+ * @param out_offset A bit offset for TDI data.
+ * @param tms_out A pointer to TMS data, if NULL, zeroes will be emitted.
+ * @param tms_offset A bit offset for TMS data.
+ * @param in A pointer to store TDO data to, if NULL the data will be discarded.
+ * @param in_offset A bit offset for TDO data.
+ * @param length Amount of bits to transfer out and in.
+ *
+ * @retval This function doesn't return any value.
+ */
+static void jlink_clock_data(const uint8_t *out, unsigned out_offset,
+ const uint8_t *tms_out, unsigned tms_offset,
+ uint8_t *in, unsigned in_offset,
+ unsigned length);
static enum tap_state jlink_last_state = TAP_RESET;
static int queued_retval;
@@ -105,6 +120,12 @@ static int queued_retval;
/***************************************************************************/
/* External interface implementation */
+static void jlink_execute_stableclocks(struct jtag_command *cmd)
+{
+ DEBUG_JTAG_IO("stableclocks %i cycles", cmd->cmd.runtest->num_cycles);
+ jlink_stableclocks(cmd->cmd.runtest->num_cycles);
+}
+
static void jlink_execute_runtest(struct jtag_command *cmd)
{
DEBUG_JTAG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
@@ -133,19 +154,95 @@ static void jlink_execute_pathmove(struct jtag_command *cmd)
static void jlink_execute_scan(struct jtag_command *cmd)
{
- int scan_size;
- enum scan_type type;
- uint8_t *buffer;
+ DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN",
+ jtag_scan_type(cmd->cmd.scan));
+
+ /* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */
+ while (cmd->cmd.scan->num_fields > 0
+ && cmd->cmd.scan->fields[cmd->cmd.scan->num_fields - 1].num_bits == 0) {
+ cmd->cmd.scan->num_fields--;
+ LOG_DEBUG("discarding trailing empty field");
+ }
- DEBUG_JTAG_IO("scan end in %s", tap_state_name(cmd->cmd.scan->end_state));
+ if (cmd->cmd.scan->num_fields == 0) {
+ LOG_DEBUG("empty scan, doing nothing");
+ return;
+ }
+
+ if (cmd->cmd.scan->ir_scan) {
+ if (tap_get_state() != TAP_IRSHIFT) {
+ jlink_end_state(TAP_IRSHIFT);
+ jlink_state_move();
+ }
+ } else {
+ if (tap_get_state() != TAP_DRSHIFT) {
+ jlink_end_state(TAP_DRSHIFT);
+ jlink_state_move();
+ }
+ }
jlink_end_state(cmd->cmd.scan->end_state);
- scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
- DEBUG_JTAG_IO("scan input, length = %d", scan_size);
+ struct scan_field *field = cmd->cmd.scan->fields;
+ unsigned scan_size = 0;
+
+ for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
+ scan_size += field->num_bits;
+ DEBUG_JTAG_IO("%s%s field %d/%d %d bits",
+ field->in_value ? "in" : "",
+ field->out_value ? "out" : "",
+ i,
+ cmd->cmd.scan->num_fields,
+ field->num_bits);
+
+ if (i == cmd->cmd.scan->num_fields - 1 && tap_get_state() != tap_get_end_state()) {
+ /* Last field, and we're leaving IRSHIFT/DRSHIFT. Clock last bit during tap
+ * movement. This last field can't have length zero, it was checked above. */
+ jlink_clock_data(field->out_value,
+ 0,
+ NULL,
+ 0,
+ field->in_value,
+ 0,
+ field->num_bits - 1);
+ uint8_t last_bit = 0;
+ if (field->out_value)
+ bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);
+ uint8_t tms_bits = 0x01;
+ jlink_clock_data(&last_bit,
+ 0,
+ &tms_bits,
+ 0,
+ field->in_value,
+ field->num_bits - 1,
+ 1);
+ tap_set_state(tap_state_transition(tap_get_state(), 1));
+ jlink_clock_data(NULL,
+ 0,
+ &tms_bits,
+ 1,
+ NULL,
+ 0,
+ 1);
+ tap_set_state(tap_state_transition(tap_get_state(), 0));
+ } else
+ jlink_clock_data(field->out_value,
+ 0,
+ NULL,
+ 0,
+ field->in_value,
+ 0,
+ field->num_bits);
+ }
+
+ if (tap_get_state() != tap_get_end_state()) {
+ jlink_end_state(tap_get_end_state());
+ jlink_state_move();
+ }
- type = jtag_scan_type(cmd->cmd.scan);
- jlink_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan);
+ DEBUG_JTAG_IO("%s scan, %i bits, end in %s",
+ (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
+ tap_state_name(tap_get_end_state()));
}
static void jlink_execute_reset(struct jtag_command *cmd)
@@ -153,21 +250,24 @@ static void jlink_execute_reset(struct jtag_command *cmd)
DEBUG_JTAG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst,
cmd->cmd.reset->srst);
- jlink_tap_execute();
+ jlink_flush();
jlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
- jlink_tap_execute();
+ jlink_flush();
}
static void jlink_execute_sleep(struct jtag_command *cmd)
{
DEBUG_JTAG_IO("sleep %" PRIi32 "", cmd->cmd.sleep->us);
- jlink_tap_execute();
+ jlink_flush();
jtag_sleep(cmd->cmd.sleep->us);
}
static int jlink_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
+ case JTAG_STABLECLOCKS:
+ jlink_execute_stableclocks(cmd);
+ break;
case JTAG_RUNTEST:
jlink_execute_runtest(cmd);
break;
@@ -208,18 +308,17 @@ static int jlink_execute_queue(void)
cmd = cmd->next;
}
- return jlink_tap_execute();
+ return jlink_flush();
}
static int jlink_speed(int speed)
{
int ret;
- uint32_t freq;
- uint16_t divider;
+ struct jaylink_speed tmp;
int max_speed;
if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_SPEEDS)) {
- ret = jaylink_get_speeds(devh, &freq, ÷r);
+ ret = jaylink_get_speeds(devh, &tmp);
if (ret != JAYLINK_OK) {
LOG_ERROR("jaylink_get_speeds() failed: %s.",
@@ -227,8 +326,8 @@ static int jlink_speed(int speed)
return ERROR_JTAG_DEVICE_ERROR;
}
- freq = freq / 1000;
- max_speed = freq / divider;
+ tmp.freq /= 1000;
+ max_speed = tmp.freq / tmp.div;
} else {
max_speed = JLINK_MAX_SPEED;
}
@@ -319,7 +418,7 @@ static int select_interface(void)
return ERROR_JTAG_INIT_FAILED;
}
- ret = jaylink_select_interface(devh, iface);
+ ret = jaylink_select_interface(devh, iface, NULL);
if (ret < 0) {
LOG_ERROR("jaylink_select_interface() failed: %s.",
@@ -333,15 +432,16 @@ static int select_interface(void)
static int jlink_register(void)
{
int ret;
- int i;
+ size_t i;
bool handle_found;
+ size_t count;
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER))
return ERROR_OK;
- ret = jaylink_register(devh, &conn, connlist, NULL, NULL);
+ ret = jaylink_register(devh, &conn, connlist, &count);
- if (ret < 0) {
+ if (ret != JAYLINK_OK) {
LOG_ERROR("jaylink_register() failed: %s.",
jaylink_strerror_name(ret));
return ERROR_FAIL;
@@ -349,7 +449,7 @@ static int jlink_register(void)
handle_found = false;
- for (i = 0; i < ret; i++) {
+ for (i = 0; i < count; i++) {
if (connlist[i].handle == conn.handle) {
handle_found = true;
break;
@@ -402,6 +502,36 @@ static bool adjust_swd_buffer_size(void)
return true;
}
+static int jaylink_log_handler(const struct jaylink_context *ctx,
+ enum jaylink_log_level level, const char *format, va_list args,
+ void *user_data)
+{
+ enum log_levels tmp;
+
+ switch (level) {
+ case JAYLINK_LOG_LEVEL_ERROR:
+ tmp = LOG_LVL_ERROR;
+ break;
+ case JAYLINK_LOG_LEVEL_WARNING:
+ tmp = LOG_LVL_WARNING;
+ break;
+ /*
+ * Forward info messages to the debug output because they are more verbose
+ * than info messages of OpenOCD.
+ */
+ case JAYLINK_LOG_LEVEL_INFO:
+ case JAYLINK_LOG_LEVEL_DEBUG:
+ tmp = LOG_LVL_DEBUG;
+ break;
+ default:
+ tmp = LOG_LVL_WARNING;
+ }
+
+ log_vprintf_lf(tmp, __FILE__, __LINE__, __func__, format, args);
+
+ return 0;
+}
+
static int jlink_init(void)
{
int ret;
@@ -412,6 +542,11 @@ static int jlink_init(void)
char *firmware_version;
struct jaylink_hardware_version hwver;
struct jaylink_hardware_status hwstatus;
+ enum jaylink_usb_address address;
+ size_t length;
+
+ LOG_DEBUG("Using libjaylink %s (compiled with %s).",
+ jaylink_version_package_get_string(), JAYLINK_VERSION_PACKAGE_STRING);
ret = jaylink_init(&jayctx);
@@ -421,10 +556,28 @@ static int jlink_init(void)
return ERROR_JTAG_INIT_FAILED;
}
- ret = jaylink_get_device_list(jayctx, &devs);
+ ret = jaylink_log_set_callback(jayctx, &jaylink_log_handler, NULL);
- if (ret < 0) {
- LOG_ERROR("jaylink_get_device_list() failed: %s.",
+ if (ret != JAYLINK_OK) {
+ LOG_ERROR("jaylink_log_set_callback() failed: %s.",
+ jaylink_strerror_name(ret));
+ jaylink_exit(jayctx);
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ ret = jaylink_discovery_scan(jayctx, 0);
+
+ if (ret != JAYLINK_OK) {
+ LOG_ERROR("jaylink_discovery_scan() failed: %s.",
+ jaylink_strerror_name(ret));
+ jaylink_exit(jayctx);
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ ret = jaylink_get_devices(jayctx, &devs, NULL);
+
+ if (ret != JAYLINK_OK) {
+ LOG_ERROR("jaylink_get_devices() failed: %s.",
jaylink_strerror_name(ret));
jaylink_exit(jayctx);
return ERROR_JTAG_INIT_FAILED;
@@ -436,27 +589,45 @@ static int jlink_init(void)
LOG_INFO("No device selected, using first device.");
for (i = 0; devs[i]; i++) {
- jaylink_device_get_serial_number(devs[i], &tmp);
- ret = jaylink_device_get_usb_address(devs[i]);
+ if (use_serial_number) {
+ ret = jaylink_device_get_serial_number(devs[i], &tmp);
+
+ if (ret == JAYLINK_ERR_NOT_AVAILABLE) {
+ continue;
+ } else if (ret != JAYLINK_OK) {
+ LOG_WARNING("jaylink_device_get_serial_number() failed: %s.",
+ jaylink_strerror_name(ret));
+ continue;
+ }
+
+ if (serial_number != tmp)
+ continue;
+ }
- if (use_usb_address && usb_address != ret)
- continue;
+ if (use_usb_address) {
+ ret = jaylink_device_get_usb_address(devs[i], &address);
- if (use_serial_number && tmp != serial_number)
- continue;
+ if (ret != JAYLINK_OK) {
+ LOG_WARNING("jaylink_device_get_usb_address() failed: %s.",
+ jaylink_strerror_name(ret));
+ continue;
+ }
+
+ if (usb_address != address)
+ continue;
+ }
ret = jaylink_open(devs[i], &devh);
- if (ret != JAYLINK_OK) {
- LOG_ERROR("Failed to open device: %s.", jaylink_strerror_name(ret));
- continue;
+ if (ret == JAYLINK_OK) {
+ found_device = true;
+ break;
}
- found_device = true;
- break;
+ LOG_ERROR("Failed to open device: %s.", jaylink_strerror_name(ret));
}
- jaylink_free_device_list(devs, 1);
+ jaylink_free_devices(devs, true);
if (!found_device) {
LOG_ERROR("No J-Link device found.");
@@ -469,19 +640,19 @@ static int jlink_init(void)
* some devices are known to be sensitive regarding the order.
*/
- ret = jaylink_get_firmware_version(devh, &firmware_version);
+ ret = jaylink_get_firmware_version(devh, &firmware_version, &length);
- if (ret > 0) {
- LOG_INFO("%s", firmware_version);
- free(firmware_version);
- } else if (!ret) {
- LOG_WARNING("Device responds empty firmware version string.");
- } else {
+ if (ret != JAYLINK_OK) {
LOG_ERROR("jaylink_get_firmware_version() failed: %s.",
jaylink_strerror_name(ret));
jaylink_close(devh);
jaylink_exit(jayctx);
return ERROR_JTAG_INIT_FAILED;
+ } else if (length > 0) {
+ LOG_INFO("%s", firmware_version);
+ free(firmware_version);
+ } else {
+ LOG_WARNING("Device responds empty firmware version string.");
}
memset(caps, 0, JAYLINK_DEV_EXT_CAPS_SIZE);
@@ -506,7 +677,7 @@ static int jlink_init(void)
}
}
- jtag_command_version = JAYLINK_JTAG_V2;
+ jtag_command_version = JAYLINK_JTAG_VERSION_2;
if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_HW_VERSION)) {
ret = jaylink_get_hardware_version(devh, &hwver);
@@ -522,7 +693,7 @@ static int jlink_init(void)
LOG_INFO("Hardware version: %u.%02u", hwver.major, hwver.minor);
if (hwver.major >= 5)
- jtag_command_version = JAYLINK_JTAG_V3;
+ jtag_command_version = JAYLINK_JTAG_VERSION_3;
}
if (iface == JAYLINK_TIF_SWD) {
@@ -565,7 +736,7 @@ static int jlink_init(void)
conn.handle = 0;
conn.pid = 0;
- conn.hid = 0;
+ strcpy(conn.hid, "0.0.0.0");
conn.iid = 0;
conn.cid = 0;
@@ -597,10 +768,10 @@ static int jlink_init(void)
* if the first tap move is not divisible by 8, so we send a TLR on
* first power up.
*/
- for (i = 0; i < 8; i++)
- jlink_tap_append_step(1, 0);
+ uint8_t tms = 0xff;
+ jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 8);
- jlink_tap_execute();
+ jlink_flush();
}
return ERROR_OK;
@@ -609,6 +780,7 @@ static int jlink_init(void)
static int jlink_quit(void)
{
int ret;
+ size_t count;
if (trace_enabled) {
ret = jaylink_swo_stop(devh);
@@ -619,9 +791,9 @@ static int jlink_quit(void)
}
if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER)) {
- ret = jaylink_unregister(devh, &conn, connlist, NULL, NULL);
+ ret = jaylink_unregister(devh, &conn, connlist, &count);
- if (ret < 0)
+ if (ret != JAYLINK_OK)
LOG_ERROR("jaylink_unregister() failed: %s.",
jaylink_strerror_name(ret));
}
@@ -648,18 +820,13 @@ static void jlink_end_state(tap_state_t state)
/* Goes to the end state. */
static void jlink_state_move(void)
{
- int i;
- int tms = 0;
uint8_t tms_scan;
uint8_t tms_scan_bits;
tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
- for (i = 0; i < tms_scan_bits; i++) {
- tms = (tms_scan >> i) & 1;
- jlink_tap_append_step(tms, 0);
- }
+ jlink_clock_data(NULL, 0, &tms_scan, 0, NULL, 0, tms_scan_bits);
tap_set_state(tap_get_end_state());
}
@@ -667,12 +834,13 @@ static void jlink_state_move(void)
static void jlink_path_move(int num_states, tap_state_t *path)
{
int i;
+ uint8_t tms = 0xff;
for (i = 0; i < num_states; i++) {
if (path[i] == tap_state_transition(tap_get_state(), false))
- jlink_tap_append_step(0, 0);
+ jlink_clock_data(NULL, 0, NULL, 0, NULL, 0, 1);
else if (path[i] == tap_state_transition(tap_get_state(), true))
- jlink_tap_append_step(1, 0);
+ jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1);
else {
LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition.",
tap_state_name(tap_get_state()), tap_state_name(path[i]));
@@ -685,13 +853,19 @@ static void jlink_path_move(int num_states, tap_state_t *path)
tap_set_end_state(tap_get_state());
}
-static void jlink_runtest(int num_cycles)
+static void jlink_stableclocks(int num_cycles)
{
int i;
- tap_state_t saved_end_state = tap_get_end_state();
+ uint8_t tms = tap_get_state() == TAP_RESET;
+ /* Execute num_cycles. */
+ for (i = 0; i < num_cycles; i++)
+ jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1);
+}
- jlink_tap_ensure_space(1, num_cycles + 16);
+static void jlink_runtest(int num_cycles)
+{
+ tap_state_t saved_end_state = tap_get_end_state();
/* Only do a state_move when we're not already in IDLE. */
if (tap_get_state() != TAP_IDLE) {
@@ -700,9 +874,7 @@ static void jlink_runtest(int num_cycles)
/* num_cycles--; */
}
- /* Execute num_cycles. */
- for (i = 0; i < num_cycles; i++)
- jlink_tap_append_step(0, 0);
+ jlink_stableclocks(num_cycles);
/* Finish in end_state. */
jlink_end_state(saved_end_state);
@@ -711,36 +883,6 @@ static void jlink_runtest(int num_cycles)
jlink_state_move();
}
-static void jlink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
- int scan_size, struct scan_command *command)
-{
- tap_state_t saved_end_state;
-
- jlink_tap_ensure_space(1, scan_size + 16);
-
- saved_end_state = tap_get_end_state();
-
- /* Move to appropriate scan state. */
- jlink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
-
- /* Only move if we're not already there. */
- if (tap_get_state() != tap_get_end_state())
- jlink_state_move();
-
- jlink_end_state(saved_end_state);
-
- /* Scan. */
- jlink_tap_append_scan(scan_size, buffer, command);
-
- /* We are in Exit1, go to Pause. */
- jlink_tap_append_step(0, 0);
-
- tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
-
- if (tap_get_state() != tap_get_end_state())
- jlink_state_move();
-}
-
static void jlink_reset(int trst, int srst)
{
LOG_DEBUG("TRST: %i, SRST: %i.", trst, srst);
@@ -761,21 +903,25 @@ static void jlink_reset(int trst, int srst)
COMMAND_HANDLER(jlink_usb_command)
{
+ int tmp;
+
if (CMD_ARGC != 1) {
command_print(CMD_CTX, "Need exactly one argument for jlink usb.");
return ERROR_COMMAND_SYNTAX_ERROR;
}
- if (sscanf(CMD_ARGV[0], "%" SCNd8, &usb_address) != 1) {
+ if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) {
command_print(CMD_CTX, "Invalid USB address: %s.", CMD_ARGV[0]);
return ERROR_FAIL;
}
- if (usb_address > JAYLINK_USB_ADDRESS_3) {
+ if (tmp < JAYLINK_USB_ADDRESS_0 || tmp > JAYLINK_USB_ADDRESS_3) {
command_print(CMD_CTX, "Invalid USB address: %s.", CMD_ARGV[0]);
return ERROR_FAIL;
}
+ usb_address = tmp;
+
use_serial_number = false;
use_usb_address = true;
@@ -784,14 +930,22 @@ COMMAND_HANDLER(jlink_usb_command)
COMMAND_HANDLER(jlink_serial_command)
{
+ int ret;
+
if (CMD_ARGC != 1) {
command_print(CMD_CTX, "Need exactly one argument for jlink serial.");
return ERROR_COMMAND_SYNTAX_ERROR;
}
- if (sscanf(CMD_ARGV[0], "%" SCNd32, &serial_number) != 1) {
+ ret = jaylink_parse_serial_number(CMD_ARGV[0], &serial_number);
+
+ if (ret == JAYLINK_ERR) {
command_print(CMD_CTX, "Invalid serial number: %s.", CMD_ARGV[0]);
return ERROR_FAIL;
+ } else if (ret != JAYLINK_OK) {
+ command_print(CMD_CTX, "jaylink_parse_serial_number() failed: %s.",
+ jaylink_strerror_name(ret));
+ return ERROR_FAIL;
}
use_serial_number = true;
@@ -857,10 +1011,10 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
if (!CMD_ARGC) {
switch (jtag_command_version) {
- case JAYLINK_JTAG_V2:
+ case JAYLINK_JTAG_VERSION_2:
version = 2;
break;
- case JAYLINK_JTAG_V3:
+ case JAYLINK_JTAG_VERSION_3:
version = 3;
break;
default:
@@ -876,10 +1030,10 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
switch (tmp) {
case 2:
- jtag_command_version = JAYLINK_JTAG_V2;
+ jtag_command_version = JAYLINK_JTAG_VERSION_2;
break;
case 3:
- jtag_command_version = JAYLINK_JTAG_V3;
+ jtag_command_version = JAYLINK_JTAG_VERSION_3;
break;
default:
command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]);
@@ -1062,15 +1216,17 @@ static uint32_t calculate_trace_buffer_size(void)
return tmp & 0xffffff00;
}
-static bool check_trace_freq(uint32_t freq, uint32_t divider, uint32_t trace_freq)
+static bool check_trace_freq(struct jaylink_swo_speed speed,
+ uint32_t trace_freq)
{
double min;
double deviation;
+ uint32_t divider;
- min = fabs(1.0 - (freq / ((double)trace_freq * divider)));
+ min = fabs(1.0 - (speed.freq / ((double)trace_freq * speed.min_div)));
- while (freq / divider > 0) {
- deviation = fabs(1.0 - (freq / ((double)trace_freq * divider)));
+ for (divider = speed.min_div; divider < speed.max_div; divider++) {
+ deviation = fabs(1.0 - (speed.freq / ((double)trace_freq * divider)));
if (deviation < 0.03) {
LOG_DEBUG("Found suitable frequency divider %u with deviation of "
@@ -1080,8 +1236,6 @@ static bool check_trace_freq(uint32_t freq, uint32_t divider, uint32_t trace_fre
if (deviation < min)
min = deviation;
-
- divider++;
}
LOG_ERROR("Selected trace frequency is not supported by the device. "
@@ -1097,8 +1251,7 @@ static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
{
int ret;
uint32_t buffer_size;
- uint32_t freq;
- uint32_t divider;
+ struct jaylink_swo_speed speed;
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SWO)) {
LOG_ERROR("Trace capturing is not supported by the device.");
@@ -1137,7 +1290,7 @@ static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
return ERROR_FAIL;
}
- ret = jaylink_swo_get_speeds(devh, JAYLINK_SWO_MODE_UART, &freq, ÷r);
+ ret = jaylink_swo_get_speeds(devh, JAYLINK_SWO_MODE_UART, &speed);
if (ret != JAYLINK_OK) {
LOG_ERROR("jaylink_swo_get_speeds() failed: %s.",
@@ -1146,9 +1299,9 @@ static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
}
if (!*trace_freq)
- *trace_freq = freq / divider;
+ *trace_freq = speed.freq / speed.min_div;
- if (!check_trace_freq(freq, divider, *trace_freq))
+ if (!check_trace_freq(speed, *trace_freq))
return ERROR_FAIL;
LOG_DEBUG("Using %u bytes device memory for trace capturing.", buffer_size);
@@ -1452,6 +1605,125 @@ COMMAND_HANDLER(jlink_handle_config_command)
return ERROR_OK;
}
+COMMAND_HANDLER(jlink_handle_emucom_write_command)
+{
+ int ret;
+ size_t tmp;
+ uint32_t channel;
+ uint32_t length;
+ uint8_t *buf;
+ size_t dummy;
+
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
+ LOG_ERROR("Device does not support EMUCOM.");
+ return ERROR_FAIL;
+ }
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);
+
+ tmp = strlen(CMD_ARGV[1]);
+
+ if (tmp % 2 != 0) {
+ LOG_ERROR("Data must be encoded as hexadecimal pairs.");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
+ buf = malloc(tmp / 2);
+
+ if (!buf) {
+ LOG_ERROR("Failed to allocate buffer.");
+ return ERROR_FAIL;
+ }
+
+ dummy = unhexify(buf, CMD_ARGV[1], tmp / 2);
+
+ if (dummy != (tmp / 2)) {
+ LOG_ERROR("Data must be encoded as hexadecimal pairs.");
+ free(buf);
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
+ length = tmp / 2;
+ ret = jaylink_emucom_write(devh, channel, buf, &length);
+
+ free(buf);
+
+ if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
+ LOG_ERROR("Channel not supported by the device.");
+ return ERROR_FAIL;
+ } else if (ret != JAYLINK_OK) {
+ LOG_ERROR("Failed to write to channel: %s.",
+ jaylink_strerror_name(ret));
+ return ERROR_FAIL;
+ }
+
+ if (length != (tmp / 2))
+ LOG_WARNING("Only %" PRIu32 " bytes written to the channel.", length);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(jlink_handle_emucom_read_command)
+{
+ int ret;
+ uint32_t channel;
+ uint32_t length;
+ uint8_t *buf;
+ size_t tmp;
+
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
+ LOG_ERROR("Device does not support EMUCOM.");
+ return ERROR_FAIL;
+ }
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
+
+ buf = malloc(length * 3 + 1);
+
+ if (!buf) {
+ LOG_ERROR("Failed to allocate buffer.");
+ return ERROR_FAIL;
+ }
+
+ ret = jaylink_emucom_read(devh, channel, buf, &length);
+
+ if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
+ LOG_ERROR("Channel is not supported by the device.");
+ free(buf);
+ return ERROR_FAIL;
+ } else if (ret == JAYLINK_ERR_DEV_NOT_AVAILABLE) {
+ LOG_ERROR("Channel is not available for the requested amount of data. "
+ "%" PRIu32 " bytes are avilable.", length);
+ free(buf);
+ return ERROR_FAIL;
+ } else if (ret != JAYLINK_OK) {
+ LOG_ERROR("Failed to read from channel: %s.",
+ jaylink_strerror_name(ret));
+ free(buf);
+ return ERROR_FAIL;
+ }
+
+ tmp = hexify((char *)buf + length, buf, length, 2 * length + 1);
+
+ if (tmp != 2 * length) {
+ LOG_ERROR("Failed to convert data into hexadecimal string.");
+ free(buf);
+ return ERROR_FAIL;
+ }
+
+ command_print(CMD_CTX, "%s", buf + length);
+ free(buf);
+
+ return ERROR_OK;
+}
+
static const struct command_registration jlink_config_subcommand_handlers[] = {
{
.name = "usb",
@@ -1497,6 +1769,24 @@ static const struct command_registration jlink_config_subcommand_handlers[] = {
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration jlink_emucom_subcommand_handlers[] = {
+ {
+ .name = "write",
+ .handler = &jlink_handle_emucom_write_command,
+ .mode = COMMAND_EXEC,
+ .help = "write to a channel",
+ .usage = " ",
+ },
+ {
+ .name = "read",
+ .handler = &jlink_handle_emucom_read_command,
+ .mode = COMMAND_EXEC,
+ .help = "read from a channel",
+ .usage = " "
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
static const struct command_registration jlink_subcommand_handlers[] = {
{
.name = "jtag",
@@ -1546,6 +1836,12 @@ static const struct command_registration jlink_subcommand_handlers[] = {
"this will show the device configuration",
.chain = jlink_config_subcommand_handlers,
},
+ {
+ .name = "emucom",
+ .mode = COMMAND_EXEC,
+ .help = "access EMUCOM channel",
+ .chain = jlink_emucom_subcommand_handlers
+ },
COMMAND_REGISTRATION_DONE
};
@@ -1596,10 +1892,14 @@ static uint8_t tdi_buffer[JLINK_TAP_BUFFER_SIZE];
static uint8_t tdo_buffer[JLINK_TAP_BUFFER_SIZE];
struct pending_scan_result {
- int first; /* First bit position in tdo_buffer to read. */
- int length; /* Number of bits to read. */
- struct scan_command *command; /* Corresponding scan command. */
+ /** First bit position in tdo_buffer to read. */
+ unsigned first;
+ /** Number of bits to read. */
+ unsigned length;
+ /** Location to store the result */
void *buffer;
+ /** Offset in the destination buffer */
+ unsigned buffer_offset;
};
#define MAX_PENDING_SCAN_RESULTS 256
@@ -1611,69 +1911,53 @@ static void jlink_tap_init(void)
{
tap_length = 0;
pending_scan_results_length = 0;
+ memset(tms_buffer, 0, sizeof(tms_buffer));
+ memset(tdi_buffer, 0, sizeof(tdi_buffer));
}
-static void jlink_tap_ensure_space(int scans, int bits)
-{
- int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
- int available_bits = JLINK_TAP_BUFFER_SIZE * 8 - tap_length - 32;
-
- if (scans > available_scans || bits > available_bits)
- jlink_tap_execute();
-}
-
-static void jlink_tap_append_step(int tms, int tdi)
+static void jlink_clock_data(const uint8_t *out, unsigned out_offset,
+ const uint8_t *tms_out, unsigned tms_offset,
+ uint8_t *in, unsigned in_offset,
+ unsigned length)
{
- int index_var = tap_length / 8;
-
- assert(index_var < JLINK_TAP_BUFFER_SIZE);
-
- int bit_index = tap_length % 8;
- uint8_t bit = 1 << bit_index;
-
- /* We do not pad TMS, so be sure to initialize all bits. */
- if (0 == bit_index)
- tms_buffer[index_var] = tdi_buffer[index_var] = 0;
-
- if (tms)
- tms_buffer[index_var] |= bit;
- else
- tms_buffer[index_var] &= ~bit;
-
- if (tdi)
- tdi_buffer[index_var] |= bit;
- else
- tdi_buffer[index_var] &= ~bit;
+ do {
+ unsigned available_length = JLINK_TAP_BUFFER_SIZE - tap_length / 8;
+
+ if (!available_length ||
+ (in && pending_scan_results_length == MAX_PENDING_SCAN_RESULTS)) {
+ if (jlink_flush() != ERROR_OK)
+ return;
+ available_length = JLINK_TAP_BUFFER_SIZE;
+ }
- tap_length++;
-}
+ struct pending_scan_result *pending_scan_result =
+ &pending_scan_results_buffer[pending_scan_results_length];
-static void jlink_tap_append_scan(int length, uint8_t *buffer,
- struct scan_command *command)
-{
- struct pending_scan_result *pending_scan_result =
- &pending_scan_results_buffer[pending_scan_results_length];
- int i;
+ unsigned scan_length = length > available_length ?
+ available_length : length;
- pending_scan_result->first = tap_length;
- pending_scan_result->length = length;
- pending_scan_result->command = command;
- pending_scan_result->buffer = buffer;
+ if (out)
+ buf_set_buf(out, out_offset, tdi_buffer, tap_length, scan_length);
+ if (tms_out)
+ buf_set_buf(tms_out, tms_offset, tms_buffer, tap_length, scan_length);
- for (i = 0; i < length; i++) {
- int tms = (i < (length - 1)) ? 0 : 1;
- int tdi = (buffer[i / 8] & (1 << (i % 8))) != 0;
- jlink_tap_append_step(tms, tdi);
- }
+ if (in) {
+ pending_scan_result->first = tap_length;
+ pending_scan_result->length = scan_length;
+ pending_scan_result->buffer = in;
+ pending_scan_result->buffer_offset = in_offset;
+ pending_scan_results_length++;
+ }
- pending_scan_results_length++;
+ tap_length += scan_length;
+ out_offset += scan_length;
+ tms_offset += scan_length;
+ in_offset += scan_length;
+ length -= scan_length;
+ } while (length > 0);
}
-/*
- * Pad and send a tap sequence to the device, and receive the answer. For the
- * purpose of padding we assume that we are in idle or pause state.
- */
-static int jlink_tap_execute(void)
+static int jlink_flush(void)
{
int i;
int ret;
@@ -1684,9 +1968,6 @@ static int jlink_tap_execute(void)
jlink_last_state = jtag_debug_state_machine(tms_buffer, tdi_buffer,
tap_length, jlink_last_state);
- jlink_last_state = jtag_debug_state_machine(tms_buffer, tdi_buffer,
- tap_length, jlink_last_state);
-
ret = jaylink_jtag_io(devh, tms_buffer, tdi_buffer, tdo_buffer,
tap_length, jtag_command_version);
@@ -1697,24 +1978,12 @@ static int jlink_tap_execute(void)
}
for (i = 0; i < pending_scan_results_length; i++) {
- struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[i];
- uint8_t *buffer = pending_scan_result->buffer;
- int length = pending_scan_result->length;
- int first = pending_scan_result->first;
- struct scan_command *command = pending_scan_result->command;
-
- /* Copy to buffer. */
- buf_set_buf(tdo_buffer, first, buffer, 0, length);
+ struct pending_scan_result *p = &pending_scan_results_buffer[i];
- DEBUG_JTAG_IO("Pending scan result, length = %d.", length);
-
- if (jtag_read_buffer(buffer, command) != ERROR_OK) {
- jlink_tap_init();
- return ERROR_JTAG_QUEUE_FAILED;
- }
+ buf_set_buf(tdo_buffer, p->first, p->buffer,
+ p->buffer_offset, p->length);
- if (pending_scan_result->buffer != NULL)
- free(pending_scan_result->buffer);
+ DEBUG_JTAG_IO("Pending scan result, length = %d.", p->length);
}
jlink_tap_init();
diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c
index 7c42220d6..746e14751 100644
--- a/src/jtag/drivers/jtag_vpi.c
+++ b/src/jtag/drivers/jtag_vpi.c
@@ -16,6 +16,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
#ifdef HAVE_CONFIG_H
@@ -316,7 +318,11 @@ static int jtag_vpi_runtest(int cycles, tap_state_t state)
if (retval != ERROR_OK)
return retval;
+#if BUILD_RISCV == 1
+ retval = jtag_vpi_queue_tdi(NULL, cycles, NO_TAP_SHIFT);
+#else
retval = jtag_vpi_queue_tdi(NULL, cycles, TAP_SHIFT);
+#endif
if (retval != ERROR_OK)
return retval;
diff --git a/src/jtag/drivers/libusb0_common.c b/src/jtag/drivers/libusb0_common.c
index 5b1248d26..1825543e2 100644
--- a/src/jtag/drivers/libusb0_common.c
+++ b/src/jtag/drivers/libusb0_common.c
@@ -14,9 +14,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -148,7 +146,7 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
unsigned int *usb_read_ep,
unsigned int *usb_write_ep,
- int bclass, int subclass, int protocol)
+ int bclass, int subclass, int protocol, int trans_type)
{
struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
struct usb_interface *iface = udev->config->interface;
@@ -159,7 +157,8 @@ int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
for (int i = 0; i < desc->bNumEndpoints; i++) {
if ((bclass > 0 && desc->bInterfaceClass != bclass) ||
(subclass > 0 && desc->bInterfaceSubClass != subclass) ||
- (protocol > 0 && desc->bInterfaceProtocol != protocol))
+ (protocol > 0 && desc->bInterfaceProtocol != protocol) ||
+ (trans_type > 0 && (desc->endpoint[i].bmAttributes & 0x3) != trans_type))
continue;
uint8_t epnum = desc->endpoint[i].bEndpointAddress;
diff --git a/src/jtag/drivers/libusb0_common.h b/src/jtag/drivers/libusb0_common.h
index ca372a080..baa9e3c5a 100644
--- a/src/jtag/drivers/libusb0_common.h
+++ b/src/jtag/drivers/libusb0_common.h
@@ -14,13 +14,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef JTAG_LIBUSB_COMMON_H
-#define JTAG_LIBUSB_COMMON_H
+#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H
+#define OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H
#include
@@ -69,7 +67,7 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
unsigned int *usb_read_ep,
unsigned int *usb_write_ep,
- int bclass, int subclass, int protocol);
+ int bclass, int subclass, int protocol, int trans_type);
int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid);
-#endif /* JTAG_USB_COMMON_H */
+#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H */
diff --git a/src/jtag/drivers/libusb1_common.c b/src/jtag/drivers/libusb1_common.c
index bda91ffbc..89f809271 100644
--- a/src/jtag/drivers/libusb1_common.c
+++ b/src/jtag/drivers/libusb1_common.c
@@ -14,9 +14,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -189,7 +187,7 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
unsigned int *usb_read_ep,
unsigned int *usb_write_ep,
- int bclass, int subclass, int protocol)
+ int bclass, int subclass, int protocol, int trans_type)
{
struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
const struct libusb_interface *inter;
@@ -212,6 +210,8 @@ int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
continue;
epdesc = &interdesc->endpoint[k];
+ if (trans_type > 0 && (epdesc->bmAttributes & 0x3) != trans_type)
+ continue;
uint8_t epnum = epdesc->bEndpointAddress;
bool is_input = epnum & 0x80;
diff --git a/src/jtag/drivers/libusb1_common.h b/src/jtag/drivers/libusb1_common.h
index 4ef6bf730..7c73d29a4 100644
--- a/src/jtag/drivers/libusb1_common.h
+++ b/src/jtag/drivers/libusb1_common.h
@@ -14,13 +14,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef JTAG_LIBUSB_COMMON_H
-#define JTAG_LIBUSB_COMMON_H
+#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H
+#define OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H
#include
@@ -71,12 +69,13 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
* @param bclass `bInterfaceClass` to match, or -1 to ignore this field.
* @param subclass `bInterfaceSubClass` to match, or -1 to ignore this field.
* @param protocol `bInterfaceProtocol` to match, or -1 to ignore this field.
+ * @param trans_type `bmAttributes Bits 0..1 Transfer type` to match, or -1 to ignore this field.
* @returns Returns ERROR_OK on success, ERROR_FAIL otherwise.
*/
int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
unsigned int *usb_read_ep,
unsigned int *usb_write_ep,
- int bclass, int subclass, int protocol);
+ int bclass, int subclass, int protocol, int trans_type);
int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid);
-#endif /* JTAG_USB_COMMON_H */
+#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H */
diff --git a/src/jtag/drivers/libusb_common.h b/src/jtag/drivers/libusb_common.h
index bad6c8cc9..599a0a9b0 100644
--- a/src/jtag/drivers/libusb_common.h
+++ b/src/jtag/drivers/libusb_common.h
@@ -12,13 +12,16 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H
+#define OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H
+
#ifdef HAVE_LIBUSB1
-#include
+#include "libusb1_common.h"
#else
-#include
+#include "libusb0_common.h"
#endif
+
+#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H */
diff --git a/src/jtag/drivers/minidriver_imp.h b/src/jtag/drivers/minidriver_imp.h
index b81368bd6..cd59a74fb 100644
--- a/src/jtag/drivers/minidriver_imp.h
+++ b/src/jtag/drivers/minidriver_imp.h
@@ -14,12 +14,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef MINIDRIVER_IMP_H
-#define MINIDRIVER_IMP_H
+
+#ifndef OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H
+#define OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H
#include
@@ -39,4 +38,4 @@ void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,
jtag_callback_data_t data1, jtag_callback_data_t data2,
jtag_callback_data_t data3);
-#endif /* MINIDRIVER_IMP_H */
+#endif /* OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H */
diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c
index d9f73a2a7..924c97450 100644
--- a/src/jtag/drivers/mpsse.c
+++ b/src/jtag/drivers/mpsse.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -104,12 +102,67 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in
return strncmp(string, desc_string, sizeof(desc_string)) == 0;
}
+static bool device_location_equal(libusb_device *device, const char *location)
+{
+ bool result = false;
+#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
+ char *loc = strdup(location);
+ uint8_t port_path[7];
+ int path_step, path_len;
+ uint8_t dev_bus = libusb_get_bus_number(device);
+ char *ptr;
+
+ path_len = libusb_get_port_numbers(device, port_path, 7);
+ if (path_len == LIBUSB_ERROR_OVERFLOW) {
+ LOG_ERROR("cannot determine path to usb device! (more than 7 ports in path)");
+ goto done;
+ }
+
+ LOG_DEBUG("device path has %i steps", path_len);
+
+ ptr = strtok(loc, ":");
+ if (ptr == NULL) {
+ LOG_DEBUG("no ':' in path");
+ goto done;
+ }
+ if (atoi(ptr) != dev_bus) {
+ LOG_DEBUG("bus mismatch");
+ goto done;
+ }
+
+ path_step = 0;
+ while (path_step < 7) {
+ ptr = strtok(NULL, ",");
+ if (ptr == NULL) {
+ LOG_DEBUG("no more tokens in path at step %i", path_step);
+ break;
+ }
+
+ if (path_step < path_len
+ && atoi(ptr) != port_path[path_step]) {
+ LOG_DEBUG("path mismatch at step %i", path_step);
+ break;
+ }
+
+ path_step++;
+ };
+
+ /* walked the full path, all elements match */
+ if (path_step == path_len)
+ result = true;
+
+ done:
+ free(loc);
+#endif
+ return result;
+}
+
/* Helper to open a libusb device that matches vid, pid, product string and/or serial string.
* Set any field to 0 as a wildcard. If the device is found true is returned, with ctx containing
* the already opened handle. ctx->interface must be set to the desired interface (channel) number
* prior to calling this function. */
static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, const uint16_t *pid,
- const char *product, const char *serial)
+ const char *product, const char *serial, const char *location)
{
libusb_device **list;
struct libusb_device_descriptor desc;
@@ -141,6 +194,11 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con
continue;
}
+ if (location && !device_location_equal(device, location)) {
+ libusb_close(ctx->usb_dev);
+ continue;
+ }
+
if (product && !string_descriptor_equal(ctx->usb_dev, desc.iProduct, product)) {
libusb_close(ctx->usb_dev);
continue;
@@ -189,8 +247,8 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con
err = libusb_detach_kernel_driver(ctx->usb_dev, ctx->interface);
if (err != LIBUSB_SUCCESS && err != LIBUSB_ERROR_NOT_FOUND
&& err != LIBUSB_ERROR_NOT_SUPPORTED) {
- LOG_ERROR("libusb_detach_kernel_driver() failed with %s", libusb_error_name(err));
- goto error;
+ LOG_WARNING("libusb_detach_kernel_driver() failed with %s, trying to continue anyway",
+ libusb_error_name(err));
}
err = libusb_claim_interface(ctx->usb_dev, ctx->interface);
@@ -263,7 +321,7 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con
}
struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const char *description,
- const char *serial, int channel)
+ const char *serial, const char *location, int channel)
{
struct mpsse_ctx *ctx = calloc(1, sizeof(*ctx));
int err;
@@ -292,16 +350,17 @@ struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const cha
goto error;
}
- if (!open_matching_device(ctx, vid, pid, description, serial)) {
+ if (!open_matching_device(ctx, vid, pid, description, serial, location)) {
/* Four hex digits plus terminating zero each */
char vidstr[5];
char pidstr[5];
- LOG_ERROR("unable to open ftdi device with vid %s, pid %s, description '%s' and "
- "serial '%s'",
+ LOG_ERROR("unable to open ftdi device with vid %s, pid %s, description '%s', "
+ "serial '%s' at bus location '%s'",
vid ? sprintf(vidstr, "%04x", *vid), vidstr : "*",
pid ? sprintf(pidstr, "%04x", *pid), pidstr : "*",
description ? description : "*",
- serial ? serial : "*");
+ serial ? serial : "*",
+ location ? location : "*");
ctx->usb_dev = 0;
goto error;
}
@@ -813,6 +872,8 @@ int mpsse_flush(struct mpsse_ctx *ctx)
libusb_fill_bulk_transfer(write_transfer, ctx->usb_dev, ctx->out_ep, ctx->write_buffer,
ctx->write_count, write_cb, &write_result, ctx->usb_write_timeout);
retval = libusb_submit_transfer(write_transfer);
+ if (retval != LIBUSB_SUCCESS)
+ goto error_check;
if (ctx->read_count) {
read_transfer = libusb_alloc_transfer(0);
@@ -820,22 +881,36 @@ int mpsse_flush(struct mpsse_ctx *ctx)
ctx->read_chunk_size, read_cb, &read_result,
ctx->usb_read_timeout);
retval = libusb_submit_transfer(read_transfer);
+ if (retval != LIBUSB_SUCCESS)
+ goto error_check;
}
/* Polling loop, more or less taken from libftdi */
while (!write_result.done || !read_result.done) {
- retval = libusb_handle_events(ctx->usb_ctx);
+ struct timeval timeout_usb;
+
+ timeout_usb.tv_sec = 1;
+ timeout_usb.tv_usec = 0;
+
+ retval = libusb_handle_events_timeout_completed(ctx->usb_ctx, &timeout_usb, NULL);
keep_alive();
- if (retval != LIBUSB_SUCCESS && retval != LIBUSB_ERROR_INTERRUPTED) {
+ if (retval == LIBUSB_ERROR_NO_DEVICE || retval == LIBUSB_ERROR_INTERRUPTED)
+ break;
+
+ if (retval != LIBUSB_SUCCESS) {
libusb_cancel_transfer(write_transfer);
if (read_transfer)
libusb_cancel_transfer(read_transfer);
- while (!write_result.done || !read_result.done)
- if (libusb_handle_events(ctx->usb_ctx) != LIBUSB_SUCCESS)
+ while (!write_result.done || !read_result.done) {
+ retval = libusb_handle_events_timeout_completed(ctx->usb_ctx,
+ &timeout_usb, NULL);
+ if (retval != LIBUSB_SUCCESS)
break;
+ }
}
}
+error_check:
if (retval != LIBUSB_SUCCESS) {
LOG_ERROR("libusb_handle_events() failed with %s", libusb_error_name(retval));
retval = ERROR_FAIL;
diff --git a/src/jtag/drivers/mpsse.h b/src/jtag/drivers/mpsse.h
index 3e287f75a..651eef940 100644
--- a/src/jtag/drivers/mpsse.h
+++ b/src/jtag/drivers/mpsse.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef MPSSE_H_
-#define MPSSE_H_
+#ifndef OPENOCD_JTAG_DRIVERS_MPSSE_H
+#define OPENOCD_JTAG_DRIVERS_MPSSE_H
#include
#include "helper/binarybuffer.h"
@@ -43,7 +41,7 @@ struct mpsse_ctx;
/* Device handling */
struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const char *description,
- const char *serial, int channel);
+ const char *serial, const char *location, int channel);
void mpsse_close(struct mpsse_ctx *ctx);
bool mpsse_is_high_speed(struct mpsse_ctx *ctx);
@@ -77,4 +75,4 @@ int mpsse_set_frequency(struct mpsse_ctx *ctx, int frequency);
int mpsse_flush(struct mpsse_ctx *ctx);
void mpsse_purge(struct mpsse_ctx *ctx);
-#endif /* MPSSE_H_ */
+#endif /* OPENOCD_JTAG_DRIVERS_MPSSE_H */
diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c
index deb6c7a80..458df34a7 100644
--- a/src/jtag/drivers/opendous.c
+++ b/src/jtag/drivers/opendous.c
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c
index 85d17938e..8f11b4ba1 100644
--- a/src/jtag/drivers/openjtag.c
+++ b/src/jtag/drivers/openjtag.c
@@ -2,6 +2,10 @@
* Driver for OpenJTAG Project (www.openjtag.org) *
* Compatible with libftdi and ftd2xx drivers. *
* *
+ * Cypress CY7C65215 support *
+ * Copyright (C) 2015 Vianney le Clément de Saint-Marcq, Essensium NV *
+ * *
+ * *
* Copyright (C) 2010 by Ivan Meleca *
* *
* Copyright (C) 2013 by Ryan Corbin, GlueLogix Inc. *
@@ -26,13 +30,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/***************************************************************************
- * Version 1.0 Tested on a MCBSTM32 board using a Cortex M3 (stm32f103x), *
+ * Version 1.0 Tested on a MCBSTM32 board using a Cortex-M3 (stm32f103x), *
* GDB and Eclipse under Linux (Ubuntu 10.04) *
* *
***************************************************************************/
@@ -43,7 +45,18 @@
#include
#include
-#include "usb_common.h"
+#include "libusb_common.h"
+
+static enum {
+ OPENJTAG_VARIANT_STANDARD,
+ OPENJTAG_VARIANT_CY7C65215,
+} openjtag_variant = OPENJTAG_VARIANT_STANDARD;
+
+static const char * const openjtag_variant_names[] = {
+ "standard",
+ "cy7c65215",
+ NULL
+};
/*
* OpenJTAG-OpenOCD state conversion
@@ -68,19 +81,8 @@ typedef enum openjtag_tap_state {
OPENJTAG_TAP_UPDATE_IR = 15,
} openjtag_tap_state_t;
-#if (BUILD_OPENJTAG_FTD2XX == 1 && BUILD_OPENJTAG_LIBFTDI == 1)
-#error "BUILD_OPENJTAG_FTD2XX && BUILD_OPENJTAG_LIBFTDI "
- "are mutually exclusive"
-#elif (BUILD_OPENJTAG_FTD2XX != 1 && BUILD_OPENJTAG_LIBFTDI != 1)
-#error "BUILD_OPENJTAG_FTD2XX || BUILD_OPENJTAG_LIBFTDI must be chosen"
-#endif
-
/* OPENJTAG access library includes */
-#if BUILD_OPENJTAG_FTD2XX == 1
-#include
-#elif BUILD_OPENJTAG_LIBFTDI == 1
#include
-#endif
/* OpenJTAG vid/pid */
static uint16_t openjtag_vid = 0x0403;
@@ -88,12 +90,7 @@ static uint16_t openjtag_pid = 0x6001;
static char *openjtag_device_desc;
-#if BUILD_OPENJTAG_FTD2XX == 1
-static FT_HANDLE ftdih;
-
-#elif BUILD_OPENJTAG_LIBFTDI == 1
static struct ftdi_context ftdic;
-#endif
#define OPENJTAG_BUFFER_SIZE 504
#define OPENJTAG_MAX_PENDING_RESULTS 256
@@ -114,10 +111,24 @@ static uint8_t usb_rx_buf[OPENJTAG_BUFFER_SIZE];
static struct openjtag_scan_result openjtag_scan_result_buffer[OPENJTAG_MAX_PENDING_RESULTS];
static int openjtag_scan_result_count;
-/* Openocd usb handler */
-struct openocd {
- struct usb_dev_handle *usb_handle;
-};
+static jtag_libusb_device_handle *usbh;
+
+/* CY7C65215 model only */
+#define CY7C65215_JTAG_REQUEST 0x40 /* bmRequestType: vendor host-to-device */
+#define CY7C65215_JTAG_ENABLE 0xD0 /* bRequest: enable JTAG */
+#define CY7C65215_JTAG_DISABLE 0xD1 /* bRequest: disable JTAG */
+#define CY7C65215_JTAG_READ 0xD2 /* bRequest: read buffer */
+#define CY7C65215_JTAG_WRITE 0xD3 /* bRequest: write buffer */
+
+#define CY7C65215_USB_TIMEOUT 100
+
+static const uint16_t cy7c65215_vids[] = {0x04b4, 0};
+static const uint16_t cy7c65215_pids[] = {0x0007, 0};
+
+#define CY7C65215_JTAG_CLASS 0xff
+#define CY7C65215_JTAG_SUBCLASS 0x04
+
+static unsigned int ep_in, ep_out;
#ifdef _DEBUG_USB_COMMS_
@@ -203,26 +214,9 @@ static int8_t openjtag_get_tap_state(int8_t state)
}
}
-static int openjtag_buf_write(
+static int openjtag_buf_write_standard(
uint8_t *buf, int size, uint32_t *bytes_written)
{
-#if BUILD_OPENJTAG_FTD2XX == 1
- FT_STATUS status;
- DWORD dw_bytes_written;
-
-#ifdef _DEBUG_USB_COMMS_
- openjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);
-#endif
-
- status = FT_Write(ftdih, buf, size, &dw_bytes_written);
- if (status != FT_OK) {
- *bytes_written = dw_bytes_written;
- LOG_ERROR("FT_Write returned: %u", status);
- return ERROR_JTAG_DEVICE_ERROR;
- }
- *bytes_written = dw_bytes_written;
- return ERROR_OK;
-#elif BUILD_OPENJTAG_LIBFTDI == 1
int retval;
#ifdef _DEBUG_USB_COMMS_
openjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);
@@ -238,36 +232,56 @@ static int openjtag_buf_write(
*bytes_written += retval;
return ERROR_OK;
-#endif
}
-static int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
+static int openjtag_buf_write_cy7c65215(
+ uint8_t *buf, int size, uint32_t *bytes_written)
{
+ int ret;
-#if BUILD_OPENJTAG_FTD2XX == 1
- DWORD dw_bytes_read;
- FT_STATUS status;
- int timeout = 50;
+#ifdef _DEBUG_USB_COMMS_
+ openjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);
+#endif
- *bytes_read = 0;
- while (qty && (*bytes_read < qty) && timeout--) {
+ if (size == 0) {
+ *bytes_written = 0;
+ return ERROR_OK;
+ }
- status = FT_Read(ftdih, buf + *bytes_read,
- qty - *bytes_read, &dw_bytes_read);
- if (status != FT_OK) {
- *bytes_read = dw_bytes_read;
- LOG_ERROR("FT_Read returned: %u", status);
- return ERROR_JTAG_DEVICE_ERROR;
- }
- *bytes_read += dw_bytes_read;
+ ret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,
+ CY7C65215_JTAG_WRITE, size, 0,
+ NULL, 0, CY7C65215_USB_TIMEOUT);
+ if (ret < 0) {
+ LOG_ERROR("vendor command failed, error %d", ret);
+ return ERROR_JTAG_DEVICE_ERROR;
}
-#ifdef _DEBUG_USB_COMMS_
- openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);
-#endif
+ ret = jtag_libusb_bulk_write(usbh, ep_out, (char *)buf, size,
+ CY7C65215_USB_TIMEOUT);
+ if (ret < 0) {
+ LOG_ERROR("bulk write failed, error %d", ret);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+ *bytes_written = ret;
return ERROR_OK;
-#elif BUILD_OPENJTAG_LIBFTDI == 1
+}
+
+static int openjtag_buf_write(
+ uint8_t *buf, int size, uint32_t *bytes_written)
+{
+ switch (openjtag_variant) {
+ case OPENJTAG_VARIANT_CY7C65215:
+ return openjtag_buf_write_cy7c65215(buf, size, bytes_written);
+ default:
+ return openjtag_buf_write_standard(buf, size, bytes_written);
+ }
+}
+
+static int openjtag_buf_read_standard(
+ uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
+{
+
int retval;
int timeout = 5;
@@ -289,10 +303,53 @@ static int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);
#endif
+ return ERROR_OK;
+}
+
+static int openjtag_buf_read_cy7c65215(
+ uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
+{
+ int ret;
+
+ if (qty == 0) {
+ *bytes_read = 0;
+ goto out;
+ }
+
+ ret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,
+ CY7C65215_JTAG_READ, qty, 0,
+ NULL, 0, CY7C65215_USB_TIMEOUT);
+ if (ret < 0) {
+ LOG_ERROR("vendor command failed, error %d", ret);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+
+ ret = jtag_libusb_bulk_read(usbh, ep_in, (char *)buf, qty,
+ CY7C65215_USB_TIMEOUT);
+ if (ret < 0) {
+ LOG_ERROR("bulk read failed, error %d", ret);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+ *bytes_read = ret;
+
+out:
+#ifdef _DEBUG_USB_COMMS_
+ openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);
#endif
+
return ERROR_OK;
}
+static int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
+{
+ switch (openjtag_variant) {
+ case OPENJTAG_VARIANT_CY7C65215:
+ return openjtag_buf_read_cy7c65215(buf, qty, bytes_read);
+ default:
+ return openjtag_buf_read_standard(buf, qty, bytes_read);
+ }
+}
+
static int openjtag_sendcommand(uint8_t cmd)
{
uint32_t written;
@@ -337,109 +394,17 @@ static int openjtag_speed(int speed)
return ERROR_OK;
}
-static int openjtag_init(void)
+static int openjtag_init_standard(void)
{
uint8_t latency_timer;
-#if BUILD_OPENJTAG_FTD2XX == 1
- FT_STATUS status;
-#endif
-
-usb_tx_buf_offs = 0;
-usb_rx_buf_len = 0;
-openjtag_scan_result_count = 0;
-
-#if BUILD_OPENJTAG_FTD2XX == 1
- LOG_DEBUG("'openjtag' interface using FTD2XX");
-#elif BUILD_OPENJTAG_LIBFTDI == 1
- LOG_DEBUG("'openjtag' interface using libftdi");
-#endif
-
-/* Open by device description */
-if (openjtag_device_desc == NULL) {
- LOG_WARNING("no openjtag device description specified, "
+ /* Open by device description */
+ if (openjtag_device_desc == NULL) {
+ LOG_WARNING("no openjtag device description specified, "
"using default 'Open JTAG Project'");
- openjtag_device_desc = "Open JTAG Project";
-}
-
-#if BUILD_OPENJTAG_FTD2XX == 1
-
-#if IS_WIN32 == 0
- /* Add non-standard Vid/Pid to the linux driver */
- status = FT_SetVIDPID(openjtag_vid, openjtag_pid);
- if (status != FT_OK) {
- LOG_WARNING("couldn't add %4.4x:%4.4x",
- openjtag_vid, openjtag_pid);
+ openjtag_device_desc = "Open JTAG Project";
}
-#endif
- status = FT_OpenEx(openjtag_device_desc, FT_OPEN_BY_DESCRIPTION,
- &ftdih);
- if (status != FT_OK) {
- DWORD num_devices;
-
- LOG_ERROR("unable to open ftdi device: %u", status);
- status = FT_ListDevices(&num_devices, NULL,
- FT_LIST_NUMBER_ONLY);
- if (status == FT_OK) {
- char **desc_array = malloc(sizeof(char *)
- * (num_devices + 1));
- unsigned int i;
-
- for (i = 0; i < num_devices; i++)
- desc_array[i] = malloc(64);
- desc_array[num_devices] = NULL;
-
- status = FT_ListDevices(desc_array, &num_devices,
- FT_LIST_ALL | FT_OPEN_BY_DESCRIPTION);
-
- if (status == FT_OK) {
- LOG_ERROR("ListDevices: %u\n", num_devices);
- for (i = 0; i < num_devices; i++)
- LOG_ERROR("%i: %s", i, desc_array[i]);
- }
-
- for (i = 0; i < num_devices; i++)
- free(desc_array[i]);
- free(desc_array);
- } else {
- LOG_ERROR("ListDevices: NONE\n");
- }
- return ERROR_JTAG_INIT_FAILED;
- }
-
- status = FT_SetLatencyTimer(ftdih, 2);
- if (status != FT_OK) {
- LOG_ERROR("unable to set latency timer: %u", status);
- return ERROR_JTAG_INIT_FAILED;
- }
-
- status = FT_GetLatencyTimer(ftdih, &latency_timer);
- if (status != FT_OK) {
- LOG_ERROR("unable to get latency timer: %u", status);
- return ERROR_JTAG_INIT_FAILED;
- }
- LOG_DEBUG("current latency timer: %i", latency_timer);
-
- status = FT_SetBitMode(ftdih, 0x00, 0x40);
- if (status != FT_OK) {
- LOG_ERROR("unable to disable bit i/o mode: %u", status);
- return ERROR_JTAG_INIT_FAILED;
- }
-
- status = FT_SetTimeouts(ftdih, 50, 0);
- if (status != FT_OK) {
- LOG_ERROR("unable to set timeouts: %u", status);
- return ERROR_JTAG_INIT_FAILED;
- }
-
- status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX);
- if (status != FT_OK) {
- LOG_ERROR("unable to FT_Purge() %u", status);
- return ERROR_JTAG_INIT_FAILED;
- }
-
-#elif BUILD_OPENJTAG_LIBFTDI == 1
if (ftdi_init(&ftdic) < 0)
return ERROR_JTAG_INIT_FAILED;
@@ -471,41 +436,110 @@ if (openjtag_device_desc == NULL) {
LOG_ERROR("Can't set baud rate to max: %s",
ftdi_get_error_string(&ftdic));
return ERROR_JTAG_DEVICE_ERROR;
- };
-#endif
+ }
-#if BUILD_OPENJTAG_FTD2XX == 1
- status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX);
- if (status != FT_OK)
- return ERROR_JTAG_INIT_FAILED;
-#elif BUILD_OPENJTAG_LIBFTDI == 1
if (ftdi_usb_purge_buffers(&ftdic) < 0) {
LOG_ERROR("ftdi_purge_buffers: %s", ftdic.error_str);
return ERROR_JTAG_INIT_FAILED;
}
-#endif
- /* OpenJTAG speed */
- openjtag_sendcommand(0xE0); /*Start at slowest adapter speed*/
+ return ERROR_OK;
+}
+
+static int openjtag_init_cy7c65215(void)
+{
+ int ret;
+
+ usbh = NULL;
+ ret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, NULL, &usbh);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("unable to open cy7c65215 device");
+ goto err;
+ }
+
+ ret = jtag_libusb_choose_interface(usbh, &ep_in, &ep_out,
+ CY7C65215_JTAG_CLASS,
+ CY7C65215_JTAG_SUBCLASS, -1, LIBUSB_TRANSFER_TYPE_BULK);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("unable to claim JTAG interface");
+ goto err;
+ }
- /* MSB */
- openjtag_sendcommand(0x75);
+ ret = jtag_libusb_control_transfer(usbh,
+ CY7C65215_JTAG_REQUEST,
+ CY7C65215_JTAG_ENABLE,
+ 0, 0, NULL, 0, CY7C65215_USB_TIMEOUT);
+ if (ret < 0) {
+ LOG_ERROR("could not enable JTAG module");
+ goto err;
+ }
return ERROR_OK;
+
+err:
+ if (usbh != NULL)
+ jtag_libusb_close(usbh);
+ return ERROR_JTAG_INIT_FAILED;
}
-static int openjtag_quit(void)
+static int openjtag_init(void)
+{
+ int ret;
+
+ usb_tx_buf_offs = 0;
+ usb_rx_buf_len = 0;
+ openjtag_scan_result_count = 0;
+
+ switch (openjtag_variant) {
+ case OPENJTAG_VARIANT_CY7C65215:
+ ret = openjtag_init_cy7c65215();
+ break;
+ default:
+ ret = openjtag_init_standard();
+ }
+ if (ret != ERROR_OK)
+ return ret;
+
+ openjtag_speed(375); /* Start at slowest adapter speed */
+ openjtag_sendcommand(0x75); /* MSB */
+
+ return ERROR_OK;
+}
+
+static int openjtag_quit_standard(void)
{
-#if BUILD_OPENJTAG_FTD2XX == 1
- FT_Close(ftdih);
-#elif BUILD_OPENJTAG_LIBFTDI == 1
ftdi_usb_close(&ftdic);
ftdi_deinit(&ftdic);
-#endif
return ERROR_OK;
}
+static int openjtag_quit_cy7c65215(void)
+{
+ int ret;
+
+ ret = jtag_libusb_control_transfer(usbh,
+ CY7C65215_JTAG_REQUEST,
+ CY7C65215_JTAG_DISABLE,
+ 0, 0, NULL, 0, CY7C65215_USB_TIMEOUT);
+ if (ret < 0)
+ LOG_WARNING("could not disable JTAG module");
+
+ jtag_libusb_close(usbh);
+
+ return ERROR_OK;
+}
+
+static int openjtag_quit(void)
+{
+ switch (openjtag_variant) {
+ case OPENJTAG_VARIANT_CY7C65215:
+ return openjtag_quit_cy7c65215();
+ default:
+ return openjtag_quit_standard();
+ }
+}
+
static void openjtag_write_tap_buffer(void)
{
uint32_t written;
@@ -538,8 +572,8 @@ static int openjtag_execute_tap_queue(void)
uint8_t *buffer = openjtag_scan_result_buffer[res_count].buffer;
- while (len) {
- if (len <= 8) {
+ while (len > 0) {
+ if (len <= 8 && openjtag_variant != OPENJTAG_VARIANT_CY7C65215) {
DEBUG_JTAG_IO("bits < 8 buf = 0x%X, will be 0x%X",
usb_rx_buf[rx_offs], usb_rx_buf[rx_offs] >> (8 - len));
buffer[count] = usb_rx_buf[rx_offs] >> (8 - len);
@@ -726,11 +760,14 @@ static void openjtag_execute_runtest(struct jtag_command *cmd)
if (cmd->cmd.runtest->num_cycles > 16)
LOG_WARNING("num_cycles > 16 on run test");
- uint8_t command;
- command = 7;
- command |= ((cmd->cmd.runtest->num_cycles - 1) & 0x0F) << 4;
+ if (openjtag_variant != OPENJTAG_VARIANT_CY7C65215 ||
+ cmd->cmd.runtest->num_cycles) {
+ uint8_t command;
+ command = 7;
+ command |= ((cmd->cmd.runtest->num_cycles - 1) & 0x0F) << 4;
- openjtag_add_byte(command);
+ openjtag_add_byte(command);
+ }
tap_set_end_state(end_state);
if (tap_get_end_state() != tap_get_state()) {
@@ -818,6 +855,24 @@ COMMAND_HANDLER(openjtag_handle_device_desc_command)
return ERROR_OK;
}
+COMMAND_HANDLER(openjtag_handle_variant_command)
+{
+ if (CMD_ARGC == 1) {
+ const char * const *name = openjtag_variant_names;
+ int variant = 0;
+ for (; *name; name++, variant++) {
+ if (strcasecmp(CMD_ARGV[0], *name) == 0) {
+ openjtag_variant = variant;
+ return ERROR_OK;
+ }
+ }
+ LOG_ERROR("unknown openjtag variant '%s'", CMD_ARGV[0]);
+ } else {
+ LOG_ERROR("require exactly one argument to "
+ "openjtag_variant ");
+ }
+ return ERROR_OK;
+}
static const struct command_registration openjtag_command_handlers[] = {
{
@@ -827,6 +882,13 @@ static const struct command_registration openjtag_command_handlers[] = {
.help = "set the USB device description of the OpenJTAG",
.usage = "description-string",
},
+ {
+ .name = "openjtag_variant",
+ .handler = openjtag_handle_variant_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the OpenJTAG variant",
+ .usage = "variant-string",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c
index d1eeedb33..5db36a122 100644
--- a/src/jtag/drivers/osbdm.c
+++ b/src/jtag/drivers/osbdm.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c
index ff7585951..c9e331644 100644
--- a/src/jtag/drivers/parport.c
+++ b/src/jtag/drivers/parport.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/presto.c b/src/jtag/drivers/presto.c
index 45e434a14..49caa679f 100644
--- a/src/jtag/drivers/presto.c
+++ b/src/jtag/drivers/presto.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/**
@@ -36,14 +34,7 @@
#include "bitq.h"
/* PRESTO access library includes */
-#if BUILD_PRESTO_FTD2XX == 1
-#include
-#include "ftd2xx_common.h"
-#elif BUILD_PRESTO_LIBFTDI == 1
#include
-#else
-#error "BUG: either FTD2XX and LIBFTDI has to be used"
-#endif
/* -------------------------------------------------------------------------- */
@@ -57,13 +48,8 @@
#define BUFFER_SIZE (64*62)
struct presto {
-#if BUILD_PRESTO_FTD2XX == 1
- FT_HANDLE handle;
- FT_STATUS status;
-#elif BUILD_PRESTO_LIBFTDI == 1
struct ftdi_context ftdic;
int retval;
-#endif
char serial[FT_DEVICE_SERNUM_LEN];
@@ -97,15 +83,6 @@ static uint8_t presto_init_seq[] = {
static int presto_write(uint8_t *buf, uint32_t size)
{
-#if BUILD_PRESTO_FTD2XX == 1
- DWORD ftbytes;
- presto->status = FT_Write(presto->handle, buf, size, &ftbytes);
- if (presto->status != FT_OK) {
- LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(presto->status));
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
-#elif BUILD_PRESTO_LIBFTDI == 1
uint32_t ftbytes;
presto->retval = ftdi_write_data(&presto->ftdic, buf, size);
if (presto->retval < 0) {
@@ -113,7 +90,6 @@ static int presto_write(uint8_t *buf, uint32_t size)
return ERROR_JTAG_DEVICE_ERROR;
}
ftbytes = presto->retval;
-#endif
if (ftbytes != size) {
LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%u < %u)",
@@ -126,15 +102,6 @@ static int presto_write(uint8_t *buf, uint32_t size)
static int presto_read(uint8_t *buf, uint32_t size)
{
-#if BUILD_PRESTO_FTD2XX == 1
- DWORD ftbytes;
- presto->status = FT_Read(presto->handle, buf, size, &ftbytes);
- if (presto->status != FT_OK) {
- LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(presto->status));
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
-#elif BUILD_PRESTO_LIBFTDI == 1
uint32_t ftbytes = 0;
struct timeval timeout, now;
@@ -154,7 +121,6 @@ static int presto_read(uint8_t *buf, uint32_t size)
((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec)))
break;
}
-#endif
if (ftbytes != size) {
/* this is just a warning, there might have been timeout when detecting PRESTO,
@@ -167,150 +133,6 @@ static int presto_read(uint8_t *buf, uint32_t size)
return ERROR_OK;
}
-#if BUILD_PRESTO_FTD2XX == 1
-static int presto_open_ftd2xx(char *req_serial)
-{
- uint32_t i;
- DWORD numdevs;
- DWORD vidpid;
- char devname[FT_DEVICE_NAME_LEN];
- FT_DEVICE device;
-
- BYTE presto_data;
- DWORD ftbytes;
-
- presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
-
-#if IS_WIN32 == 0
- /* Add non-standard Vid/Pid to the linux driver */
- presto->status = FT_SetVIDPID(PRESTO_VID, PRESTO_PID);
- if (presto->status != FT_OK) {
- LOG_ERROR("couldn't add PRESTO VID/PID");
- exit(-1);
- }
-#endif
-
- presto->status = FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY);
- if (presto->status != FT_OK) {
- LOG_ERROR("FT_ListDevices failed: %s", ftd2xx_status_string(presto->status));
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- LOG_DEBUG("FTDI devices available: %" PRIu32, (uint32_t)numdevs);
- for (i = 0; i < numdevs; i++) {
- presto->status = FT_Open(i, &(presto->handle));
- if (presto->status != FT_OK) {
- /* this is not fatal, the device may be legitimately open by other process,
- *hence debug message only */
- LOG_DEBUG("FT_Open failed: %s", ftd2xx_status_string(presto->status));
- continue;
- }
- LOG_DEBUG("FTDI device %i open", (int)i);
-
- presto->status = FT_GetDeviceInfo(presto->handle, &device,
- &vidpid, presto->serial, devname, NULL);
- if (presto->status == FT_OK) {
- if (vidpid == PRESTO_VID_PID && (req_serial == NULL ||
- !strcmp(presto->serial, req_serial)))
- break;
- } else
- LOG_DEBUG("FT_GetDeviceInfo failed: %s", ftd2xx_status_string(
- presto->status));
-
- LOG_DEBUG("FTDI device %i does not match, closing", (int)i);
- FT_Close(presto->handle);
- presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
- }
-
- if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
- return ERROR_JTAG_DEVICE_ERROR; /* presto not open, return */
-
- presto->status = FT_SetLatencyTimer(presto->handle, 1);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- presto->status = FT_SetTimeouts(presto->handle, 100, 0);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- presto_data = 0xD0;
- presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- /* delay between first write/read turnaround (after purge?) necessary
- * under Linux for unknown reason,
- * probably a bug in library threading */
- usleep(100000);
- presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- if (ftbytes != 1) {
- LOG_DEBUG("PRESTO reset");
-
- presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
- presto->status = FT_SetBitMode(presto->handle, 0x80, 1);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
- presto->status = FT_SetBaudRate(presto->handle, 9600);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- presto_data = 0;
- for (i = 0; i < 4 * 62; i++) {
- presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
- }
- usleep(100000);
-
- presto->status = FT_SetBitMode(presto->handle, 0x00, 0);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- presto_data = 0xD0;
- presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
- probably a bug in library threading */
- usleep(100000);
- presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- if (ftbytes != 1) {
- LOG_DEBUG("PRESTO not responding");
- return ERROR_JTAG_DEVICE_ERROR;
- }
- }
-
- presto->status = FT_SetTimeouts(presto->handle, 0, 0);
- if (presto->status != FT_OK)
- return ERROR_JTAG_DEVICE_ERROR;
-
- presto->status = FT_Write(presto->handle, &presto_init_seq,
- sizeof(presto_init_seq), &ftbytes);
-
- if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
- return ERROR_JTAG_DEVICE_ERROR;
-
- return ERROR_OK;
-}
-
-#elif BUILD_PRESTO_LIBFTDI == 1
static int presto_open_libftdi(char *req_serial)
{
uint8_t presto_data;
@@ -373,7 +195,6 @@ static int presto_open_libftdi(char *req_serial)
return ERROR_OK;
}
-#endif /* BUILD_PRESTO_LIBFTDI == 1 */
static int presto_open(char *req_serial)
{
@@ -393,11 +214,7 @@ static int presto_open(char *req_serial)
presto->jtag_speed = 0;
-#if BUILD_PRESTO_FTD2XX == 1
- return presto_open_ftd2xx(req_serial);
-#elif BUILD_PRESTO_LIBFTDI == 1
return presto_open_libftdi(req_serial);
-#endif
}
static int presto_close(void)
@@ -405,35 +222,6 @@ static int presto_close(void)
int result = ERROR_OK;
-#if BUILD_PRESTO_FTD2XX == 1
- DWORD ftbytes;
-
- if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
- return result;
-
- presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
- if (presto->status != FT_OK)
- result = ERROR_JTAG_DEVICE_ERROR;
-
- presto->status = FT_Write(presto->handle,
- &presto_init_seq,
- sizeof(presto_init_seq),
- &ftbytes);
- if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
- result = ERROR_JTAG_DEVICE_ERROR;
-
- presto->status = FT_SetLatencyTimer(presto->handle, 16);
- if (presto->status != FT_OK)
- result = ERROR_JTAG_DEVICE_ERROR;
-
- presto->status = FT_Close(presto->handle);
- if (presto->status != FT_OK)
- result = ERROR_JTAG_DEVICE_ERROR;
- else
- presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
-
-#elif BUILD_PRESTO_LIBFTDI == 1
-
presto->retval = ftdi_write_data(&presto->ftdic, presto_init_seq, sizeof(presto_init_seq));
if (presto->retval != sizeof(presto_init_seq))
result = ERROR_JTAG_DEVICE_ERROR;
@@ -447,7 +235,6 @@ static int presto_close(void)
result = ERROR_JTAG_DEVICE_ERROR;
else
ftdi_deinit(&presto->ftdic);
-#endif
return result;
}
@@ -457,11 +244,7 @@ static int presto_flush(void)
if (presto->buff_out_pos == 0)
return ERROR_OK;
-#if BUILD_PRESTO_FTD2XX == 1
- if (presto->status != FT_OK) {
-#elif BUILD_PRESTO_LIBFTDI == 1
if (presto->retval < 0) {
-#endif
LOG_DEBUG("error in previous communication, canceling I/O operation");
return ERROR_JTAG_DEVICE_ERROR;
}
@@ -504,13 +287,9 @@ static int presto_sendbyte(int data)
} else
return ERROR_JTAG_DEVICE_ERROR;
-#if BUILD_PRESTO_FTD2XX == 1
- if (presto->buff_out_pos >= BUFFER_SIZE)
-#elif BUILD_PRESTO_LIBFTDI == 1
/* libftdi does not do background read, be sure that USB IN buffer does not overflow (128
*bytes only!) */
if (presto->buff_out_pos >= BUFFER_SIZE || presto->buff_in_exp == 128)
-#endif
return presto_flush();
return ERROR_OK;
diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c
index a1c11b244..b898e957d 100644
--- a/src/jtag/drivers/remote_bitbang.c
+++ b/src/jtag/drivers/remote_bitbang.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -133,7 +131,7 @@ static int remote_bitbang_init_tcp(void)
{
struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM };
struct addrinfo *result, *rp;
- int fd;
+ int fd = 0;
LOG_INFO("Connecting to %s:%s",
remote_bitbang_host ? remote_bitbang_host : "localhost",
diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c
index 3587a9d53..3f9e33268 100644
--- a/src/jtag/drivers/rlink.c
+++ b/src/jtag/drivers/rlink.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/rlink.h b/src/jtag/drivers/rlink.h
index 8f09f8ce6..74b62580c 100644
--- a/src/jtag/drivers/rlink.h
+++ b/src/jtag/drivers/rlink.h
@@ -13,11 +13,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_JTAG_DRIVERS_RLINK_H
+#define OPENOCD_JTAG_DRIVERS_RLINK_H
+
struct rlink_speed_table {
uint8_t const *dtc;
uint16_t dtc_size;
@@ -27,3 +28,5 @@ struct rlink_speed_table {
extern const struct rlink_speed_table rlink_speed_table[];
extern const size_t rlink_speed_table_size;
+
+#endif /* OPENOCD_JTAG_DRIVERS_RLINK_H */
diff --git a/src/jtag/drivers/rlink_call.m4 b/src/jtag/drivers/rlink_call.m4
index 13e0fc2d2..b27f39238 100644
--- a/src/jtag/drivers/rlink_call.m4
+++ b/src/jtag/drivers/rlink_call.m4
@@ -14,9 +14,7 @@ m4_divert(`-1')
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
m4_dnl Setup and hold times depend on SHIFTER_PRESCALER
diff --git a/src/jtag/drivers/rlink_dtc_cmd.h b/src/jtag/drivers/rlink_dtc_cmd.h
index faf41ce5f..ff9e8b25f 100644
--- a/src/jtag/drivers/rlink_dtc_cmd.h
+++ b/src/jtag/drivers/rlink_dtc_cmd.h
@@ -13,11 +13,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_JTAG_DRIVERS_RLINK_DTC_CMD_H
+#define OPENOCD_JTAG_DRIVERS_RLINK_DTC_CMD_H
+
/* A command position with the high nybble of 0x0 is reserved for an error condition.
* If executed, it stops the DTC and raises the ERROR flag */
@@ -71,3 +72,5 @@
/* A shared status byte is updated with bit 0 set when this has happened,
* and it is cleared when a new command buffer becomes ready.
* The host can poll that byte to see when it is safe to read a reply. */
+
+#endif /* 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 00b19eee6..3f9f2b381 100644
--- a/src/jtag/drivers/rlink_ep1_cmd.h
+++ b/src/jtag/drivers/rlink_ep1_cmd.h
@@ -13,11 +13,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_JTAG_DRIVERS_RLINK_EP1_CMD_H
+#define OPENOCD_JTAG_DRIVERS_RLINK_EP1_CMD_H
+
/*
* Command opcodes that can be sent over endpoint 1.
* This codifies information provided by Rob Brown .
@@ -55,3 +56,5 @@
#define EP1_CMD_MEMORY_WRITE (0x29)
#define EP1_CMD_GET_FWREV (0xfe)
#define EP1_CMD_GET_SERIAL (0xff)
+
+#endif /* OPENOCD_JTAG_DRIVERS_RLINK_EP1_CMD_H */
diff --git a/src/jtag/drivers/rlink_init.m4 b/src/jtag/drivers/rlink_init.m4
index b13400462..8ad2f51d8 100644
--- a/src/jtag/drivers/rlink_init.m4
+++ b/src/jtag/drivers/rlink_init.m4
@@ -14,9 +14,7 @@ m4_divert(`-1')
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
m4_undefine(`CTRL_MPEG_L')
diff --git a/src/jtag/drivers/rlink_st7.h b/src/jtag/drivers/rlink_st7.h
index a30acb470..3d573e72c 100644
--- a/src/jtag/drivers/rlink_st7.h
+++ b/src/jtag/drivers/rlink_st7.h
@@ -13,11 +13,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_JTAG_DRIVERS_RLINK_ST7_H
+#define OPENOCD_JTAG_DRIVERS_RLINK_ST7_H
+
#define ST7_FOSC (12 * 1000000)
/* This is not a complete enumeration of ST7 registers, but it is sufficient for this interface driver. */
@@ -112,3 +113,5 @@
#define ST7_PF5 (1 << 5)
#define ST7_PF6 (1 << 6)
#define ST7_PF7 (1 << 7)
+
+#endif /* OPENOCD_JTAG_DRIVERS_RLINK_ST7_H */
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index a4847abd6..0bdcd316b 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -18,9 +18,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -135,9 +133,19 @@ struct stlink_usb_handle_s {
#define STLINK_DEBUG_ERR_OK 0x80
#define STLINK_DEBUG_ERR_FAULT 0x81
#define STLINK_SWD_AP_WAIT 0x10
+#define STLINK_SWD_AP_FAULT 0x11
+#define STLINK_SWD_AP_ERROR 0x12
+#define STLINK_SWD_AP_PARITY_ERROR 0x13
#define STLINK_JTAG_WRITE_ERROR 0x0c
#define STLINK_JTAG_WRITE_VERIF_ERROR 0x0d
#define STLINK_SWD_DP_WAIT 0x14
+#define STLINK_SWD_DP_FAULT 0x15
+#define STLINK_SWD_DP_ERROR 0x16
+#define STLINK_SWD_DP_PARITY_ERROR 0x17
+
+#define STLINK_SWD_AP_WDATA_ERROR 0x18
+#define STLINK_SWD_AP_STICKY_ERROR 0x19
+#define STLINK_SWD_AP_STICKYORUN_ERROR 0x1a
#define STLINK_CORE_RUNNING 0x80
#define STLINK_CORE_HALTED 0x81
@@ -208,7 +216,7 @@ struct stlink_usb_handle_s {
#define STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH 0x01
#define STLINK_DEBUG_APIV2_DRIVE_NRST_PULSE 0x02
-#define STLINK_TRACE_SIZE 1024
+#define STLINK_TRACE_SIZE 4096
#define STLINK_TRACE_MAX_HZ 2000000
#define STLINK_TRACE_MIN_VERSION 13
@@ -398,6 +406,38 @@ static int stlink_usb_error_check(void *handle)
case STLINK_JTAG_WRITE_VERIF_ERROR:
LOG_DEBUG("Verify error");
return ERROR_FAIL;
+ case STLINK_SWD_AP_FAULT:
+ /* git://git.ac6.fr/openocd commit 657e3e885b9ee10
+ * returns ERROR_OK with the comment:
+ * Change in error status when reading outside RAM.
+ * This fix allows CDT plugin to visualize memory.
+ */
+ LOG_DEBUG("STLINK_SWD_AP_FAULT");
+ return ERROR_FAIL;
+ case STLINK_SWD_AP_ERROR:
+ LOG_DEBUG("STLINK_SWD_AP_ERROR");
+ return ERROR_FAIL;
+ case STLINK_SWD_AP_PARITY_ERROR:
+ LOG_DEBUG("STLINK_SWD_AP_PARITY_ERROR");
+ return ERROR_FAIL;
+ case STLINK_SWD_DP_FAULT:
+ LOG_DEBUG("STLINK_SWD_DP_FAULT");
+ return ERROR_FAIL;
+ case STLINK_SWD_DP_ERROR:
+ LOG_DEBUG("STLINK_SWD_DP_ERROR");
+ return ERROR_FAIL;
+ case STLINK_SWD_DP_PARITY_ERROR:
+ LOG_DEBUG("STLINK_SWD_DP_PARITY_ERROR");
+ return ERROR_FAIL;
+ case STLINK_SWD_AP_WDATA_ERROR:
+ LOG_DEBUG("STLINK_SWD_AP_WDATA_ERROR");
+ return ERROR_FAIL;
+ case STLINK_SWD_AP_STICKY_ERROR:
+ LOG_DEBUG("STLINK_SWD_AP_STICKY_ERROR");
+ return ERROR_FAIL;
+ case STLINK_SWD_AP_STICKYORUN_ERROR:
+ LOG_DEBUG("STLINK_SWD_AP_STICKYORUN_ERROR");
+ return ERROR_FAIL;
default:
LOG_DEBUG("unknown/unexpected STLINK status code 0x%x", h->databuf[0]);
return ERROR_FAIL;
@@ -1122,7 +1162,7 @@ static int stlink_usb_step(void *handle)
if (h->jtag_api == STLINK_JTAG_API_V2) {
/* TODO: this emulates the v1 api, it should really use a similar auto mask isr
- * that the cortex-m3 currently does. */
+ * that the Cortex-M3 currently does. */
stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_MASKINTS|C_DEBUGEN);
stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_STEP|C_MASKINTS|C_DEBUGEN);
return stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_DEBUGEN);
diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c
index fd613c2d4..77b727c27 100644
--- a/src/jtag/drivers/sysfsgpio.c
+++ b/src/jtag/drivers/sysfsgpio.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* 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 ac4566232..171ac66c4 100644
--- a/src/jtag/drivers/ti_icdi_usb.c
+++ b/src/jtag/drivers/ti_icdi_usb.c
@@ -14,9 +14,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -244,7 +242,8 @@ static int icdi_send_remote_cmd(void *handle, const char *data)
struct icdi_usb_handle_s *h = handle;
size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,");
- cmd_len += hexify(h->write_buffer + cmd_len, data, 0, h->max_packet - cmd_len);
+ cmd_len += hexify(h->write_buffer + cmd_len, (const uint8_t *)data,
+ strlen(data), h->max_packet - cmd_len);
return icdi_send_packet(handle, cmd_len);
}
@@ -268,7 +267,7 @@ static int icdi_get_cmd_result(void *handle)
if (h->read_buffer[offset] == 'E') {
/* get error code */
- char result;
+ uint8_t result;
if (unhexify(&result, h->read_buffer + offset + 1, 1) != 1)
return ERROR_FAIL;
return result;
@@ -330,7 +329,7 @@ static int icdi_usb_version(void *handle)
}
/* convert reply */
- if (unhexify(version, h->read_buffer + 2, 4) != 4) {
+ if (unhexify((uint8_t *)version, h->read_buffer + 2, 4) != 4) {
LOG_WARNING("unable to get ICDI version");
return ERROR_OK;
}
@@ -497,7 +496,7 @@ static int icdi_usb_read_reg(void *handle, int num, uint32_t *val)
/* convert result */
uint8_t buf[4];
- if (unhexify((char *)buf, h->read_buffer + 2, 4) != 4) {
+ if (unhexify(buf, h->read_buffer + 2, 4) != 4) {
LOG_ERROR("failed to convert result");
return ERROR_FAIL;
}
@@ -514,7 +513,7 @@ static int icdi_usb_write_reg(void *handle, int num, uint32_t val)
h_u32_to_le(buf, val);
int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", num);
- hexify(cmd + cmd_len, (const char *)buf, 4, sizeof(cmd));
+ hexify(cmd + cmd_len, buf, 4, sizeof(cmd));
result = icdi_send_cmd(handle, cmd);
if (result != ERROR_OK)
diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c
index cfd693a60..550df1c93 100644
--- a/src/jtag/drivers/ulink.c
+++ b/src/jtag/drivers/ulink.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -193,6 +191,7 @@ int ulink_execute_queued_commands(struct ulink *device, int timeout);
const char *ulink_cmd_id_string(uint8_t id);
void ulink_print_command(struct ulink_cmd *ulink_cmd);
void ulink_print_queue(struct ulink *device);
+static int ulink_calculate_frequency(enum ulink_delay_type type, int delay, long *f);
#endif
int ulink_append_scan_cmd(struct ulink *device,
@@ -225,7 +224,6 @@ int ulink_append_test_cmd(struct ulink *device);
/* OpenULINK TCK frequency helper functions */
int ulink_calculate_delay(enum ulink_delay_type type, long f, int *delay);
-int ulink_calculate_frequency(enum ulink_delay_type type, int delay, long *f);
/* Interface between OpenULINK and OpenOCD */
static void ulink_set_end_state(tap_state_t endstate);
@@ -1369,6 +1367,7 @@ int ulink_calculate_delay(enum ulink_delay_type type, long f, int *delay)
return ERROR_OK;
}
+#ifdef _DEBUG_JTAG_IO_
/**
* Calculate frequency for a given delay value.
*
@@ -1383,7 +1382,7 @@ int ulink_calculate_delay(enum ulink_delay_type type, long f, int *delay)
* @return on success: ERROR_OK
* @return on failure: ERROR_FAIL
*/
-int ulink_calculate_frequency(enum ulink_delay_type type, int delay, long *f)
+static int ulink_calculate_frequency(enum ulink_delay_type type, int delay, long *f)
{
float t, f_float, f_rounded;
@@ -1432,6 +1431,7 @@ int ulink_calculate_frequency(enum ulink_delay_type type, int delay, long *f)
return ERROR_OK;
}
+#endif
/******************* Interface between OpenULINK and OpenOCD ******************/
@@ -2066,7 +2066,7 @@ static int ulink_khz(int khz, int *jtag_speed)
}
#ifdef _DEBUG_JTAG_IO_
- long f_tck, f_tms, f_scan_in, f_scan_out, f_scan_io;
+ long f_tck = 0, f_tms = 0, f_scan_in = 0, f_scan_out = 0, f_scan_io = 0;
ulink_calculate_frequency(DELAY_CLOCK_TCK, ulink_handle->delay_clock_tck,
&f_tck);
diff --git a/src/jtag/drivers/usb_blaster/Makefile.am b/src/jtag/drivers/usb_blaster/Makefile.am
index 0fb470051..a6694c543 100644
--- a/src/jtag/drivers/usb_blaster/Makefile.am
+++ b/src/jtag/drivers/usb_blaster/Makefile.am
@@ -1,24 +1,13 @@
-include $(top_srcdir)/common.mk
+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)
-AM_CPPFLAGS += -I$(top_srcdir)/src/jtag/drivers $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS)
+USB_BLASTER_SRC = %D%/usb_blaster.c %D%/ublast_access.h
-noinst_LTLIBRARIES = libocdusbblaster.la
-libocdusbblaster_la_SOURCES = $(USB_BLASTER_SRC)
-
-USB_BLASTER_SRC = usb_blaster.c
-
-if USB_BLASTER_LIBFTDI
-USB_BLASTER_SRC += ublast_access_ftdi.c
-endif
-
-if USB_BLASTER_FTD2XX
-USB_BLASTER_SRC += ublast_access_ftd2xx.c
+if USB_BLASTER
+USB_BLASTER_SRC += %D%/ublast_access_ftdi.c
endif
if USB_BLASTER_2
-USB_BLASTER_SRC += ublast2_access_libusb.c
+USB_BLASTER_SRC += %D%/ublast2_access_libusb.c
endif
-
-noinst_HEADERS = ublast_access.h
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c
index ac863918c..d99173369 100644
--- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c
+++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c
@@ -13,6 +13,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
*/
#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 5bdc2573a..252f003a9 100644
--- a/src/jtag/drivers/usb_blaster/ublast_access.h
+++ b/src/jtag/drivers/usb_blaster/ublast_access.h
@@ -20,10 +20,13 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
*/
-#ifndef JTAG_UBLAST_ACCESS_H
-#define JTAG_UBLAST_ACCESS_H
+#ifndef OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H
+#define OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H
#include
@@ -53,19 +56,16 @@ struct ublast_lowlevel {
/**
* ublast_register_ftdi - get a lowlevel USB Blaster driver
- * ublast_register_ftd2xx - get a lowlevel USB Blaster driver
* ublast2_register_libusb - get a lowlevel USB Blaster II driver
*
- * Get a lowlevel USB-Blaster driver. In the current implementation, there are 3
+ * Get a lowlevel USB-Blaster driver. In the current implementation, there are 2
* possible lowlevel drivers :
- * - one based on libftdi from ftdichip.com
- * - one based on libftdxx, the free alternative
+ * - one based on libftdi,
* - one based on libusb, specific to the USB-Blaster II
*
* Returns the lowlevel driver structure.
*/
extern struct ublast_lowlevel *ublast_register_ftdi(void);
-extern struct ublast_lowlevel *ublast_register_ftd2xx(void);
extern struct ublast_lowlevel *ublast2_register_libusb(void);
-#endif /* JTAG_UBLAST_ACCESS_H */
+#endif /* 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 2527fe9a6..cb442f2b5 100644
--- a/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c
+++ b/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c
@@ -19,6 +19,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
*/
#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 82e5537f5..a975bd1e2 100644
--- a/src/jtag/drivers/usb_blaster/usb_blaster.c
+++ b/src/jtag/drivers/usb_blaster/usb_blaster.c
@@ -20,6 +20,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
*/
/*
@@ -144,12 +147,9 @@ struct drvs_map {
};
static struct drvs_map lowlevel_drivers_map[] = {
-#if BUILD_USB_BLASTER_LIBFTDI
+#if BUILD_USB_BLASTER
{ .name = "ftdi", .drv_register = ublast_register_ftdi },
#endif
-#if BUILD_USB_BLASTER_FTD2XX
- { .name = "ftd2xx", .drv_register = ublast_register_ftd2xx },
-#endif
#if BUILD_USB_BLASTER_2
{ .name = "ublast2", .drv_register = ublast2_register_libusb },
#endif
@@ -1045,8 +1045,8 @@ static const struct command_registration ublast_command_handlers[] = {
.name = "usb_blaster_lowlevel_driver",
.handler = ublast_handle_lowlevel_drv_command,
.mode = COMMAND_CONFIG,
- .help = "set the lowlevel access for the USB Blaster (ftdi, ftd2xx, ublast2)",
- .usage = "(ftdi|ftd2xx|ublast2)",
+ .help = "set the lowlevel access for the USB Blaster (ftdi, ublast2)",
+ .usage = "(ftdi|ublast2)",
},
{
.name = "usb_blaster_pin",
diff --git a/src/jtag/drivers/usb_common.c b/src/jtag/drivers/usb_common.c
index 4f6a72296..54be6a624 100644
--- a/src/jtag/drivers/usb_common.c
+++ b/src/jtag/drivers/usb_common.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/usb_common.h b/src/jtag/drivers/usb_common.h
index d34c20b9b..4d2bd2686 100644
--- a/src/jtag/drivers/usb_common.h
+++ b/src/jtag/drivers/usb_common.h
@@ -12,17 +12,15 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef JTAG_USB_COMMON_H
-#define JTAG_USB_COMMON_H
+#ifndef OPENOCD_JTAG_DRIVERS_USB_COMMON_H
+#define OPENOCD_JTAG_DRIVERS_USB_COMMON_H
#include
int jtag_usb_open(const uint16_t vids[], const uint16_t pids[],
struct usb_dev_handle **out);
-#endif /* JTAG_USB_COMMON_H */
+#endif /* OPENOCD_JTAG_DRIVERS_USB_COMMON_H */
diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c
index 156edf022..d81c329d4 100644
--- a/src/jtag/drivers/usbprog.c
+++ b/src/jtag/drivers/usbprog.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c
index c3a09a2ae..0d60725a6 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c
index c8684a77a..f2ea175ad 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c
index a0dfb996e..16433aff5 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c
index cd9d51c03..ef1b675f7 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c
index 65e54e4e6..53a7e989b 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h
index fa53062bd..98a056a8b 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __USBTOXXX_H_INCLUDED__
-#define __USBTOXXX_H_INCLUDED__
+#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_H
+#define OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_H
RESULT usbtoxxx_init(void);
RESULT usbtoxxx_fini(void);
@@ -236,4 +234,4 @@ RESULT usbtopwm_config(uint8_t interface_index, uint16_t kHz, uint8_t mode);
RESULT usbtopwm_out(uint8_t interface_index, uint16_t count, uint16_t *rate);
RESULT usbtopwm_in(uint8_t interface_index, uint16_t count, uint16_t *rate);
-#endif /* __USBTOXXX_H_INCLUDED__ */
+#endif /* 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 4d8dfcf8a..e40667e91 100644
--- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h
+++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __USBTOXXX_INTERNAL_H_INCLUDED__
-#define __USBTOXXX_INTERNAL_H_INCLUDED__
+#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_INTERNAL_H
+#define OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_INTERNAL_H
/* USB_TO_XXX USB Commands */
/* Page0 */
@@ -160,4 +158,4 @@ RESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf,
/* USB_TO_GPIO */
#define USB_TO_GPIO_DIR_MSK 0x01
-#endif /* __USBTOXXX_INTERNAL_H_INCLUDED__ */
+#endif /* 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 04d73cf38..146383961 100644
--- a/src/jtag/drivers/versaloon/versaloon.c
+++ b/src/jtag/drivers/versaloon/versaloon.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/drivers/versaloon/versaloon.h b/src/jtag/drivers/versaloon/versaloon.h
index 46f5c3191..9d92bcaa1 100644
--- a/src/jtag/drivers/versaloon/versaloon.h
+++ b/src/jtag/drivers/versaloon/versaloon.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __VERSALOON_H_INCLUDED__
-#define __VERSALOON_H_INCLUDED__
+#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H
+#define OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H
#include
@@ -111,5 +109,4 @@ struct versaloon_interface_t {
extern struct versaloon_interface_t versaloon_interface;
extern libusb_device_handle *versaloon_usb_device_handle;
-#endif /* __VERSALOON_H_INCLUDED__ */
-
+#endif /* 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 2eb374a7e..089056d02 100644
--- a/src/jtag/drivers/versaloon/versaloon_include.h
+++ b/src/jtag/drivers/versaloon/versaloon_include.h
@@ -12,11 +12,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INCLUDE_H
+#define OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INCLUDE_H
+
/* This file is used to include different header and macros */
/* according to different platform */
#include
@@ -97,3 +98,5 @@
#define SET_LE_U32(p, v) SET_U32_LSBFIRST(p, v)
#define SET_BE_U16(p, v) SET_U16_MSBFIRST(p, v)
#define SET_BE_U32(p, v) SET_U32_MSBFIRST(p, v)
+
+#endif /* 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 66712dba5..497b6b9ce 100644
--- a/src/jtag/drivers/versaloon/versaloon_internal.h
+++ b/src/jtag/drivers/versaloon/versaloon_internal.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __VERSALOON_INTERNAL_H_INCLUDED__
-#define __VERSALOON_INTERNAL_H_INCLUDED__
+#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INTERNAL_H
+#define OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INTERNAL_H
#define VERSALOON_PRODUCTSTRING_INDEX 2
#define VERSALOON_SERIALSTRING_INDEX 3
@@ -109,4 +107,4 @@ extern uint8_t *versaloon_buf;
extern uint8_t *versaloon_cmd_buf;
extern uint16_t versaloon_buf_size;
-#endif /* __VERSALOON_INTERNAL_H_INCLUDED__ */
+#endif /* OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INTERNAL_H */
diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c
index 801de650b..6f7e9cadf 100644
--- a/src/jtag/drivers/vsllink.c
+++ b/src/jtag/drivers/vsllink.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* Versaloon is a programming tool for multiple MCUs.
diff --git a/src/jtag/drivers/w_jtag_sj.c b/src/jtag/drivers/w_jtag_sj.c
index 68c7cf43b..d1e43d564 100644
--- a/src/jtag/drivers/w_jtag_sj.c
+++ b/src/jtag/drivers/w_jtag_sj.c
@@ -389,7 +389,7 @@ static void wjtagsj_execute_stableclocks(struct jtag_command *cmd)
/* 7 bits of either ones or zeros. */
uint8_t tms = tap_get_state() == TAP_RESET ? 0x7f : 0x00;
- //Ö±½ÓÊä³ö
+ //Ö±\BD\D3\CA\E4\B3\F6
wjtagsj_clock_tms_cs_out(wjtagsj_ctx1,&tms, 0,num_cycles);
@@ -535,11 +535,11 @@ static int wjtagsj_config_trace(bool enabled, enum tpio_pin_protocol pin_protoco
return ERROR_FAIL;
}
- if(enabled)
- if (pin_protocol != ASYNC_UART) {
+ if(enabled) {
+ if (pin_protocol != ASYNC_UART) {
LOG_ERROR("Selected pin protocol is not supported.");
return ERROR_FAIL;
-
+ }
if(*trace_freq > swo_max_freq) {
LOG_ERROR("Frequency exceed the limit of max swo baudrate");
return ERROR_FAIL;
@@ -584,7 +584,7 @@ static int wjtagsj_initialize(void)
else
LOG_DEBUG("interface using shortest path jtag state transitions");
- //³¢ÊÔ´ò¿ªµÚÒ»¸ö
+ //\B3\A2\CAԴ򿪵\DAһ\B8\F6
for (int i = 0; wjtagsj_vid[i] || wjtagsj_pid[i]; i++) {
wjtagsj_ctx1 = wjtagsj_open(&wjtagsj_vid[i], &wjtagsj_pid[i], wjtagsj_device_desc,
wjtagsj_serial, wjtagsj_channel);
diff --git a/src/jtag/hla/Makefile.am b/src/jtag/hla/Makefile.am
index 4fbc70e9c..6bb2960eb 100644
--- a/src/jtag/hla/Makefile.am
+++ b/src/jtag/hla/Makefile.am
@@ -1,23 +1,11 @@
-include $(top_srcdir)/common.mk
-
-noinst_LTLIBRARIES = libocdhla.la
-
-libocdhla_la_SOURCES = \
- $(HLFILES)
-
-HLFILES =
-
-if HLADAPTER
-HLFILES += hla_transport.c
-HLFILES += hla_tcl.c
-HLFILES += hla_interface.c
-HLFILES += hla_layout.c
-endif
-
-noinst_HEADERS = \
- hla_interface.h \
- hla_layout.h \
- hla_tcl.h \
- hla_transport.h
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+noinst_LTLIBRARIES += %D%/libocdhla.la
+
+%C%_libocdhla_la_SOURCES = \
+ %D%/hla_transport.c \
+ %D%/hla_tcl.c \
+ %D%/hla_interface.c \
+ %D%/hla_layout.c \
+ %D%/hla_transport.h \
+ %D%/hla_interface.h \
+ %D%/hla_layout.h \
+ %D%/hla_tcl.h
diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c
index a208e9fd0..9217631b0 100644
--- a/src/jtag/hla/hla_interface.c
+++ b/src/jtag/hla/hla_interface.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h
index a15592572..0992d1cad 100644
--- a/src/jtag/hla/hla_interface.h
+++ b/src/jtag/hla/hla_interface.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _HL_INTERFACE
-#define _HL_INTERFACE
+#ifndef OPENOCD_JTAG_HLA_HLA_INTERFACE_H
+#define OPENOCD_JTAG_HLA_HLA_INTERFACE_H
/** */
struct target;
@@ -67,4 +65,4 @@ int hl_interface_init_target(struct target *t);
int hl_interface_init_reset(void);
int hl_interface_override_target(const char **targetname);
-#endif /* _HL_INTERFACE */
+#endif /* OPENOCD_JTAG_HLA_HLA_INTERFACE_H */
diff --git a/src/jtag/hla/hla_layout.c b/src/jtag/hla/hla_layout.c
index 0a20fbd36..c5e35182d 100644
--- a/src/jtag/hla/hla_layout.c
+++ b/src/jtag/hla/hla_layout.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/hla/hla_layout.h b/src/jtag/hla/hla_layout.h
index 8833d6c80..40c1321ba 100644
--- a/src/jtag/hla/hla_layout.h
+++ b/src/jtag/hla/hla_layout.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _HL_LAYOUT_H
-#define _HL_LAYOUT_H
+#ifndef OPENOCD_JTAG_HLA_HLA_LAYOUT_H
+#define OPENOCD_JTAG_HLA_HLA_LAYOUT_H
#include
@@ -127,4 +125,4 @@ const struct hl_layout *hl_layout_get_list(void);
/** */
int hl_layout_init(struct hl_interface_s *adapter);
-#endif /* _HL_LAYOUT_H */
+#endif /* OPENOCD_JTAG_HLA_HLA_LAYOUT_H */
diff --git a/src/jtag/hla/hla_tcl.c b/src/jtag/hla/hla_tcl.c
index 20082f385..9378427b0 100644
--- a/src/jtag/hla/hla_tcl.c
+++ b/src/jtag/hla/hla_tcl.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -100,11 +98,13 @@ static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi)
free(pTap);
return JIM_ERR;
}
- Jim_GetOpt_String(goi, &cp, NULL);
- pTap->chip = strdup(cp);
- Jim_GetOpt_String(goi, &cp, NULL);
- pTap->tapname = strdup(cp);
+ const char *tmp;
+ Jim_GetOpt_String(goi, &tmp, NULL);
+ pTap->chip = strdup(tmp);
+
+ Jim_GetOpt_String(goi, &tmp, NULL);
+ pTap->tapname = strdup(tmp);
/* name + dot + name + null */
x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
diff --git a/src/jtag/hla/hla_tcl.h b/src/jtag/hla/hla_tcl.h
index 3ce3effab..ac00add51 100644
--- a/src/jtag/hla/hla_tcl.h
+++ b/src/jtag/hla/hla_tcl.h
@@ -16,15 +16,13 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _HL_TCL_
-#define _HL_TCL_
+#ifndef OPENOCD_JTAG_HLA_HLA_TCL_H
+#define OPENOCD_JTAG_HLA_HLA_TCL_H
/** */
int jim_hl_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv);
-#endif /* _HL_TCL_ */
+#endif /* OPENOCD_JTAG_HLA_HLA_TCL_H */
diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c
index ae7cbb1ac..5a5671db6 100644
--- a/src/jtag/hla/hla_transport.c
+++ b/src/jtag/hla/hla_transport.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/hla/hla_transport.h b/src/jtag/hla/hla_transport.h
index 09eece282..07eb751e2 100644
--- a/src/jtag/hla/hla_transport.h
+++ b/src/jtag/hla/hla_transport.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _HL_TRANSPORT
-#define _HL_TRANSPORT
+#ifndef OPENOCD_JTAG_HLA_HLA_TRANSPORT_H
+#define OPENOCD_JTAG_HLA_HLA_TRANSPORT_H
enum hl_transports {
HL_TRANSPORT_UNKNOWN = 0,
@@ -31,4 +29,4 @@ enum hl_transports {
HL_TRANSPORT_SWIM
};
-#endif /* _HL_TRANSPORT */
+#endif /* OPENOCD_JTAG_HLA_HLA_TRANSPORT_H */
diff --git a/src/jtag/interface.c b/src/jtag/interface.c
index 19a0b052c..e12b2aebb 100644
--- a/src/jtag/interface.c
+++ b/src/jtag/interface.c
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/interface.h b/src/jtag/interface.h
index e7b20148e..cdfc676ee 100644
--- a/src/jtag/interface.h
+++ b/src/jtag/interface.h
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef OPENOCD_JTAG_INTERFACE_H
diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c
index 9a331485d..6960f4c29 100644
--- a/src/jtag/interfaces.c
+++ b/src/jtag/interfaces.c
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -53,19 +51,13 @@ extern struct jtag_interface parport_interface;
#if BUILD_DUMMY == 1
extern struct jtag_interface dummy_interface;
#endif
-#if BUILD_FT2232_FTD2XX == 1
-extern struct jtag_interface ft2232_interface;
-#endif
-#if BUILD_FT2232_LIBFTDI == 1
-extern struct jtag_interface ft2232_interface;
-#endif
#if BUILD_FTDI == 1
extern struct jtag_interface ftdi_interface;
#endif
#if BUILD_W_JTAG_SJ == 1
extern struct jtag_interface w_jtag_sj_interface;
#endif
-#if BUILD_USB_BLASTER_LIBFTDI == 1 || BUILD_USB_BLASTER_FTD2XX == 1 || BUILD_USB_BLASTER_2 == 1
+#if BUILD_USB_BLASTER == 1 || BUILD_USB_BLASTER_2 == 1
extern struct jtag_interface usb_blaster_interface;
#endif
#if BUILD_JTAG_VPI == 1
@@ -83,7 +75,7 @@ extern struct jtag_interface at91rm9200_interface;
#if BUILD_GW16012 == 1
extern struct jtag_interface gw16012_interface;
#endif
-#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
+#if BUILD_PRESTO
extern struct jtag_interface presto_interface;
#endif
#if BUILD_USBPROG == 1
@@ -134,6 +126,12 @@ extern struct jtag_interface bcm2835gpio_interface;
#if BUILD_CMSIS_DAP == 1
extern struct jtag_interface cmsis_dap_interface;
#endif
+#if BUILD_KITPROG == 1
+extern struct jtag_interface kitprog_interface;
+#endif
+#if BUILD_IMX_GPIO == 1
+extern struct jtag_interface imx_gpio_interface;
+#endif
#endif /* standard drivers */
/**
@@ -155,19 +153,13 @@ struct jtag_interface *jtag_interfaces[] = {
#if BUILD_DUMMY == 1
&dummy_interface,
#endif
-#if BUILD_FT2232_FTD2XX == 1
- &ft2232_interface,
-#endif
-#if BUILD_FT2232_LIBFTDI == 1
- &ft2232_interface,
-#endif
#if BUILD_FTDI == 1
&ftdi_interface,
#endif
#if BUILD_W_JTAG_SJ == 1
&w_jtag_sj_interface,
#endif
-#if BUILD_USB_BLASTER_LIBFTDI == 1 || BUILD_USB_BLASTER_FTD2XX == 1 || BUILD_USB_BLASTER_2 == 1
+#if BUILD_USB_BLASTER || BUILD_USB_BLASTER_2 == 1
&usb_blaster_interface,
#endif
#if BUILD_JTAG_VPI == 1
@@ -185,7 +177,7 @@ struct jtag_interface *jtag_interfaces[] = {
#if BUILD_GW16012 == 1
&gw16012_interface,
#endif
-#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
+#if BUILD_PRESTO
&presto_interface,
#endif
#if BUILD_USBPROG == 1
@@ -236,6 +228,12 @@ struct jtag_interface *jtag_interfaces[] = {
#if BUILD_CMSIS_DAP == 1
&cmsis_dap_interface,
#endif
+#if BUILD_KITPROG == 1
+ &kitprog_interface,
+#endif
+#if BUILD_IMX_GPIO == 1
+ &imx_gpio_interface,
+#endif
#endif /* standard drivers */
NULL,
};
diff --git a/src/jtag/interfaces.h b/src/jtag/interfaces.h
index e17420f53..02d201b1f 100644
--- a/src/jtag/interfaces.h
+++ b/src/jtag/interfaces.h
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifndef OPENOCD_JTAG_INTERFACES_H
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index eda4ccdd5..7702d6ca8 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -16,13 +16,11 @@
* GNU 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., *
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+* along with this program. If not, see . *
***************************************************************************/
-#ifndef JTAG_H
-#define JTAG_H
+#ifndef OPENOCD_JTAG_JTAG_H
+#define OPENOCD_JTAG_JTAG_H
#include
#include
@@ -107,7 +105,7 @@ extern tap_state_t cmd_queue_cur_state;
* jtag_add_dr_scan_check() to validate the value that was scanned out.
*/
struct scan_field {
- /** The number of bits this field specifies (up to 32) */
+ /** The number of bits this field specifies */
int num_bits;
/** A pointer to value to be scanned into the device */
const uint8_t *out_value;
@@ -648,4 +646,4 @@ bool transport_is_jtag(void);
int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
-#endif /* JTAG_H */
+#endif /* OPENOCD_JTAG_JTAG_H */
diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h
index 0de870926..688c39630 100644
--- a/src/jtag/minidriver.h
+++ b/src/jtag/minidriver.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef MINIDRIVER_H
-#define MINIDRIVER_H
+#ifndef OPENOCD_JTAG_MINIDRIVER_H
+#define OPENOCD_JTAG_MINIDRIVER_H
/**
* @page jtagminidriver JTAG Mini-Driver
@@ -89,4 +87,4 @@ int interface_jtag_execute_queue(void);
*/
int default_interface_jtag_execute_queue(void);
-#endif /* MINIDRIVER_H */
+#endif /* OPENOCD_JTAG_MINIDRIVER_H */
diff --git a/src/jtag/minidriver/minidriver_imp.h b/src/jtag/minidriver/minidriver_imp.h
index 8ad992c1d..11d0fae72 100644
--- a/src/jtag/minidriver/minidriver_imp.h
+++ b/src/jtag/minidriver/minidriver_imp.h
@@ -14,13 +14,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef MINIDRIVER_IMP_H
-#define MINIDRIVER_IMP_H
+#ifndef OPENOCD_JTAG_MINIDRIVER_MINIDRIVER_IMP_H
+#define OPENOCD_JTAG_MINIDRIVER_MINIDRIVER_IMP_H
#include
@@ -29,4 +27,4 @@
#define jtag_add_callback4(callback, in, data1, data2, data3) \
interface_jtag_add_callback4(callback, in, data1, data2, data3)
-#endif /* MINIDRIVER_IMP_H */
+#endif /* OPENOCD_JTAG_MINIDRIVER_MINIDRIVER_IMP_H */
diff --git a/src/jtag/minidummy/jtag_minidriver.h b/src/jtag/minidummy/jtag_minidriver.h
index 452fbc8bb..1708356a5 100644
--- a/src/jtag/minidummy/jtag_minidriver.h
+++ b/src/jtag/minidummy/jtag_minidriver.h
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#define interface_jtag_add_callback(callback, in) callback(in)
diff --git a/src/jtag/minidummy/minidummy.c b/src/jtag/minidummy/minidummy.c
index 4f04acdeb..b7c989fc0 100644
--- a/src/jtag/minidummy/minidummy.c
+++ b/src/jtag/minidummy/minidummy.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/jtag/swd.h b/src/jtag/swd.h
index d208f393b..c888cc07d 100644
--- a/src/jtag/swd.h
+++ b/src/jtag/swd.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef SWD_H
-#define SWD_H
+#ifndef OPENOCD_JTAG_SWD_H
+#define OPENOCD_JTAG_SWD_H
#include
@@ -215,4 +213,4 @@ void swd_add_reset(int req_srst);
bool transport_is_swd(void);
-#endif /* SWD_H */
+#endif /* OPENOCD_JTAG_SWD_H */
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index c916fb1ca..bc6bbf204 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -23,9 +23,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -533,11 +531,13 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
free(pTap);
return JIM_ERR;
}
- Jim_GetOpt_String(goi, &cp, NULL);
- pTap->chip = strdup(cp);
- Jim_GetOpt_String(goi, &cp, NULL);
- pTap->tapname = strdup(cp);
+ const char *tmp;
+ Jim_GetOpt_String(goi, &tmp, NULL);
+ pTap->chip = strdup(tmp);
+
+ Jim_GetOpt_String(goi, &tmp, NULL);
+ pTap->tapname = strdup(tmp);
/* name + dot + name + null */
x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
@@ -1247,7 +1247,7 @@ COMMAND_HANDLER(handle_wait_srst_deassert)
LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms);
int asserted_yet;
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {
if ((timeval_ms() - then) > timeout_ms) {
LOG_ERROR("Timed out");
diff --git a/src/jtag/tcl.h b/src/jtag/tcl.h
index 95dea13c0..932b47ac8 100644
--- a/src/jtag/tcl.h
+++ b/src/jtag/tcl.h
@@ -23,17 +23,15 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _JTAG_TCL_H_
-#define _JTAG_TCL_H_
+#ifndef OPENOCD_JTAG_TCL_H
+#define OPENOCD_JTAG_TCL_H
int jim_jtag_configure(Jim_Interp *interp, int argc,
Jim_Obj * const *argv);
int jim_jtag_tap_enabler(Jim_Interp *interp, int argc,
Jim_Obj * const *argv);
-#endif
+#endif /* OPENOCD_JTAG_TCL_H */
diff --git a/src/jtag/zy1000/jtag_minidriver.h b/src/jtag/zy1000/jtag_minidriver.h
index d7fa43761..7d1ede5d4 100644
--- a/src/jtag/zy1000/jtag_minidriver.h
+++ b/src/jtag/zy1000/jtag_minidriver.h
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* used to test manual mode */
diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c
index 16c3e5d0f..67d990700 100644
--- a/src/jtag/zy1000/zy1000.c
+++ b/src/jtag/zy1000/zy1000.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* This file supports the zy1000 debugger:
@@ -147,8 +145,8 @@ static int zy1000_power_dropout(int *dropout)
static void waitSRST(bool asserted)
{
bool first = true;
- long long start = 0;
- long total = 0;
+ int64_t start = 0;
+ int64_t total = 0;
const char *mode = asserted ? "assert" : "deassert";
for (;; ) {
@@ -169,7 +167,7 @@ static void waitSRST(bool asserted)
keep_alive();
if (total > 5000) {
- LOG_ERROR("SRST took too long to %s: %dms", mode, (int)total);
+ LOG_ERROR("SRST took too long to %s: %" PRId64 "ms", mode, total);
break;
}
}
diff --git a/src/main.c b/src/main.c
index f3ff51b66..83e60d8e0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/openocd.c b/src/openocd.c
index 7d5cad171..1b72448a7 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -47,7 +45,10 @@
#include
#endif
-#define OPENOCD_BRANDING ""
+// [GNU MCU Eclipse]
+// Add --enable-branding='GNU MCU Eclipse' at build time
+#if defined(BUILD_BRANDING)
+
#if INTPTR_MAX == INT32_MAX
#define OPENOCD_WORDSIZE "32-bits "
#elif INTPTR_MAX == INT64_MAX
@@ -56,8 +57,25 @@
#define OPENOCD_WORDSIZE ""
#endif
-#define OPENOCD_VERSION OPENOCD_BRANDING OPENOCD_WORDSIZE \
+#ifdef PKGBLDDATE
+#define OPENOCD_VERSION BUILD_BRANDING " " OPENOCD_WORDSIZE \
"Open On-Chip Debugger " VERSION RELSTR " (" PKGBLDDATE ")"
+#else
+#define OPENOCD_VERSION BUILD_BRANDING " " OPENOCD_WORDSIZE \
+ "Open On-Chip Debugger " VERSION RELSTR
+#endif
+
+#else
+
+#ifdef PKGBLDDATE
+#define OPENOCD_VERSION \
+ "Open On-Chip Debugger " VERSION RELSTR " (" PKGBLDDATE ")"
+#else
+#define OPENOCD_VERSION \
+ "Open On-Chip Debugger " VERSION RELSTR
+#endif
+
+#endif
static const char openocd_startup_tcl[] = {
#include "startup_tcl.inc"
@@ -303,8 +321,10 @@ static int openocd_thread(int argc, char *argv[], struct command_context *cmd_ct
if (init_at_startup) {
ret = command_run_line(cmd_ctx, "init");
- if (ERROR_OK != ret)
+ if (ERROR_OK != ret) {
+ server_quit();
return ERROR_FAIL;
+ }
}
ret = server_loop(cmd_ctx);
diff --git a/src/openocd.h b/src/openocd.h
index 6d87c2af9..543ac3c23 100644
--- a/src/openocd.h
+++ b/src/openocd.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef OPENOCD_H
-#define OPENOCD_H
+#ifndef OPENOCD_OPENOCD_H
+#define OPENOCD_OPENOCD_H
/**
* Different applications can define this entry point to override
@@ -31,4 +29,4 @@
*/
int openocd_main(int argc, char *argv[]);
-#endif
+#endif /* OPENOCD_OPENOCD_H */
diff --git a/src/pld/Makefile.am b/src/pld/Makefile.am
index 93b79f4a1..7f3a55423 100644
--- a/src/pld/Makefile.am
+++ b/src/pld/Makefile.am
@@ -1,8 +1,8 @@
-include $(top_srcdir)/common.mk
-
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libpld.la
-noinst_HEADERS = pld.h xilinx_bit.h virtex2.h
-libpld_la_SOURCES = pld.c xilinx_bit.c virtex2.c
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+noinst_LTLIBRARIES += %D%/libpld.la
+%C%_libpld_la_SOURCES = \
+ %D%/pld.c \
+ %D%/xilinx_bit.c \
+ %D%/virtex2.c \
+ %D%/pld.h \
+ %D%/xilinx_bit.h \
+ %D%/virtex2.h
diff --git a/src/pld/pld.c b/src/pld/pld.c
index fb5d32ed6..5210b97b7 100644
--- a/src/pld/pld.c
+++ b/src/pld/pld.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/pld/pld.h b/src/pld/pld.h
index c089fe635..3178fd459 100644
--- a/src/pld/pld.h
+++ b/src/pld/pld.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef PLD_H
-#define PLD_H
+#ifndef OPENOCD_PLD_PLD_H
+#define OPENOCD_PLD_PLD_H
#include
@@ -51,4 +49,4 @@ struct pld_device *get_pld_device_by_num(int num);
#define ERROR_PLD_DEVICE_INVALID (-1000)
#define ERROR_PLD_FILE_LOAD_FAILED (-1001)
-#endif /* PLD_H */
+#endif /* OPENOCD_PLD_PLD_H */
diff --git a/src/pld/virtex2.c b/src/pld/virtex2.c
index 82eb788f9..4e385e97b 100644
--- a/src/pld/virtex2.c
+++ b/src/pld/virtex2.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/pld/virtex2.h b/src/pld/virtex2.h
index 8ed1c1c77..d6d922e79 100644
--- a/src/pld/virtex2.h
+++ b/src/pld/virtex2.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef VIRTEX2_H
-#define VIRTEX2_H
+#ifndef OPENOCD_PLD_VIRTEX2_H
+#define OPENOCD_PLD_VIRTEX2_H
#include
@@ -28,4 +26,4 @@ struct virtex2_pld_device {
int no_jstart;
};
-#endif /* VIRTEX2_H */
+#endif /* OPENOCD_PLD_VIRTEX2_H */
diff --git a/src/pld/xilinx_bit.c b/src/pld/xilinx_bit.c
index cd414ba8a..a975a7a0c 100644
--- a/src/pld/xilinx_bit.c
+++ b/src/pld/xilinx_bit.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/pld/xilinx_bit.h b/src/pld/xilinx_bit.h
index d507dfcf8..1a35c3be2 100644
--- a/src/pld/xilinx_bit.h
+++ b/src/pld/xilinx_bit.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef XILINX_BIT_H
-#define XILINX_BIT_H
+#ifndef OPENOCD_PLD_XILINX_BIT_H
+#define OPENOCD_PLD_XILINX_BIT_H
struct xilinx_bit_file {
uint8_t unknown_header[13];
@@ -33,4 +31,4 @@ struct xilinx_bit_file {
int xilinx_read_bit_file(struct xilinx_bit_file *bit_file, const char *filename);
-#endif /* XILINX_BIT_H */
+#endif /* OPENOCD_PLD_XILINX_BIT_H */
diff --git a/src/rtos/ChibiOS.c b/src/rtos/ChibiOS.c
index 84393860c..1bc1af8fc 100644
--- a/src/rtos/ChibiOS.c
+++ b/src/rtos/ChibiOS.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -130,15 +128,13 @@ struct rtos_type ChibiOS_rtos = {
enum ChibiOS_symbol_values {
ChibiOS_VAL_rlist = 0,
ChibiOS_VAL_ch = 1,
- ChibiOS_VAL_ch_debug = 2,
- ChibiOS_VAL_chSysInit = 3
+ ChibiOS_VAL_ch_debug = 2
};
static symbol_table_elem_t ChibiOS_symbol_list[] = {
{ "rlist", 0, true}, /* Thread ready list */
{ "ch", 0, true}, /* System data structure */
{ "ch_debug", 0, false}, /* Memory Signature containing offsets of fields in rlist */
- { "chSysInit", 0, false}, /* Necessary part of API, used for ChibiOS detection */
{ NULL, 0, false}
};
@@ -226,7 +222,7 @@ static int ChibiOS_update_stacking(struct rtos *rtos)
/* Sometimes the stacking can not be determined only by looking at the
* target name but only a runtime.
*
- * For example, this is the case for cortex-m4 targets and ChibiOS which
+ * For example, this is the case for Cortex-M4 targets and ChibiOS which
* only stack the FPU registers if it is enabled during ChibiOS build.
*
* Terminating which stacking is used is target depending.
@@ -248,7 +244,7 @@ static int ChibiOS_update_stacking(struct rtos *rtos)
struct ChibiOS_params *param;
param = (struct ChibiOS_params *) rtos->rtos_specific_params;
- /* Check for armv7m with *enabled* FPU, i.e. a Cortex M4 */
+ /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4 */
struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);
if (is_armv7m(armv7m_target)) {
if (armv7m_target->fp_feature == FPv4_SP) {
@@ -361,7 +357,6 @@ static int ChibiOS_update_threads(struct rtos *rtos)
sizeof(struct thread_detail));
rtos->thread_details->threadid = 1;
rtos->thread_details->exists = true;
- rtos->thread_details->display_str = NULL;
rtos->thread_details->extra_info_str = malloc(
sizeof(tmp_thread_extra_info));
@@ -445,14 +440,13 @@ static int ChibiOS_update_threads(struct rtos *rtos)
if (threadState < CHIBIOS_NUM_STATES)
state_desc = ChibiOS_thread_states[threadState];
else
- state_desc = "Unknown state";
+ state_desc = "Unknown";
curr_thrd_details->extra_info_str = malloc(strlen(
- state_desc)+1);
- strcpy(curr_thrd_details->extra_info_str, state_desc);
+ state_desc)+8);
+ sprintf(curr_thrd_details->extra_info_str, "State: %s", state_desc);
curr_thrd_details->exists = true;
- curr_thrd_details->display_str = NULL;
curr_thrd_details++;
}
@@ -520,12 +514,11 @@ static int ChibiOS_detect_rtos(struct target *target)
{
if ((target->rtos->symbols != NULL) &&
((target->rtos->symbols[ChibiOS_VAL_rlist].address != 0) ||
- (target->rtos->symbols[ChibiOS_VAL_ch].address != 0)) &&
- (target->rtos->symbols[ChibiOS_VAL_chSysInit].address != 0)) {
+ (target->rtos->symbols[ChibiOS_VAL_ch].address != 0))) {
if (target->rtos->symbols[ChibiOS_VAL_ch_debug].address == 0) {
- LOG_INFO("It looks like the target is running ChibiOS without "
- "ch_debug.");
+ LOG_INFO("It looks like the target may be running ChibiOS "
+ "without ch_debug.");
return 0;
}
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
index 1ce680724..83961eb95 100644
--- a/src/rtos/FreeRTOS.c
+++ b/src/rtos/FreeRTOS.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -30,6 +28,10 @@
#include "helper/log.h"
#include "helper/types.h"
#include "rtos_standard_stackings.h"
+#include "target/armv7m.h"
+#include "target/cortex_m.h"
+
+
#define FREERTOS_MAX_PRIORITIES 63
@@ -45,7 +47,9 @@ struct FreeRTOS_params {
const unsigned char list_elem_content_offset;
const unsigned char thread_stack_offset;
const unsigned char thread_name_offset;
- const struct rtos_register_stacking *stacking_info;
+ const struct rtos_register_stacking *stacking_info_cm3;
+ const struct rtos_register_stacking *stacking_info_cm4f;
+ const struct rtos_register_stacking *stacking_info_cm4f_fpu;
};
static const struct FreeRTOS_params FreeRTOS_params_list[] = {
@@ -60,6 +64,8 @@ static const struct FreeRTOS_params FreeRTOS_params_list[] = {
0, /* thread_stack_offset; */
52, /* thread_name_offset; */
&rtos_standard_Cortex_M3_stacking, /* stacking_info */
+ &rtos_standard_Cortex_M4F_stacking,
+ &rtos_standard_Cortex_M4F_FPU_stacking,
},
{
"hla_target", /* target_name */
@@ -72,6 +78,8 @@ static const struct FreeRTOS_params FreeRTOS_params_list[] = {
0, /* thread_stack_offset; */
52, /* thread_name_offset; */
&rtos_standard_Cortex_M3_stacking, /* stacking_info */
+ &rtos_standard_Cortex_M4F_stacking,
+ &rtos_standard_Cortex_M4F_FPU_stacking,
},
{
"nds32_v3", /* target_name */
@@ -84,6 +92,8 @@ static const struct FreeRTOS_params FreeRTOS_params_list[] = {
0, /* thread_stack_offset; */
52, /* thread_name_offset; */
&rtos_standard_NDS32_N1068_stacking, /* stacking_info */
+ &rtos_standard_Cortex_M4F_stacking,
+ &rtos_standard_Cortex_M4F_FPU_stacking,
},
};
@@ -211,7 +221,6 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
}
rtos->thread_details->threadid = 1;
rtos->thread_details->exists = true;
- rtos->thread_details->display_str = NULL;
rtos->thread_details->extra_info_str = NULL;
rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));
strcpy(rtos->thread_details->thread_name_str, tmp_str);
@@ -350,11 +359,10 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
rtos->thread_details[tasks_found].thread_name_str =
malloc(strlen(tmp_str)+1);
strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);
- rtos->thread_details[tasks_found].display_str = NULL;
rtos->thread_details[tasks_found].exists = true;
if (rtos->thread_details[tasks_found].threadid == rtos->current_thread) {
- char running_str[] = "Running";
+ char running_str[] = "State: Running";
rtos->thread_details[tasks_found].extra_info_str = malloc(
sizeof(running_str));
strcpy(rtos->thread_details[tasks_found].extra_info_str,
@@ -418,7 +426,45 @@ static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, ch
thread_id + param->thread_stack_offset,
stack_ptr);
- return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, hex_reg_list);
+ /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4F */
+ 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) {
+ /* Found ARM v7m target which includes a FPU */
+ uint32_t cpacr;
+
+ retval = target_read_u32(rtos->target, FPU_CPACR, &cpacr);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Could not read CPACR register to check FPU state");
+ return -1;
+ }
+
+ /* Check if CP10 and CP11 are set to full access. */
+ if (cpacr & 0x00F00000) {
+ /* Found target with enabled FPU */
+ cm4_fpu_enabled = 1;
+ }
+ }
+ }
+
+ if (cm4_fpu_enabled == 1) {
+ /* Read the LR to decide between stacking with or without FPU */
+ uint32_t LR_svc = 0;
+ retval = target_read_buffer(rtos->target,
+ stack_ptr + 0x20,
+ param->pointer_width,
+ (uint8_t *)&LR_svc);
+ if (retval != ERROR_OK) {
+ LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
+ return retval;
+ }
+ if ((LR_svc & 0x10) == 0)
+ return rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f_fpu, stack_ptr, hex_reg_list);
+ else
+ return rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f, stack_ptr, hex_reg_list);
+ } else
+ return rtos_generic_stack_read(rtos->target, param->stacking_info_cm3, stack_ptr, hex_reg_list);
}
static int FreeRTOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am
index 62293ec66..27d9cd66a 100644
--- a/src/rtos/Makefile.am
+++ b/src/rtos/Makefile.am
@@ -1,34 +1,34 @@
-# ***************************************************************************
-# * 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, write to the *
-# * Free Software Foundation, Inc., *
-# * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
-# ***************************************************************************
+noinst_LTLIBRARIES += %D%/librtos.la
+%C%_librtos_la_SOURCES = \
+ %D%/rtos.c \
+ %D%/rtos_standard_stackings.c \
+ %D%/rtos_ecos_stackings.c \
+ %D%/rtos_chibios_stackings.c \
+ %D%/rtos_embkernel_stackings.c \
+ %D%/rtos_mqx_stackings.c \
+ %D%/rtos_ucos_iii_stackings.c \
+ %D%/FreeRTOS.c \
+ %D%/ThreadX.c \
+ %D%/eCos.c \
+ %D%/linux.c \
+ %D%/ChibiOS.c \
+ %D%/embKernel.c \
+ %D%/mqx.c \
+ %D%/uCOS-III.c \
+ %D%/riscv_debug.c \
+ %D%/rtos.h \
+ %D%/rtos_standard_stackings.h \
+ %D%/rtos_ecos_stackings.h \
+ %D%/linux_header.h \
+ %D%/rtos_chibios_stackings.h \
+ %D%/rtos_embkernel_stackings.h \
+ %D%/rtos_mqx_stackings.h \
+ %D%/rtos_ucos_iii_stackings.h \
+ %D%/riscv_debug.h
-include $(top_srcdir)/common.mk
+%C%_librtos_la_CFLAGS = $(AM_CFLAGS)
-METASOURCES = AUTO
-noinst_LTLIBRARIES = librtos.la
-noinst_HEADERS = rtos.h rtos_standard_stackings.h rtos_ecos_stackings.h linux_header.h rtos_chibios_stackings.h rtos_embkernel_stackings.h rtos_mqx_stackings.h
-librtos_la_SOURCES = rtos.c rtos_standard_stackings.c rtos_ecos_stackings.c rtos_chibios_stackings.c rtos_embkernel_stackings.c rtos_mqx_stackings.c FreeRTOS.c ThreadX.c eCos.c linux.c ChibiOS.c embKernel.c mqx.c
-
-librtos_la_CFLAGS =
if IS_MINGW
# FD_* macros are sloppy with their signs on MinGW32 platform
-librtos_la_CFLAGS += -Wno-sign-compare
+%C%_librtos_la_CFLAGS += -Wno-sign-compare
endif
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c
index 16df7a4b7..ab8a66e93 100644
--- a/src/rtos/ThreadX.c
+++ b/src/rtos/ThreadX.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -321,7 +319,6 @@ static int ThreadX_update_threads(struct rtos *rtos)
sizeof(struct thread_detail) * thread_list_size);
rtos->thread_details->threadid = 1;
rtos->thread_details->exists = true;
- rtos->thread_details->display_str = NULL;
rtos->thread_details->extra_info_str = NULL;
rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));
strcpy(rtos->thread_details->thread_name_str, tmp_str);
@@ -411,13 +408,11 @@ static int ThreadX_update_threads(struct rtos *rtos)
state_desc = "Unknown state";
rtos->thread_details[tasks_found].extra_info_str = malloc(strlen(
- state_desc)+1);
- strcpy(rtos->thread_details[tasks_found].extra_info_str, state_desc);
+ state_desc)+8);
+ sprintf(rtos->thread_details[tasks_found].extra_info_str, "State: %s", state_desc);
rtos->thread_details[tasks_found].exists = true;
- rtos->thread_details[tasks_found].display_str = NULL;
-
tasks_found++;
prev_thread_ptr = thread_ptr;
@@ -598,8 +593,6 @@ static int ThreadX_get_thread_detail(struct rtos *rtos,
detail->exists = true;
- detail->display_str = NULL;
-
return 0;
}
diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c
index 746172d6c..edc3d8b51 100644
--- a/src/rtos/eCos.c
+++ b/src/rtos/eCos.c
@@ -11,9 +11,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -174,7 +172,6 @@ static int eCos_update_threads(struct rtos *rtos)
sizeof(struct thread_detail) * thread_list_size);
rtos->thread_details->threadid = 1;
rtos->thread_details->exists = true;
- rtos->thread_details->display_str = NULL;
rtos->thread_details->extra_info_str = NULL;
rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));
strcpy(rtos->thread_details->thread_name_str, tmp_str);
@@ -264,13 +261,11 @@ static int eCos_update_threads(struct rtos *rtos)
state_desc = "Unknown state";
rtos->thread_details[tasks_found].extra_info_str = malloc(strlen(
- state_desc)+1);
- strcpy(rtos->thread_details[tasks_found].extra_info_str, state_desc);
+ state_desc)+8);
+ sprintf(rtos->thread_details[tasks_found].extra_info_str, "State: %s", state_desc);
rtos->thread_details[tasks_found].exists = true;
- rtos->thread_details[tasks_found].display_str = NULL;
-
tasks_found++;
prev_thread_ptr = thread_index;
diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c
index a8b07c398..e515383ac 100644
--- a/src/rtos/embKernel.c
+++ b/src/rtos/embKernel.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -145,7 +143,6 @@ static int embKernel_get_tasks_details(struct rtos *rtos, int64_t iterable, cons
return retval;
details->threadid = (threadid_t) task;
details->exists = true;
- details->display_str = NULL;
int64_t name_ptr = 0;
retval = target_read_buffer(rtos->target, task + param->thread_name_offset, param->pointer_width,
@@ -171,11 +168,11 @@ static int embKernel_get_tasks_details(struct rtos *rtos, int64_t iterable, cons
return retval;
details->extra_info_str = malloc(EMBKERNEL_MAX_THREAD_NAME_STR_SIZE);
if (task == rtos->current_thread) {
- snprintf(details->extra_info_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, "Pri=%u, Running",
+ snprintf(details->extra_info_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, "State: Running, Priority: %u",
(unsigned int) priority);
} else {
- snprintf(details->extra_info_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, "Pri=%u, %s", (unsigned int) priority,
- state_str);
+ snprintf(details->extra_info_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, "State: %s, Priority: %u",
+ state_str, (unsigned int) priority);
}
LOG_OUTPUT("Getting task details: iterable=0x%08X, task=0x%08X, name=%s\n", (unsigned int)iterable,
diff --git a/src/rtos/linux.c b/src/rtos/linux.c
index c28236d37..3efaab133 100644
--- a/src/rtos/linux.c
+++ b/src/rtos/linux.c
@@ -14,9 +14,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -107,11 +105,11 @@ static int linux_os_dummy_update(struct rtos *rtos)
return 0;
}
-static int linux_compute_virt2phys(struct target *target, uint32_t address)
+static int linux_compute_virt2phys(struct target *target, target_addr_t address)
{
struct linux_os *linux_os = (struct linux_os *)
target->rtos->rtos_specific_params;
- uint32_t pa = 0;
+ target_addr_t pa = 0;
int retval = target->type->virt2phys(target, address, &pa);
if (retval != ERROR_OK) {
LOG_ERROR("Cannot compute linux virt2phys translation");
@@ -1215,7 +1213,7 @@ int linux_thread_extra_info(struct target *target,
if (temp->threadid == threadid) {
char *pid = " PID: ";
char *pid_current = "*PID: ";
- char *name = "NAME: ";
+ char *name = "Name: ";
int str_size = strlen(pid) + strlen(name);
char *tmp_str = calloc(1, str_size + 50);
char *tmp_str_ptr = tmp_str;
@@ -1227,13 +1225,12 @@ int linux_thread_extra_info(struct target *target,
else
tmp_str_ptr += sprintf(tmp_str_ptr, "%s", pid);
- tmp_str_ptr +=
- sprintf(tmp_str_ptr, "%d", (int)temp->pid);
- tmp_str_ptr += sprintf(tmp_str_ptr, "%s", " | ");
+ tmp_str_ptr += sprintf(tmp_str_ptr, "%d, ", (int)temp->pid);
sprintf(tmp_str_ptr, "%s", name);
sprintf(tmp_str_ptr, "%s", temp->name);
char *hex_str = calloc(1, strlen(tmp_str) * 2 + 1);
- int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1);
+ size_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str,
+ strlen(tmp_str), strlen(tmp_str) * 2 + 1);
gdb_put_packet(connection, hex_str, pkt_len);
free(hex_str);
free(tmp_str);
diff --git a/src/rtos/linux_header.h b/src/rtos/linux_header.h
index faaf319b1..a2b408efd 100644
--- a/src/rtos/linux_header.h
+++ b/src/rtos/linux_header.h
@@ -1,3 +1,6 @@
+#ifndef OPENOCD_RTOS_LINUX_HEADER_H
+#define OPENOCD_RTOS_LINUX_HEADER_H
+
/* gdb script to update the header file
according to kernel version and build option
before executing function awareness
@@ -30,3 +33,5 @@ define awareness
#define CPU_CONT 0x1c
#define PREEMPT 0x4
#define MM_CTX 0x160
+
+#endif /* OPENOCD_RTOS_LINUX_HEADER_H */
diff --git a/src/rtos/mqx.c b/src/rtos/mqx.c
index 272658c8a..63a48c54b 100644
--- a/src/rtos/mqx.c
+++ b/src/rtos/mqx.c
@@ -13,8 +13,7 @@
* GNU 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. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -109,7 +108,7 @@ static int mqx_valid_address_check(
enum mqx_arch arch_type = ((struct mqx_params *)rtos->rtos_specific_params)->target_arch;
const char * targetname = ((struct mqx_params *)rtos->rtos_specific_params)->target_name;
- /* Cortex M address range */
+ /* Cortex-M address range */
if (arch_type == mqx_arch_cortexm) {
if (
/* code and sram area */
@@ -354,7 +353,7 @@ static int mqx_update_threads(
uint32_t task_name_addr = 0, task_id = 0, task_errno = 0;
uint32_t state_index = 0, state_max = 0;
uint32_t extra_info_length = 0;
- char *state_name = "unknown state";
+ char *state_name = "Unknown";
/* set current taskpool address */
if (ERROR_OK != mqx_get_member(
@@ -424,7 +423,6 @@ static int mqx_update_threads(
/* setup thread details struct */
rtos->thread_details[i].threadid = task_id;
rtos->thread_details[i].exists = true;
- rtos->thread_details[i].display_str = NULL;
/* set thread name */
rtos->thread_details[i].thread_name_str = malloc(strlen((void *)task_name) + 1);
if (NULL == rtos->thread_details[i].thread_name_str)
@@ -437,13 +435,13 @@ static int mqx_update_threads(
* calculate length as:
* state length + address length + errno length + formatter length
*/
- extra_info_length += strlen((void *)state_name) + 8 + 8 + 8;
+ extra_info_length += strlen((void *)state_name) + 7 + 13 + 8 + 15 + 8;
rtos->thread_details[i].extra_info_str = malloc(extra_info_length + 1);
if (NULL == rtos->thread_details[i].extra_info_str)
return ERROR_FAIL;
- snprintf(
- rtos->thread_details[i].extra_info_str, extra_info_length, "%s : 0x%"PRIx32 " : %" PRIu32,
- state_name, task_addr, task_errno
+ snprintf(rtos->thread_details[i].extra_info_str, extra_info_length,
+ "State: %s, Address: 0x%" PRIx32 ", Error Code: %" PRIu32,
+ state_name, task_addr, task_errno
);
/* set active thread */
if (active_td_addr == task_addr)
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index 528546eaa..804ecc9ef 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -36,6 +34,10 @@ extern struct rtos_type Linux_os;
extern struct rtos_type ChibiOS_rtos;
extern struct rtos_type embKernel_rtos;
extern struct rtos_type mqx_rtos;
+extern struct rtos_type uCOS_III_rtos;
+#if BUILD_RISCV == 1
+extern struct rtos_type riscv_rtos;
+#endif
static struct rtos_type *rtos_types[] = {
&ThreadX_rtos,
@@ -45,7 +47,11 @@ static struct rtos_type *rtos_types[] = {
&ChibiOS_rtos,
&embKernel_rtos,
&mqx_rtos,
- NULL
+ &uCOS_III_rtos,
+#if BUILD_RISCV == 1
+ &riscv_rtos,
+#endif
+ NULL
};
int rtos_thread_packet(struct connection *connection, const char *packet, int packet_size);
@@ -72,6 +78,9 @@ static int os_alloc(struct target *target, struct rtos_type *ostype)
/* RTOS drivers can override the packet handler in _create(). */
os->gdb_thread_packet = rtos_thread_packet;
+#if BUILD_RISCV == 1
+ os->gdb_v_packet = NULL;
+#endif
return JIM_OK;
}
@@ -104,8 +113,9 @@ static int os_alloc_create(struct target *target, struct rtos_type *ostype)
int rtos_create(Jim_GetOptInfo *goi, struct target *target)
{
int x;
- char *cp;
+ const char *cp;
struct Jim_Obj *res;
+ int e;
if (!goi->isconfigure && goi->argc != 0) {
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS");
@@ -114,7 +124,9 @@ int rtos_create(Jim_GetOptInfo *goi, struct target *target)
os_free(target);
- Jim_GetOpt_String(goi, &cp, NULL);
+ e = Jim_GetOpt_String(goi, &cp, NULL);
+ if (e != JIM_OK)
+ return e;
if (0 == strcmp(cp, "auto")) {
/* Auto detect tries to look up all symbols for each RTOS,
@@ -215,7 +227,7 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s
goto done;
/* Decode any symbol name in the packet*/
- int len = unhexify(cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1));
+ size_t len = unhexify((uint8_t *)cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1));
cur_sym[len] = 0;
if ((strcmp(packet, "qSymbol::") != 0) && /* GDB is not offering symbol lookup for the first time */
@@ -263,7 +275,9 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s
}
reply_len = snprintf(reply, sizeof(reply), "qSymbol:");
- reply_len += hexify(reply + reply_len, next_sym->symbol_name, 0, sizeof(reply) - reply_len);
+ reply_len += hexify(reply + reply_len,
+ (const uint8_t *)next_sym->symbol_name, strlen(next_sym->symbol_name),
+ sizeof(reply) - reply_len);
done:
gdb_put_packet(connection, reply, reply_len);
@@ -298,35 +312,28 @@ int rtos_thread_packet(struct connection *connection, char const *packet, int pa
struct thread_detail *detail = &target->rtos->thread_details[found];
int str_size = 0;
- if (detail->display_str != NULL)
- str_size += strlen(detail->display_str);
if (detail->thread_name_str != NULL)
str_size += strlen(detail->thread_name_str);
if (detail->extra_info_str != NULL)
str_size += strlen(detail->extra_info_str);
- char *tmp_str = calloc(str_size + 7, sizeof(char));
+ char *tmp_str = calloc(str_size + 9, sizeof(char));
char *tmp_str_ptr = tmp_str;
- if (detail->display_str != NULL)
- tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->display_str);
- if (detail->thread_name_str != NULL) {
- if (tmp_str_ptr != tmp_str)
- tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
- tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->thread_name_str);
- }
+ if (detail->thread_name_str != NULL)
+ tmp_str_ptr += sprintf(tmp_str_ptr, "Name: %s", detail->thread_name_str);
if (detail->extra_info_str != NULL) {
if (tmp_str_ptr != tmp_str)
- tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
- tmp_str_ptr +=
- sprintf(tmp_str_ptr, " : %s", detail->extra_info_str);
+ tmp_str_ptr += sprintf(tmp_str_ptr, ", ");
+ tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->extra_info_str);
}
assert(strlen(tmp_str) ==
(size_t) (tmp_str_ptr - tmp_str));
char *hex_str = malloc(strlen(tmp_str) * 2 + 1);
- int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1);
+ size_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str,
+ strlen(tmp_str), strlen(tmp_str) * 2 + 1);
gdb_put_packet(connection, hex_str, pkt_len);
free(hex_str);
@@ -407,9 +414,14 @@ int rtos_thread_packet(struct connection *connection, char const *packet, int pa
} else if (packet[0] == 'H') { /* Set current thread ( 'c' for step and continue, 'g' for
* all other operations ) */
if ((packet[1] == 'g') && (target->rtos != NULL)) {
- sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid);
- LOG_DEBUG("RTOS: GDB requested to set current thread to 0x%" PRIx64 "\r\n",
- target->rtos->current_threadid);
+ threadid_t threadid;
+ sscanf(packet, "Hg%16" SCNx64, &threadid);
+ LOG_DEBUG("RTOS: GDB requested to set current thread to 0x%" PRIx64, threadid);
+ /* threadid of 0 indicates target should choose */
+ if (threadid == 0)
+ target->rtos->current_threadid = target->rtos->current_thread;
+ else
+ target->rtos->current_threadid = threadid;
}
gdb_put_packet(connection, "OK", 2);
return ERROR_OK;
@@ -428,14 +440,25 @@ int rtos_get_gdb_reg_list(struct connection *connection)
(target->smp))) { /* in smp several current thread are possible */
char *hex_reg_list;
- LOG_DEBUG("RTOS: getting register list for thread 0x%" PRIx64
+#if BUILD_RISCV == 1
+ LOG_INFO("RTOS: getting register list for thread 0x%" PRIx64
", target->rtos->current_thread=0x%" PRIx64 "\r\n",
current_threadid,
target->rtos->current_thread);
+#else
+ LOG_DEBUG("RTOS: getting register list for thread 0x%" PRIx64
+ ", target->rtos->current_thread=0x%" PRIx64 "\r\n",
+ current_threadid,
+ target->rtos->current_thread);
+#endif
- target->rtos->type->get_thread_reg_list(target->rtos,
- current_threadid,
- &hex_reg_list);
+ int retval = target->rtos->type->get_thread_reg_list(target->rtos,
+ current_threadid,
+ &hex_reg_list);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("RTOS: failed to get register list");
+ return retval;
+ }
if (hex_reg_list != NULL) {
gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list));
@@ -547,12 +570,13 @@ void rtos_free_threadlist(struct rtos *rtos)
for (j = 0; j < rtos->thread_count; j++) {
struct thread_detail *current_thread = &rtos->thread_details[j];
- free(current_thread->display_str);
free(current_thread->thread_name_str);
free(current_thread->extra_info_str);
}
free(rtos->thread_details);
rtos->thread_details = NULL;
rtos->thread_count = 0;
+ rtos->current_threadid = -1;
+ rtos->current_thread = 0;
}
}
diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h
index d082fb7a7..6ff5f8575 100644
--- a/src/rtos/rtos.h
+++ b/src/rtos/rtos.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef RTOS_H
-#define RTOS_H
+#ifndef OPENOCD_RTOS_RTOS_H
+#define OPENOCD_RTOS_RTOS_H
#include "server/server.h"
#include
@@ -41,7 +39,6 @@ typedef struct symbol_table_elem_struct {
struct thread_detail {
threadid_t threadid;
bool exists;
- char *display_str;
char *thread_name_str;
char *extra_info_str;
};
@@ -57,6 +54,9 @@ struct rtos {
struct thread_detail *thread_details;
int thread_count;
int (*gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size);
+#if BUILD_RISCV == 1
+ int (*gdb_v_packet)(struct connection *connection, char const *packet, int packet_size);
+#endif
void *rtos_specific_params;
};
@@ -111,4 +111,4 @@ int rtos_smp_init(struct target *target);
/* function for handling symbol access */
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size);
-#endif /* RTOS_H */
+#endif /* OPENOCD_RTOS_RTOS_H */
diff --git a/src/rtos/rtos_chibios_stackings.c b/src/rtos/rtos_chibios_stackings.c
index e138b0684..3651c49a9 100644
--- a/src/rtos/rtos_chibios_stackings.c
+++ b/src/rtos/rtos_chibios_stackings.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/rtos_chibios_stackings.h b/src/rtos/rtos_chibios_stackings.h
index 8ba2a6ca3..130aaa18f 100644
--- a/src/rtos/rtos_chibios_stackings.h
+++ b/src/rtos/rtos_chibios_stackings.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef INCLUDED_RTOS_CHIBIOS_STACKINGS_H_
-#define INCLUDED_RTOS_CHIBIOS_STACKINGS_H_
+#ifndef OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H
+#define OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -30,4 +28,4 @@
extern const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking;
extern const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu;
-#endif /* ifndef INCLUDED_RTOS_CHIBIOS_STACKINGS_H_ */
+#endif /* OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H */
diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c
index cc924ae22..43d97a605 100644
--- a/src/rtos/rtos_ecos_stackings.c
+++ b/src/rtos/rtos_ecos_stackings.c
@@ -11,9 +11,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/rtos_ecos_stackings.h b/src/rtos/rtos_ecos_stackings.h
index 3bcd7cb05..951f7de50 100644
--- a/src/rtos/rtos_ecos_stackings.h
+++ b/src/rtos/rtos_ecos_stackings.h
@@ -11,13 +11,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef INCLUDED_RTOS_STANDARD_STACKINGS_H_
-#define INCLUDED_RTOS_STANDARD_STACKINGS_H_
+#ifndef OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H
+#define OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -27,4 +25,4 @@
extern const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking;
-#endif /* ifndef INCLUDED_RTOS_STANDARD_STACKINGS_H_ */
+#endif /* OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H */
diff --git a/src/rtos/rtos_embkernel_stackings.c b/src/rtos/rtos_embkernel_stackings.c
index 8171957fd..2a3062955 100644
--- a/src/rtos/rtos_embkernel_stackings.c
+++ b/src/rtos/rtos_embkernel_stackings.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/rtos_embkernel_stackings.h b/src/rtos/rtos_embkernel_stackings.h
index 5bbcb4615..89a0c2f12 100644
--- a/src/rtos/rtos_embkernel_stackings.h
+++ b/src/rtos/rtos_embkernel_stackings.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef INCLUDED_RTOS_EMBKERNEL_STACKINGS_H_
-#define INCLUDED_RTOS_EMBKERNEL_STACKINGS_H_
+#ifndef OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H
+#define OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -29,4 +27,4 @@
extern const struct rtos_register_stacking rtos_embkernel_Cortex_M_stacking;
-#endif /* ifndef INCLUDED_RTOS_EMBKERNEL_STACKINGS_H_ */
+#endif /* OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H */
diff --git a/src/rtos/rtos_mqx_stackings.c b/src/rtos/rtos_mqx_stackings.c
index fac18b606..5db2f8ec3 100644
--- a/src/rtos/rtos_mqx_stackings.c
+++ b/src/rtos/rtos_mqx_stackings.c
@@ -13,8 +13,7 @@
* GNU 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. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/rtos/rtos_mqx_stackings.h b/src/rtos/rtos_mqx_stackings.h
index 9536c400f..6ebd28789 100644
--- a/src/rtos/rtos_mqx_stackings.h
+++ b/src/rtos/rtos_mqx_stackings.h
@@ -13,12 +13,11 @@
* GNU 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. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef INCLUDED_RTOS_MQX_STACKINGS_H_
-#define INCLUDED_RTOS_MQX_STACKINGS_H_
+#ifndef OPENOCD_RTOS_RTOS_MQX_STACKINGS_H
+#define OPENOCD_RTOS_RTOS_MQX_STACKINGS_H
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -28,5 +27,4 @@
extern const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking;
-#endif /* ifndef INCLUDED_RTOS_MQX_STACKINGS_H_ */
-
+#endif /* OPENOCD_RTOS_RTOS_MQX_STACKINGS_H */
diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c
index 1a58870fc..0176c01ab 100644
--- a/src/rtos/rtos_standard_stackings.c
+++ b/src/rtos/rtos_standard_stackings.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -45,6 +43,47 @@ static const struct stack_register_offset rtos_standard_Cortex_M3_stack_offsets[
{ 0x3c, 32 }, /* xPSR */
};
+static const struct stack_register_offset rtos_standard_Cortex_M4F_stack_offsets[] = {
+ { 0x24, 32 }, /* r0 */
+ { 0x28, 32 }, /* r1 */
+ { 0x2c, 32 }, /* r2 */
+ { 0x30, 32 }, /* r3 */
+ { 0x00, 32 }, /* r4 */
+ { 0x04, 32 }, /* r5 */
+ { 0x08, 32 }, /* r6 */
+ { 0x0c, 32 }, /* r7 */
+ { 0x10, 32 }, /* r8 */
+ { 0x14, 32 }, /* r9 */
+ { 0x18, 32 }, /* r10 */
+ { 0x1c, 32 }, /* r11 */
+ { 0x34, 32 }, /* r12 */
+ { -2, 32 }, /* sp */
+ { 0x38, 32 }, /* lr */
+ { 0x3c, 32 }, /* pc */
+ { 0x40, 32 }, /* xPSR */
+};
+
+static const struct stack_register_offset rtos_standard_Cortex_M4F_FPU_stack_offsets[] = {
+ { 0x64, 32 }, /* r0 */
+ { 0x68, 32 }, /* r1 */
+ { 0x6c, 32 }, /* r2 */
+ { 0x70, 32 }, /* r3 */
+ { 0x00, 32 }, /* r4 */
+ { 0x04, 32 }, /* r5 */
+ { 0x08, 32 }, /* r6 */
+ { 0x0c, 32 }, /* r7 */
+ { 0x10, 32 }, /* r8 */
+ { 0x14, 32 }, /* r9 */
+ { 0x18, 32 }, /* r10 */
+ { 0x1c, 32 }, /* r11 */
+ { 0x74, 32 }, /* r12 */
+ { -2, 32 }, /* sp */
+ { 0x78, 32 }, /* lr */
+ { 0x7c, 32 }, /* pc */
+ { 0x80, 32 }, /* xPSR */
+};
+
+
static const struct stack_register_offset rtos_standard_Cortex_R4_stack_offsets[] = {
{ 0x08, 32 }, /* r0 (a1) */
{ 0x0c, 32 }, /* r1 (a2) */
@@ -141,7 +180,7 @@ int64_t rtos_generic_stack_align8(struct target *target,
stacking, stack_ptr, 8);
}
-/* The Cortex M3 will indicate that an alignment adjustment
+/* The Cortex-M3 will indicate that an alignment adjustment
* has been done on the stack by setting bit 9 of the stacked xPSR
* register. In this case, we can just add an extra 4 bytes to get
* to the program stack. Note that some places in the ARM documentation
@@ -198,6 +237,22 @@ const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking = {
rtos_standard_Cortex_M3_stack_offsets /* register_offsets */
};
+const struct rtos_register_stacking rtos_standard_Cortex_M4F_stacking = {
+ 0x44, /* stack_registers_size 4 more for LR*/
+ -1, /* stack_growth_direction */
+ ARMV7M_NUM_CORE_REGS, /* num_output_registers */
+ rtos_standard_Cortex_M3_stack_align, /* stack_alignment */
+ rtos_standard_Cortex_M4F_stack_offsets /* register_offsets */
+};
+
+const struct rtos_register_stacking rtos_standard_Cortex_M4F_FPU_stacking = {
+ 0xcc, /* stack_registers_size 4 more for LR + 48 more for FPU S0-S15 register*/
+ -1, /* stack_growth_direction */
+ ARMV7M_NUM_CORE_REGS, /* num_output_registers */
+ rtos_standard_Cortex_M3_stack_align, /* stack_alignment */
+ rtos_standard_Cortex_M4F_FPU_stack_offsets /* register_offsets */
+};
+
const struct rtos_register_stacking rtos_standard_Cortex_R4_stacking = {
0x48, /* stack_registers_size */
-1, /* stack_growth_direction */
diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h
index f931bb9f2..6971efd1e 100644
--- a/src/rtos/rtos_standard_stackings.h
+++ b/src/rtos/rtos_standard_stackings.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef INCLUDED_RTOS_STANDARD_STACKINGS_H_
-#define INCLUDED_RTOS_STANDARD_STACKINGS_H_
+#ifndef OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H
+#define OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -28,6 +26,8 @@
#include "rtos.h"
extern const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking;
+extern const struct rtos_register_stacking rtos_standard_Cortex_M4F_stacking;
+extern const struct rtos_register_stacking rtos_standard_Cortex_M4F_FPU_stacking;
extern const struct rtos_register_stacking rtos_standard_Cortex_R4_stacking;
extern const struct rtos_register_stacking rtos_standard_NDS32_N1068_stacking;
int64_t rtos_generic_stack_align8(struct target *target,
@@ -37,4 +37,4 @@ int64_t rtos_Cortex_M_stack_align(struct target *target,
const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
int64_t stack_ptr, size_t xpsr_offset);
-#endif /* ifndef INCLUDED_RTOS_STANDARD_STACKINGS_H_ */
+#endif /* OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H */
diff --git a/src/server/Makefile.am b/src/server/Makefile.am
index 04d3035f4..804efac16 100644
--- a/src/server/Makefile.am
+++ b/src/server/Makefile.am
@@ -1,23 +1,19 @@
-include $(top_srcdir)/common.mk
+noinst_LTLIBRARIES += %D%/libserver.la
+%C%_libserver_la_SOURCES = \
+ %D%/server.c \
+ %D%/telnet_server.c \
+ %D%/gdb_server.c \
+ %D%/server.h \
+ %D%/telnet_server.h \
+ %D%/gdb_server.h \
+ %D%/server_stubs.c \
+ %D%/tcl_server.c \
+ %D%/tcl_server.h
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libserver.la
-noinst_HEADERS = server.h telnet_server.h gdb_server.h
-libserver_la_SOURCES = server.c telnet_server.c gdb_server.c
-
-libserver_la_SOURCES += server_stubs.c
-
-libserver_la_CFLAGS =
+%C%_libserver_la_CFLAGS = $(AM_CFLAGS)
if IS_MINGW
# FD_* macros are sloppy with their signs on MinGW32 platform
-libserver_la_CFLAGS += -Wno-sign-compare
+%C%_libserver_la_CFLAGS += -Wno-sign-compare
endif
-# tcl server addons
-noinst_HEADERS += tcl_server.h
-libserver_la_SOURCES += tcl_server.c
-
-EXTRA_DIST = \
- startup.tcl
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+STARTUP_TCL_SRCS += %D%/startup.tcl
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 780359ea4..f03bdb1eb 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -31,9 +31,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -92,6 +90,8 @@ struct gdb_connection {
bool attached;
/* temporarily used for target description support */
struct target_desc_format target_desc;
+ /* temporarily used for thread list support */
+ char *thread_list;
};
#if 0
@@ -697,7 +697,8 @@ static int gdb_output_con(struct connection *connection, const char *line)
return ERROR_GDB_BUFFER_TOO_SMALL;
hex_buffer[0] = 'O';
- int pkt_len = hexify(hex_buffer + 1, line, bin_size, bin_size * 2 + 1);
+ size_t pkt_len = hexify(hex_buffer + 1, (const uint8_t *)line, bin_size,
+ bin_size * 2 + 1);
int retval = gdb_put_packet(connection, hex_buffer, pkt_len + 1);
free(hex_buffer);
@@ -734,22 +735,22 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio
stop_reason[0] = '\0';
if (target->debug_reason == DBG_REASON_WATCHPOINT) {
enum watchpoint_rw hit_wp_type;
- uint32_t hit_wp_address;
+ target_addr_t hit_wp_address;
if (watchpoint_hit(target, &hit_wp_type, &hit_wp_address) == ERROR_OK) {
switch (hit_wp_type) {
case WPT_WRITE:
snprintf(stop_reason, sizeof(stop_reason),
- "watch:%08" PRIx32 ";", hit_wp_address);
+ "watch:%08" TARGET_PRIxADDR ";", hit_wp_address);
break;
case WPT_READ:
snprintf(stop_reason, sizeof(stop_reason),
- "rwatch:%08" PRIx32 ";", hit_wp_address);
+ "rwatch:%08" TARGET_PRIxADDR ";", hit_wp_address);
break;
case WPT_ACCESS:
snprintf(stop_reason, sizeof(stop_reason),
- "awatch:%08" PRIx32 ";", hit_wp_address);
+ "awatch:%08" TARGET_PRIxADDR ";", hit_wp_address);
break;
default:
break;
@@ -936,6 +937,7 @@ static int gdb_new_connection(struct connection *connection)
gdb_connection->attached = true;
gdb_connection->target_desc.tdesc = NULL;
gdb_connection->target_desc.tdesc_length = 0;
+ gdb_connection->thread_list = NULL;
/* send ACK to GDB for debug request */
gdb_write(connection, "+", 1);
@@ -1165,8 +1167,20 @@ static int gdb_get_registers_packet(struct connection *connection,
reg_packet_p = reg_packet;
for (i = 0; i < reg_list_size; i++) {
+#if BUILD_RISCV == 1
+ if (!reg_list[i]->valid) {
+ retval = reg_list[i]->type->get(reg_list[i]);
+ if (retval != ERROR_OK) {
+ LOG_DEBUG("Couldn't get register %s.", reg_list[i]->name);
+ free(reg_packet);
+ free(reg_list);
+ return gdb_error(connection, retval);
+ }
+ }
+#else
if (!reg_list[i]->valid)
reg_list[i]->type->get(reg_list[i]);
+#endif
gdb_str_to_target(target, reg_packet_p, reg_list[i]);
reg_packet_p += DIV_ROUND_UP(reg_list[i]->size, 8) * 2;
}
@@ -1227,7 +1241,17 @@ static int gdb_set_registers_packet(struct connection *connection,
bin_buf = malloc(DIV_ROUND_UP(reg_list[i]->size, 8));
gdb_target_to_reg(target, packet_p, chars, bin_buf);
+#if BUILD_RISCV == 1
+ retval = reg_list[i]->type->set(reg_list[i], bin_buf);
+ if (retval != ERROR_OK) {
+ LOG_DEBUG("Couldn't set register %s.", reg_list[i]->name);
+ free(reg_list);
+ free(bin_buf);
+ return gdb_error(connection, retval);
+ }
+#else
reg_list[i]->type->set(reg_list[i], bin_buf);
+#endif
/* advance packet pointer */
packet_p += chars;
@@ -1267,8 +1291,19 @@ static int gdb_get_register_packet(struct connection *connection,
return ERROR_SERVER_REMOTE_CLOSED;
}
+#if BUILD_RISCV == 1
+ if (!reg_list[reg_num]->valid) {
+ retval = reg_list[reg_num]->type->get(reg_list[reg_num]);
+ if (retval != ERROR_OK) {
+ LOG_DEBUG("Couldn't get register %s.", reg_list[reg_num]->name);
+ free (reg_list);
+ return gdb_error(connection, retval);
+ }
+ }
+#else
if (!reg_list[reg_num]->valid)
reg_list[reg_num]->type->get(reg_list[reg_num]);
+#endif
reg_packet = malloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2 + 1); /* plus one for string termination null */
@@ -1322,7 +1357,17 @@ static int gdb_set_register_packet(struct connection *connection,
gdb_target_to_reg(target, separator + 1, chars, bin_buf);
+#if BUILD_RISCV == 1
+ retval = reg_list[reg_num]->type->set(reg_list[reg_num], bin_buf);
+ if (retval != ERROR_OK){
+ LOG_DEBUG("Couldn't set register %s.", reg_list[reg_num]->name);
+ free(bin_buf);
+ free(reg_list);
+ return gdb_error(connection, retval);
+ }
+#else
reg_list[reg_num]->type->set(reg_list[reg_num], bin_buf);
+#endif
gdb_put_packet(connection, "OK", 2);
@@ -1353,7 +1398,7 @@ static int gdb_read_memory_packet(struct connection *connection,
{
struct target *target = get_target_from_connection(connection);
char *separator;
- uint32_t addr = 0;
+ uint64_t addr = 0;
uint32_t len = 0;
uint8_t *buffer;
@@ -1364,7 +1409,7 @@ static int gdb_read_memory_packet(struct connection *connection,
/* skip command character */
packet++;
- addr = strtoul(packet, &separator, 16);
+ addr = strtoull(packet, &separator, 16);
if (*separator != ',') {
LOG_ERROR("incomplete read memory packet received, dropping connection");
@@ -1381,7 +1426,7 @@ static int gdb_read_memory_packet(struct connection *connection,
buffer = malloc(len);
- LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
+ LOG_DEBUG("addr: 0x%16.16" PRIx64 ", len: 0x%8.8" PRIx32 "", addr, len);
retval = target_read_buffer(target, addr, len, buffer);
@@ -1406,7 +1451,7 @@ static int gdb_read_memory_packet(struct connection *connection,
if (retval == ERROR_OK) {
hex_buffer = malloc(len * 2 + 1);
- int pkt_len = hexify(hex_buffer, (char *)buffer, len, len * 2 + 1);
+ size_t pkt_len = hexify(hex_buffer, buffer, len, len * 2 + 1);
gdb_put_packet(connection, hex_buffer, pkt_len);
@@ -1424,7 +1469,7 @@ static int gdb_write_memory_packet(struct connection *connection,
{
struct target *target = get_target_from_connection(connection);
char *separator;
- uint32_t addr = 0;
+ uint64_t addr = 0;
uint32_t len = 0;
uint8_t *buffer;
@@ -1433,7 +1478,7 @@ static int gdb_write_memory_packet(struct connection *connection,
/* skip command character */
packet++;
- addr = strtoul(packet, &separator, 16);
+ addr = strtoull(packet, &separator, 16);
if (*separator != ',') {
LOG_ERROR("incomplete write memory packet received, dropping connection");
@@ -1449,9 +1494,9 @@ static int gdb_write_memory_packet(struct connection *connection,
buffer = malloc(len);
- LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
+ LOG_DEBUG("addr: 0x%" PRIx64 ", len: 0x%8.8" PRIx32 "", addr, len);
- if (unhexify((char *)buffer, separator, len) != (int)len)
+ if (unhexify(buffer, separator, len) != len)
LOG_ERROR("unable to decode memory packet");
retval = target_write_buffer(target, addr, len, buffer);
@@ -1471,15 +1516,19 @@ static int gdb_write_memory_binary_packet(struct connection *connection,
{
struct target *target = get_target_from_connection(connection);
char *separator;
- uint32_t addr = 0;
+ uint64_t addr = 0;
uint32_t len = 0;
int retval = ERROR_OK;
+ /* Packets larger than fast_limit bytes will be acknowledged instantly on
+ * the assumption that we're in a download and it's important to go as fast
+ * as possible. */
+ uint32_t fast_limit = 8;
/* skip command character */
packet++;
- addr = strtoul(packet, &separator, 16);
+ addr = strtoull(packet, &separator, 16);
if (*separator != ',') {
LOG_ERROR("incomplete write memory binary packet received, dropping connection");
@@ -1495,31 +1544,44 @@ static int gdb_write_memory_binary_packet(struct connection *connection,
struct gdb_connection *gdb_connection = connection->priv;
- if (gdb_connection->mem_write_error) {
+ if (gdb_connection->mem_write_error)
retval = ERROR_FAIL;
- /* now that we have reported the memory write error, we can clear the condition */
- gdb_connection->mem_write_error = false;
- }
- /* By replying the packet *immediately* GDB will send us a new packet
- * while we write the last one to the target.
- */
- if (retval == ERROR_OK)
- gdb_put_packet(connection, "OK", 2);
- else {
+ if (retval == ERROR_OK) {
+ if (len >= fast_limit) {
+ /* By replying the packet *immediately* GDB will send us a new packet
+ * while we write the last one to the target.
+ * We only do this for larger writes, so that users who do something like:
+ * p *((int*)0xdeadbeef)=8675309
+ * will get immediate feedback that that write failed.
+ */
+ gdb_put_packet(connection, "OK", 2);
+ }
+ } else {
retval = gdb_error(connection, retval);
+ /* now that we have reported the memory write error, we can clear the condition */
+ gdb_connection->mem_write_error = false;
if (retval != ERROR_OK)
return retval;
}
if (len) {
- LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
+ LOG_DEBUG("addr: 0x%" PRIx64 ", len: 0x%8.8" PRIx32 "", addr, len);
retval = target_write_buffer(target, addr, len, (uint8_t *)separator);
if (retval != ERROR_OK)
gdb_connection->mem_write_error = true;
}
+ if (len < fast_limit) {
+ if (retval != ERROR_OK) {
+ gdb_error(connection, retval);
+ gdb_connection->mem_write_error = false;
+ } else {
+ gdb_put_packet(connection, "OK", 2);
+ }
+ }
+
return ERROR_OK;
}
@@ -1528,13 +1590,13 @@ static int gdb_step_continue_packet(struct connection *connection,
{
struct target *target = get_target_from_connection(connection);
int current = 0;
- uint32_t address = 0x0;
+ uint64_t address = 0x0;
int retval = ERROR_OK;
LOG_DEBUG("-");
if (packet_size > 1)
- address = strtoul(packet + 1, NULL, 16);
+ address = strtoull(packet + 1, NULL, 16);
else
current = 1;
@@ -1558,7 +1620,7 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
int type;
enum breakpoint_type bp_type = BKPT_SOFT /* dummy init to avoid warning */;
enum watchpoint_rw wp_type = WPT_READ /* dummy init to avoid warning */;
- uint32_t address;
+ uint64_t address;
uint32_t size;
char *separator;
int retval;
@@ -1590,7 +1652,7 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
return ERROR_SERVER_REMOTE_CLOSED;
}
- address = strtoul(separator + 1, &separator, 16);
+ address = strtoull(separator + 1, &separator, 16);
if (*separator != ',') {
LOG_ERROR("incomplete breakpoint/watchpoint packet received, dropping connection");
@@ -2268,6 +2330,95 @@ static int gdb_target_description_supported(struct target *target, int *supporte
return retval;
}
+static int gdb_generate_thread_list(struct target *target, char **thread_list_out)
+{
+ struct rtos *rtos = target->rtos;
+ int retval = ERROR_OK;
+ char *thread_list = NULL;
+ int pos = 0;
+ int size = 0;
+
+ xml_printf(&retval, &thread_list, &pos, &size,
+ "\n"
+ "\n");
+
+ if (rtos != NULL) {
+ for (int i = 0; i < rtos->thread_count; i++) {
+ struct thread_detail *thread_detail = &rtos->thread_details[i];
+
+ if (!thread_detail->exists)
+ continue;
+
+ xml_printf(&retval, &thread_list, &pos, &size,
+ "", thread_detail->threadid);
+
+ if (thread_detail->thread_name_str != NULL)
+ xml_printf(&retval, &thread_list, &pos, &size,
+ "Name: %s", thread_detail->thread_name_str);
+
+ if (thread_detail->extra_info_str != NULL) {
+ if (thread_detail->thread_name_str != NULL)
+ xml_printf(&retval, &thread_list, &pos, &size,
+ ", ");
+ xml_printf(&retval, &thread_list, &pos, &size,
+ thread_detail->extra_info_str);
+ }
+
+ xml_printf(&retval, &thread_list, &pos, &size,
+ "\n");
+ }
+ }
+
+ xml_printf(&retval, &thread_list, &pos, &size,
+ "\n");
+
+ if (retval == ERROR_OK)
+ *thread_list_out = thread_list;
+ else
+ free(thread_list);
+
+ return retval;
+}
+
+static int gdb_get_thread_list_chunk(struct target *target, char **thread_list,
+ char **chunk, int32_t offset, uint32_t length)
+{
+ if (*thread_list == NULL) {
+ int retval = gdb_generate_thread_list(target, thread_list);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Unable to Generate Thread List");
+ return ERROR_FAIL;
+ }
+ }
+
+ size_t thread_list_length = strlen(*thread_list);
+ char transfer_type;
+
+ length = MIN(length, thread_list_length - offset);
+ if (length < (thread_list_length - offset))
+ transfer_type = 'm';
+ else
+ transfer_type = 'l';
+
+ *chunk = malloc(length + 2);
+ if (*chunk == NULL) {
+ LOG_ERROR("Unable to allocate memory");
+ return ERROR_FAIL;
+ }
+
+ (*chunk)[0] = transfer_type;
+ strncpy((*chunk) + 1, (*thread_list) + offset, length);
+ (*chunk)[1 + length] = '\0';
+
+ /* After gdb-server sends out last chunk, invalidate thread list. */
+ if (transfer_type == 'l') {
+ free(*thread_list);
+ *thread_list = NULL;
+ }
+
+ return ERROR_OK;
+}
+
static int gdb_query_packet(struct connection *connection,
char const *packet, int packet_size)
{
@@ -2279,7 +2430,7 @@ static int gdb_query_packet(struct connection *connection,
if (packet_size > 6) {
char *cmd;
cmd = malloc((packet_size - 6) / 2 + 1);
- int len = unhexify(cmd, packet + 6, (packet_size - 6) / 2);
+ size_t len = unhexify((uint8_t *)cmd, packet + 6, (packet_size - 6) / 2);
cmd[len] = 0;
/* We want to print all debug output to GDB connection */
@@ -2302,7 +2453,7 @@ static int gdb_query_packet(struct connection *connection,
char gdb_reply[10];
char *separator;
uint32_t checksum;
- uint32_t addr = 0;
+ target_addr_t addr = 0;
uint32_t len = 0;
/* skip command character */
@@ -2357,7 +2508,7 @@ static int gdb_query_packet(struct connection *connection,
&buffer,
&pos,
&size,
- "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;QStartNoAckMode+",
+ "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+",
(GDB_BUFFER_SIZE - 1),
((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-',
(gdb_target_desc_supported == 1) ? '+' : '-');
@@ -2403,6 +2554,37 @@ static int gdb_query_packet(struct connection *connection,
gdb_put_packet(connection, xml, strlen(xml));
+ free(xml);
+ return ERROR_OK;
+ } else if (strncmp(packet, "qXfer:threads:read:", 19) == 0) {
+ char *xml = NULL;
+ int retval = ERROR_OK;
+
+ int offset;
+ unsigned int length;
+
+ /* skip command character */
+ packet += 19;
+
+ if (decode_xfer_read(packet, NULL, &offset, &length) < 0) {
+ gdb_send_error(connection, 01);
+ return ERROR_OK;
+ }
+
+ /* Target should prepare correct thread list for annex.
+ * The first character of returned xml is 'm' or 'l'. 'm' for
+ * there are *more* chunks to transfer. 'l' for it is the *last*
+ * chunk of target description.
+ */
+ retval = gdb_get_thread_list_chunk(target, &gdb_connection->thread_list,
+ &xml, offset, length);
+ if (retval != ERROR_OK) {
+ gdb_error(connection, retval);
+ return retval;
+ }
+
+ gdb_put_packet(connection, xml, strlen(xml));
+
free(xml);
return ERROR_OK;
} else if (strncmp(packet, "QStartNoAckMode", 15) == 0) {
@@ -2422,6 +2604,15 @@ static int gdb_v_packet(struct connection *connection,
struct gdb_service *gdb_service = connection->service->priv;
int result;
+#if BUILD_RISCV == 1
+ struct target *target = get_target_from_connection(connection);
+ if (target->rtos != NULL && target->rtos->gdb_v_packet != NULL) {
+ int out = target->rtos->gdb_v_packet(connection, packet, packet_size);
+ if (out != GDB_THREAD_PACKET_NOT_CONSUMED)
+ return out;
+ }
+#endif
+
/* if flash programming disabled - send a empty reply */
if (gdb_flash_program == 0) {
@@ -2620,7 +2811,11 @@ static void gdb_log_callback(void *priv, const char *file, unsigned line,
gdb_output_con(connection, string);
}
+#if BUILD_RISCV == 1
+void gdb_sig_halted(struct connection *connection)
+#else
static void gdb_sig_halted(struct connection *connection)
+#endif
{
char sig_reply[4];
snprintf(sig_reply, 4, "T%2.2x", 2);
@@ -2923,6 +3118,11 @@ static int gdb_target_start(struct target *target, const char *port)
static int gdb_target_add_one(struct target *target)
{
+ if (strcmp(gdb_port, "disabled") == 0) {
+ LOG_INFO("gdb port disabled");
+ return ERROR_OK;
+ }
+
/* one gdb instance per smp list */
if ((target->smp) && (target->gdb_service))
return ERROR_OK;
@@ -2937,7 +3137,13 @@ static int gdb_target_add_one(struct target *target)
if (!*end) {
if (parse_long(gdb_port_next, &portnumber) == ERROR_OK) {
free(gdb_port_next);
- gdb_port_next = alloc_printf("%d", portnumber+1);
+ if (portnumber) {
+ gdb_port_next = alloc_printf("%d", portnumber+1);
+ } else {
+ /* Don't increment if gdb_port is 0, since we're just
+ * trying to allocate an unused port. */
+ gdb_port_next = alloc_printf("0");
+ }
}
}
}
@@ -2946,6 +3152,11 @@ static int gdb_target_add_one(struct target *target)
int gdb_target_add_all(struct target *target)
{
+ if (strcmp(gdb_port, "disabled") == 0) {
+ LOG_INFO("gdb server disabled");
+ return ERROR_OK;
+ }
+
if (NULL == target) {
LOG_WARNING("gdb services need one or more targets defined");
return ERROR_OK;
@@ -3063,7 +3274,7 @@ COMMAND_HANDLER(handle_gdb_save_tdesc_command)
tdesc_length = strlen(tdesc);
- struct fileio fileio;
+ struct fileio *fileio;
size_t size_written;
char *tdesc_filename = alloc_printf("%s.xml", target_type_name(target));
@@ -3079,9 +3290,9 @@ COMMAND_HANDLER(handle_gdb_save_tdesc_command)
goto out;
}
- retval = fileio_write(&fileio, tdesc_length, tdesc, &size_written);
+ retval = fileio_write(fileio, tdesc_length, tdesc, &size_written);
- fileio_close(&fileio);
+ fileio_close(fileio);
if (retval != ERROR_OK)
LOG_ERROR("Error while writing the tdesc file");
@@ -3111,7 +3322,7 @@ static const struct command_registration gdb_command_handlers[] = {
"server listens for the next port number after the "
"base port number specified. "
"No arguments reports GDB port. \"pipe\" means listen to stdin "
- "output to stdout, an integer is base port number, \"disable\" disables "
+ "output to stdout, an integer is base port number, \"disabled\" disables "
"port. Any other string is are interpreted as named pipe to listen to. "
"Output pipe is the same name as input pipe, but with 'o' appended.",
.usage = "[port_num]",
@@ -3167,3 +3378,11 @@ int gdb_register_commands(struct command_context *cmd_ctx)
gdb_port_next = strdup("3333");
return register_commands(cmd_ctx, NULL, gdb_command_handlers);
}
+
+#if BUILD_RISCV == 1
+void gdb_set_frontend_state_running(struct connection *connection)
+{
+ struct gdb_connection *gdb_con = connection->priv;
+ gdb_con->frontend_state = TARGET_RUNNING;
+}
+#endif
diff --git a/src/server/gdb_server.h b/src/server/gdb_server.h
index 8092d7b6d..460b12491 100644
--- a/src/server/gdb_server.h
+++ b/src/server/gdb_server.h
@@ -22,13 +22,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef GDB_SERVER_H
-#define GDB_SERVER_H
+#ifndef OPENOCD_SERVER_GDB_SERVER_H
+#define OPENOCD_SERVER_GDB_SERVER_H
struct image;
struct reg;
@@ -47,7 +45,12 @@ static inline struct target *get_target_from_connection(struct connection *conne
return gdb_service->target;
}
+#if BUILD_RISCV == 1
+void gdb_set_frontend_state_running(struct connection *connection);
+void gdb_sig_halted(struct connection *connection);
+#endif
+
#define ERROR_GDB_BUFFER_TOO_SMALL (-800)
#define ERROR_GDB_TIMEOUT (-801)
-#endif /* GDB_SERVER_H */
+#endif /* OPENOCD_SERVER_GDB_SERVER_H */
diff --git a/src/server/server.c b/src/server/server.c
index 24747f938..dae7df3c5 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -38,6 +36,10 @@
#include
+#ifdef HAVE_NETDB_H
+#include
+#endif
+
#ifndef _WIN32
#include
#endif
@@ -54,6 +56,9 @@ static int last_signal;
/* set the polling period to 100ms */
static int polling_period = 100;
+/* address by name on which to listen for incoming TCP/IP connections */
+static char *bindto_name;
+
static int add_connection(struct service *service, struct command_context *cmd_ctx)
{
socklen_t address_size;
@@ -127,7 +132,9 @@ static int add_connection(struct service *service, struct command_context *cmd_c
free(out_file);
if (c->fd_out == -1) {
LOG_ERROR("could not open %s", service->port);
- exit(1);
+ command_done(c->cmd_ctx);
+ free(c);
+ return ERROR_FAIL;
}
LOG_INFO("accepting '%s' connection from pipe %s", service->name, service->port);
@@ -186,7 +193,13 @@ static int remove_connection(struct service *service, struct connection *connect
return ERROR_OK;
}
-/* FIX! make service return error instead of invoking exit() */
+static void free_service(struct service *c)
+{
+ free(c->name);
+ free(c->port);
+ free(c);
+}
+
int add_service(char *name,
const char *port,
int max_connections,
@@ -196,6 +209,7 @@ int add_service(char *name,
void *priv)
{
struct service *c, **p;
+ struct hostent *hp;
int so_reuseaddr_option = 1;
c = malloc(sizeof(struct service));
@@ -229,7 +243,8 @@ int add_service(char *name,
c->fd = socket(AF_INET, SOCK_STREAM, 0);
if (c->fd == -1) {
LOG_ERROR("error creating socket: %s", strerror(errno));
- exit(-1);
+ free_service(c);
+ return ERROR_FAIL;
}
setsockopt(c->fd,
@@ -242,12 +257,31 @@ int add_service(char *name,
memset(&c->sin, 0, sizeof(c->sin));
c->sin.sin_family = AF_INET;
- c->sin.sin_addr.s_addr = INADDR_ANY;
+
+ if (bindto_name == NULL)
+ c->sin.sin_addr.s_addr = INADDR_ANY;
+ else {
+ hp = gethostbyname(bindto_name);
+ if (hp == NULL) {
+ LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
+ close_socket(c->fd);
+ free_service(c);
+ return ERROR_FAIL;
+ }
+ memcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);
+ }
c->sin.sin_port = htons(c->portnumber);
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
- LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
- exit(-1);
+#if BUILD_RISCV == 1
+ LOG_ERROR("couldn't bind %s to socket on port %d: %s", name,
+ c->portnumber, strerror(errno));
+#else
+ LOG_ERROR("couldn't bind %s to socket: %s", name, strerror(errno));
+#endif
+ close_socket(c->fd);
+ free_service(c);
+ return ERROR_FAIL;
}
#ifndef _WIN32
@@ -265,8 +299,18 @@ int add_service(char *name,
if (listen(c->fd, 1) == -1) {
LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
- exit(-1);
+ close_socket(c->fd);
+ free_service(c);
+ return ERROR_FAIL;
}
+
+#if BUILD_RISCV == 1
+ struct sockaddr_in addr_in;
+ socklen_t addr_in_size = sizeof(addr_in);
+ getsockname(c->fd, (struct sockaddr*)&addr_in, &addr_in_size);
+ LOG_INFO("Listening on port %d for %s connections",
+ ntohs(addr_in.sin_port), name);
+#endif
} else if (c->type == CONNECTION_STDINOUT) {
c->fd = fileno(stdin);
@@ -286,13 +330,15 @@ int add_service(char *name,
/* we currenty do not support named pipes under win32
* so exit openocd for now */
LOG_ERROR("Named pipes currently not supported under this os");
- exit(1);
+ free_service(c);
+ return ERROR_FAIL;
#else
/* Pipe we're reading from */
c->fd = open(c->port, O_RDONLY | O_NONBLOCK);
if (c->fd == -1) {
LOG_ERROR("could not open %s", c->port);
- exit(1);
+ free_service(c);
+ return ERROR_FAIL;
}
#endif
}
@@ -409,7 +455,7 @@ int server_loop(struct command_context *command_context)
FD_ZERO(&read_fds);
else {
LOG_ERROR("error during select: %s", strerror(errno));
- exit(-1);
+ return ERROR_FAIL;
}
#else
@@ -417,7 +463,7 @@ int server_loop(struct command_context *command_context)
FD_ZERO(&read_fds);
else {
LOG_ERROR("error during select: %s", strerror(errno));
- exit(-1);
+ return ERROR_FAIL;
}
#endif
}
@@ -536,7 +582,7 @@ int server_preinit(void)
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
LOG_ERROR("Failed to Open Winsock");
- exit(-1);
+ return ERROR_FAIL;
}
/* register ctrl-c handler */
@@ -554,10 +600,18 @@ int server_preinit(void)
int server_init(struct command_context *cmd_ctx)
{
int ret = tcl_init();
- if (ERROR_OK != ret)
+
+ if (ret != ERROR_OK)
+ return ret;
+
+ ret = telnet_init("Open On-Chip Debugger");
+
+ if (ret != ERROR_OK) {
+ remove_services();
return ret;
+ }
- return telnet_init("Open On-Chip Debugger");
+ return ERROR_OK;
}
int server_quit(void)
@@ -634,6 +688,22 @@ COMMAND_HANDLER(handle_poll_period_command)
return ERROR_OK;
}
+COMMAND_HANDLER(handle_bindto_command)
+{
+ switch (CMD_ARGC) {
+ case 0:
+ command_print(CMD_CTX, "bindto name: %s", bindto_name);
+ break;
+ case 1:
+ free(bindto_name);
+ bindto_name = strdup(CMD_ARGV[0]);
+ break;
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ return ERROR_OK;
+}
+
static const struct command_registration server_command_handlers[] = {
{
.name = "shutdown",
@@ -649,6 +719,14 @@ static const struct command_registration server_command_handlers[] = {
.usage = "",
.help = "set the servers polling period",
},
+ {
+ .name = "bindto",
+ .handler = &handle_bindto_command,
+ .mode = COMMAND_ANY,
+ .usage = "[name]",
+ .help = "Specify address by name on which to listen for "
+ "incoming TCP/IP connections",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/server/server.h b/src/server/server.h
index 061523346..68ad16d55 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef SERVER_H
-#define SERVER_H
+#ifndef OPENOCD_SERVER_SERVER_H
+#define OPENOCD_SERVER_SERVER_H
#include
@@ -111,4 +109,4 @@ COMMAND_HELPER(server_port_command, unsigned short *out);
#define ERROR_SERVER_REMOTE_CLOSED (-400)
#define ERROR_CONNECTION_REJECTED (-401)
-#endif /* SERVER_H */
+#endif /* OPENOCD_SERVER_SERVER_H */
diff --git a/src/server/server_stubs.c b/src/server/server_stubs.c
index 4584f3199..a4c017289 100644
--- a/src/server/server_stubs.c
+++ b/src/server/server_stubs.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c
index 789eee8b6..0077339f2 100644
--- a/src/server/tcl_server.c
+++ b/src/server/tcl_server.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -107,7 +105,7 @@ static int tcl_target_callback_trace_handler(struct target *target,
if (tclc->tc_trace) {
hex = malloc(hex_len);
buf = malloc(max_len);
- hexify(hex, (const char *)data, len, hex_len);
+ hexify(hex, data, len, hex_len);
snprintf(buf, max_len, "%s%s%s", header, hex, trailer);
tcl_output(connection, buf, strlen(buf));
free(hex);
diff --git a/src/server/tcl_server.h b/src/server/tcl_server.h
index 971ab996a..422c794ee 100644
--- a/src/server/tcl_server.h
+++ b/src/server/tcl_server.h
@@ -12,17 +12,15 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _TCL_SERVER_H_
-#define _TCL_SERVER_H_
+#ifndef OPENOCD_SERVER_TCL_SERVER_H
+#define OPENOCD_SERVER_TCL_SERVER_H
#include
int tcl_init(void);
int tcl_register_commands(struct command_context *cmd_ctx);
-#endif /* _TCL_SERVER_H_ */
+#endif /* OPENOCD_SERVER_TCL_SERVER_H */
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index 2187dbe28..e33188b5e 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -207,10 +205,17 @@ static void telnet_save_history(struct telnet_connection *t_con)
static int telnet_new_connection(struct connection *connection)
{
- struct telnet_connection *telnet_connection = malloc(sizeof(struct telnet_connection));
+ struct telnet_connection *telnet_connection;
struct telnet_service *telnet_service = connection->service->priv;
int i;
+ telnet_connection = malloc(sizeof(struct telnet_connection));
+
+ if (!telnet_connection) {
+ LOG_ERROR("Failed to allocate telnet connection.");
+ return ERROR_FAIL;
+ }
+
connection->priv = telnet_connection;
/* initialize telnet connection information */
@@ -568,7 +573,7 @@ static int telnet_input(struct connection *connection)
break;
default:
LOG_ERROR("unknown telnet state");
- exit(-1);
+ return ERROR_FAIL;
}
bytes_read--;
@@ -619,17 +624,26 @@ int telnet_init(char *banner)
return ERROR_OK;
}
- struct telnet_service *telnet_service = malloc(sizeof(struct telnet_service));
+ struct telnet_service *telnet_service =
+ malloc(sizeof(struct telnet_service));
+
+ if (!telnet_service) {
+ LOG_ERROR("Failed to allocate telnet service.");
+ return ERROR_FAIL;
+ }
telnet_service->banner = banner;
- return add_service("telnet",
- telnet_port,
- CONNECTION_LIMIT_UNLIMITED,
- telnet_new_connection,
- telnet_input,
- telnet_connection_closed,
+ int ret = add_service("telnet", telnet_port, CONNECTION_LIMIT_UNLIMITED,
+ telnet_new_connection, telnet_input, telnet_connection_closed,
telnet_service);
+
+ if (ret != ERROR_OK) {
+ free(telnet_service);
+ return ret;
+ }
+
+ return ERROR_OK;
}
/* daemon configuration command telnet_port */
diff --git a/src/server/telnet_server.h b/src/server/telnet_server.h
index 94da3d1bc..04ba96570 100644
--- a/src/server/telnet_server.h
+++ b/src/server/telnet_server.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef TELNET_SERVER_H
-#define TELNET_SERVER_H
+#ifndef OPENOCD_SERVER_TELNET_SERVER_H
+#define OPENOCD_SERVER_TELNET_SERVER_H
#include
@@ -69,4 +67,4 @@ struct telnet_service {
int telnet_init(char *banner);
int telnet_register_commands(struct command_context *command_context);
-#endif /* TELNET_SERVER_H */
+#endif /* OPENOCD_SERVER_TELNET_SERVER_H */
diff --git a/src/svf/Makefile.am b/src/svf/Makefile.am
index 3a14d2087..5603d53b5 100644
--- a/src/svf/Makefile.am
+++ b/src/svf/Makefile.am
@@ -1,8 +1,2 @@
-include $(top_srcdir)/common.mk
-
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libsvf.la
-noinst_HEADERS = svf.h
-libsvf_la_SOURCES = svf.c
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+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 7b7b8d09d..e7e815c10 100644
--- a/src/svf/svf.c
+++ b/src/svf/svf.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* The specification for SVF is available here:
@@ -363,7 +361,7 @@ COMMAND_HANDLER(handle_svf_command)
#define SVF_MAX_NUM_OF_OPTIONS 5
int command_num = 0;
int ret = ERROR_OK;
- long long time_measure_ms;
+ int64_t time_measure_ms;
int time_measure_s, time_measure_m;
/* use NULL to indicate a "plain" svf file which accounts for
@@ -537,7 +535,7 @@ COMMAND_HANDLER(handle_svf_command)
time_measure_s %= 60;
if (time_measure_ms < 1000)
command_print(CMD_CTX,
- "\r\nTime used: %dm%ds%lldms ",
+ "\r\nTime used: %dm%ds%" PRId64 "ms ",
time_measure_m,
time_measure_s,
time_measure_ms);
diff --git a/src/svf/svf.h b/src/svf/svf.h
index 4f2ac0a9b..4101a3f85 100644
--- a/src/svf/svf.h
+++ b/src/svf/svf.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef SVF_H
-#define SVF_H
+#ifndef OPENOCD_SVF_SVF_H
+#define OPENOCD_SVF_SVF_H
#include
@@ -46,4 +44,4 @@ int svf_add_statemove(tap_state_t goal_state);
*/
bool svf_tap_state_is_stable(tap_state_t state);
-#endif /* SVF_H */
+#endif /* OPENOCD_SVF_SVF_H */
diff --git a/src/target/Makefile.am b/src/target/Makefile.am
index 9f47b1fd8..1e81f4a13 100644
--- a/src/target/Makefile.am
+++ b/src/target/Makefile.am
@@ -1,31 +1,15 @@
-include $(top_srcdir)/common.mk
-
if OOCD_TRACE
-OOCD_TRACE_FILES = oocd_trace.c
+OOCD_TRACE_FILES = %D%/oocd_trace.c
else
OOCD_TRACE_FILES =
endif
-SUBDIRS = openrisc
-libtarget_la_LIBADD = $(top_builddir)/src/target/openrisc/libopenrisc.la
-
-BIN2C = $(top_srcdir)/src/helper/bin2char.sh
-
-DEBUG_HANDLER = $(srcdir)/xscale/debug_handler.bin
-EXTRA_DIST = \
- startup.tcl \
- $(wildcard $(srcdir)/xscale/*)
+%C%_libtarget_la_LIBADD = %D%/openrisc/libopenrisc.la
-DEBUG_HEADER = xscale_debug.inc
-BUILT_SOURCES = $(DEBUG_HEADER)
-CLEANFILES = $(DEBUG_HEADER)
+STARTUP_TCL_SRCS += %D%/startup.tcl
-$(DEBUG_HEADER): $(DEBUG_HANDLER) $(BIN2C)
- $(BIN2C) < $< > $@ || { rm -f $@; false; }
-
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libtarget.la
-libtarget_la_SOURCES = \
+noinst_LTLIBRARIES += %D%/libtarget.la
+%C%_libtarget_la_SOURCES = \
$(TARGET_CORE_SRC) \
$(ARM_DEBUG_SRC) \
$(ARMV4_5_SRC) \
@@ -36,176 +20,201 @@ libtarget_la_SOURCES = \
$(MIPS32_SRC) \
$(NDS32_SRC) \
$(INTEL_IA32_SRC) \
- avrt.c \
- dsp563xx.c \
- dsp563xx_once.c \
- dsp5680xx.c \
- hla_target.c
+ $(RISCV_SRC) \
+ %D%/avrt.c \
+ %D%/dsp563xx.c \
+ %D%/dsp563xx_once.c \
+ %D%/dsp5680xx.c \
+ %D%/hla_target.c
+
+if TARGET64
+%C%_libtarget_la_SOURCES +=$(ARMV8_SRC)
+endif
TARGET_CORE_SRC = \
- algorithm.c \
- register.c \
- image.c \
- breakpoints.c \
- target.c \
- target_request.c \
- testee.c \
- smp.c
+ %D%/algorithm.c \
+ %D%/register.c \
+ %D%/image.c \
+ %D%/breakpoints.c \
+ %D%/target.c \
+ %D%/target_request.c \
+ %D%/testee.c \
+ %D%/smp.c
ARMV4_5_SRC = \
- armv4_5.c \
- armv4_5_mmu.c \
- armv4_5_cache.c \
+ %D%/armv4_5.c \
+ %D%/armv4_5_mmu.c \
+ %D%/armv4_5_cache.c \
$(ARM7_9_SRC)
ARM7_9_SRC = \
- arm7_9_common.c \
- arm7tdmi.c \
- arm720t.c \
- arm9tdmi.c \
- arm920t.c \
- arm966e.c \
- arm946e.c \
- arm926ejs.c \
- feroceon.c
+ %D%/arm7_9_common.c \
+ %D%/arm7tdmi.c \
+ %D%/arm720t.c \
+ %D%/arm9tdmi.c \
+ %D%/arm920t.c \
+ %D%/arm966e.c \
+ %D%/arm946e.c \
+ %D%/arm926ejs.c \
+ %D%/feroceon.c
ARM_MISC_SRC = \
- fa526.c \
- xscale.c
+ %D%/fa526.c \
+ %D%/xscale.c
ARMV6_SRC = \
- arm11.c \
- arm11_dbgtap.c
+ %D%/arm11.c \
+ %D%/arm11_dbgtap.c
ARMV7_SRC = \
- armv7m.c \
- armv7m_trace.c \
- cortex_m.c \
- armv7a.c \
- cortex_a.c
+ %D%/armv7m.c \
+ %D%/armv7m_trace.c \
+ %D%/cortex_m.c \
+ %D%/armv7a.c \
+ %D%/cortex_a.c \
+ %D%/ls1_sap.c
+
+ARMV8_SRC = \
+ %D%/armv8_dpm.c \
+ %D%/armv8_opcodes.c \
+ %D%/aarch64.c \
+ %D%/armv8.c \
+ %D%/armv8_cache.c
ARM_DEBUG_SRC = \
- arm_dpm.c \
- arm_jtag.c \
- arm_disassembler.c \
- arm_simulator.c \
- arm_semihosting.c \
- arm_adi_v5.c \
- armv7a_cache.c \
- armv7a_cache_l2x.c \
- adi_v5_jtag.c \
- adi_v5_swd.c \
- embeddedice.c \
- trace.c \
- etb.c \
- etm.c \
+ %D%/arm_dpm.c \
+ %D%/arm_jtag.c \
+ %D%/arm_disassembler.c \
+ %D%/arm_simulator.c \
+ %D%/arm_semihosting.c \
+ %D%/arm_adi_v5.c \
+ %D%/armv7a_cache.c \
+ %D%/armv7a_cache_l2x.c \
+ %D%/adi_v5_jtag.c \
+ %D%/adi_v5_swd.c \
+ %D%/embeddedice.c \
+ %D%/trace.c \
+ %D%/etb.c \
+ %D%/etm.c \
$(OOCD_TRACE_FILES) \
- etm_dummy.c
+ %D%/etm_dummy.c \
+ %D%/arm_cti.c
AVR32_SRC = \
- avr32_ap7k.c \
- avr32_jtag.c \
- avr32_mem.c \
- avr32_regs.c
+ %D%/avr32_ap7k.c \
+ %D%/avr32_jtag.c \
+ %D%/avr32_mem.c \
+ %D%/avr32_regs.c
MIPS32_SRC = \
- mips32.c \
- mips_m4k.c \
- mips32_pracc.c \
- mips32_dmaacc.c \
- mips_ejtag.c
+ %D%/mips32.c \
+ %D%/mips_m4k.c \
+ %D%/mips32_pracc.c \
+ %D%/mips32_dmaacc.c \
+ %D%/mips_ejtag.c
NDS32_SRC = \
- nds32.c \
- nds32_reg.c \
- nds32_cmd.c \
- nds32_disassembler.c \
- nds32_tlb.c \
- nds32_v2.c \
- nds32_v3_common.c \
- nds32_v3.c \
- nds32_v3m.c \
- nds32_aice.c
+ %D%/nds32.c \
+ %D%/nds32_reg.c \
+ %D%/nds32_cmd.c \
+ %D%/nds32_disassembler.c \
+ %D%/nds32_tlb.c \
+ %D%/nds32_v2.c \
+ %D%/nds32_v3_common.c \
+ %D%/nds32_v3.c \
+ %D%/nds32_v3m.c \
+ %D%/nds32_aice.c
INTEL_IA32_SRC = \
- quark_x10xx.c \
- lakemont.c \
- x86_32_common.c
-
-noinst_HEADERS = \
- algorithm.h \
- arm.h \
- arm_dpm.h \
- arm_jtag.h \
- arm_adi_v5.h \
- armv7a_cache.h \
- armv7a_cache_l2x.h \
- arm_disassembler.h \
- arm_opcodes.h \
- arm_simulator.h \
- arm_semihosting.h \
- arm7_9_common.h \
- arm7tdmi.h \
- arm720t.h \
- arm9tdmi.h \
- arm920t.h \
- arm926ejs.h \
- arm966e.h \
- arm946e.h \
- arm11.h \
- arm11_dbgtap.h \
- armv4_5.h \
- armv4_5_mmu.h \
- armv4_5_cache.h \
- armv7a.h \
- armv7m.h \
- armv7m_trace.h \
- avrt.h \
- dsp563xx.h \
- dsp563xx_once.h \
- dsp5680xx.h \
- breakpoints.h \
- cortex_m.h \
- cortex_a.h \
- embeddedice.h \
- etb.h \
- etm.h \
- etm_dummy.h \
- image.h \
- mips32.h \
- mips_m4k.h \
- mips_ejtag.h \
- mips32_pracc.h \
- mips32_dmaacc.h \
- oocd_trace.h \
- register.h \
- target.h \
- target_type.h \
- trace.h \
- target_request.h \
- trace.h \
- xscale.h \
- smp.h \
- avr32_ap7k.h \
- avr32_jtag.h \
- avr32_mem.h \
- avr32_regs.h \
- nds32.h \
- nds32_cmd.h \
- nds32_disassembler.h \
- nds32_edm.h \
- nds32_insn.h \
- nds32_reg.h \
- nds32_tlb.h \
- nds32_v2.h \
- nds32_v3_common.h \
- nds32_v3.h \
- nds32_v3m.h \
- nds32_aice.h \
- lakemont.h \
- x86_32_common.h
-
-ocddatadir = $(pkglibdir)
-nobase_dist_ocddata_DATA =
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+ %D%/quark_x10xx.c \
+ %D%/quark_d20xx.c \
+ %D%/lakemont.c \
+ %D%/x86_32_common.c
+
+RISCV_SRC = \
+ %D%/riscv/riscv-011.c \
+ %D%/riscv/riscv-013.c \
+ %D%/riscv/riscv.c \
+ %D%/riscv/program.c \
+ %D%/riscv/batch.c
+
+%C%_libtarget_la_SOURCES += \
+ %D%/algorithm.h \
+ %D%/arm.h \
+ %D%/arm_dpm.h \
+ %D%/arm_jtag.h \
+ %D%/arm_adi_v5.h \
+ %D%/armv7a_cache.h \
+ %D%/armv7a_cache_l2x.h \
+ %D%/arm_disassembler.h \
+ %D%/arm_opcodes.h \
+ %D%/arm_simulator.h \
+ %D%/arm_semihosting.h \
+ %D%/arm7_9_common.h \
+ %D%/arm7tdmi.h \
+ %D%/arm720t.h \
+ %D%/arm9tdmi.h \
+ %D%/arm920t.h \
+ %D%/arm926ejs.h \
+ %D%/arm966e.h \
+ %D%/arm946e.h \
+ %D%/arm11.h \
+ %D%/arm11_dbgtap.h \
+ %D%/armv4_5.h \
+ %D%/armv4_5_mmu.h \
+ %D%/armv4_5_cache.h \
+ %D%/armv7a.h \
+ %D%/armv7m.h \
+ %D%/armv7m_trace.h \
+ %D%/armv8.h \
+ %D%/armv8_dpm.h \
+ %D%/armv8_opcodes.h \
+ %D%/armv8_cache.h \
+ %D%/avrt.h \
+ %D%/dsp563xx.h \
+ %D%/dsp563xx_once.h \
+ %D%/dsp5680xx.h \
+ %D%/breakpoints.h \
+ %D%/cortex_m.h \
+ %D%/cortex_a.h \
+ %D%/aarch64.h \
+ %D%/embeddedice.h \
+ %D%/etb.h \
+ %D%/etm.h \
+ %D%/etm_dummy.h \
+ %D%/image.h \
+ %D%/mips32.h \
+ %D%/mips_m4k.h \
+ %D%/mips_ejtag.h \
+ %D%/mips32_pracc.h \
+ %D%/mips32_dmaacc.h \
+ %D%/oocd_trace.h \
+ %D%/register.h \
+ %D%/target.h \
+ %D%/target_type.h \
+ %D%/trace.h \
+ %D%/target_request.h \
+ %D%/trace.h \
+ %D%/xscale.h \
+ %D%/smp.h \
+ %D%/avr32_ap7k.h \
+ %D%/avr32_jtag.h \
+ %D%/avr32_mem.h \
+ %D%/avr32_regs.h \
+ %D%/nds32.h \
+ %D%/nds32_cmd.h \
+ %D%/nds32_disassembler.h \
+ %D%/nds32_edm.h \
+ %D%/nds32_insn.h \
+ %D%/nds32_reg.h \
+ %D%/nds32_tlb.h \
+ %D%/nds32_v2.h \
+ %D%/nds32_v3_common.h \
+ %D%/nds32_v3.h \
+ %D%/nds32_v3m.h \
+ %D%/nds32_aice.h \
+ %D%/lakemont.h \
+ %D%/x86_32_common.h \
+ %D%/arm_cti.h
+
+include %D%/openrisc/Makefile.am
diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c
index 77d714115..c7dc4f7c9 100644
--- a/src/target/adi_v5_jtag.c
+++ b/src/target/adi_v5_jtag.c
@@ -21,9 +21,7 @@
* GNU 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
***************************************************************************/
/**
@@ -39,6 +37,9 @@
#include "arm.h"
#include "arm_adi_v5.h"
#include
+#include
+
+/*#define DEBUG_WAIT*/
/* JTAG instructions/registers for JTAG-DP and SWJ-DP */
#define JTAG_DP_ABORT 0x8
@@ -52,12 +53,198 @@
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)
+{
+ char *reg_name = "UNK";
+
+ if (instr == JTAG_DP_DPACC) {
+ switch (reg_addr) {
+ case DP_ABORT:
+ reg_name = "ABORT";
+ break;
+ case DP_CTRL_STAT:
+ reg_name = "CTRL/STAT";
+ break;
+ case DP_SELECT:
+ reg_name = "SELECT";
+ break;
+ case DP_RDBUFF:
+ reg_name = "RDBUFF";
+ break;
+ case DP_WCR:
+ reg_name = "WCR";
+ break;
+ default:
+ reg_name = "UNK";
+ break;
+ }
+ }
+
+ if (instr == JTAG_DP_APACC) {
+ switch (reg_addr) {
+ case MEM_AP_REG_CSW:
+ reg_name = "CSW";
+ break;
+ case MEM_AP_REG_TAR:
+ reg_name = "TAR";
+ break;
+ case MEM_AP_REG_DRW:
+ reg_name = "DRW";
+ break;
+ case MEM_AP_REG_BD0:
+ reg_name = "BD0";
+ break;
+ case MEM_AP_REG_BD1:
+ reg_name = "BD1";
+ break;
+ case MEM_AP_REG_BD2:
+ reg_name = "BD2";
+ break;
+ case MEM_AP_REG_BD3:
+ reg_name = "BD3";
+ break;
+ case MEM_AP_REG_CFG:
+ reg_name = "CFG";
+ break;
+ case MEM_AP_REG_BASE:
+ reg_name = "BASE";
+ break;
+ case AP_REG_IDR:
+ reg_name = "IDR";
+ break;
+ default:
+ reg_name = "UNK";
+ break;
+ }
+ }
+
+ return reg_name;
+}
+#endif
+
+struct dap_cmd {
+ struct list_head lh;
+ uint8_t instr;
+ uint8_t reg_addr;
+ uint8_t RnW;
+ uint8_t *invalue;
+ uint8_t ack;
+ uint32_t memaccess_tck;
+ uint32_t dp_select;
+
+ struct scan_field fields[2];
+ uint8_t out_addr_buf;
+ uint8_t invalue_buf[4];
+ uint8_t outvalue_buf[4];
+};
+
+static void log_dap_cmd(const char *header, struct dap_cmd *el)
+{
+#ifdef DEBUG_WAIT
+ 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),
+ 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"));
+#endif
+}
+
+static struct dap_cmd *dap_cmd_new(uint8_t instr,
+ uint8_t reg_addr, uint8_t RnW,
+ uint8_t *outvalue, uint8_t *invalue,
+ uint32_t memaccess_tck)
+{
+ struct dap_cmd *cmd;
+
+ cmd = (struct dap_cmd *)calloc(1, sizeof(struct dap_cmd));
+ if (cmd != NULL) {
+ INIT_LIST_HEAD(&cmd->lh);
+ cmd->instr = instr;
+ cmd->reg_addr = reg_addr;
+ cmd->RnW = RnW;
+ if (outvalue != NULL)
+ memcpy(cmd->outvalue_buf, outvalue, 4);
+ cmd->invalue = (invalue != NULL) ? invalue : cmd->invalue_buf;
+ cmd->memaccess_tck = memaccess_tck;
+ }
+
+ return cmd;
+}
+
+static void flush_journal(struct list_head *lh)
+{
+ struct dap_cmd *el, *tmp;
+
+ list_for_each_entry_safe(el, tmp, lh, lh) {
+ list_del(&el->lh);
+ free(el);
+ }
+}
+
/***************************************************************************
*
* DPACC and APACC scanchain access through JTAG-DP (or SWJ-DP)
*
***************************************************************************/
+static int adi_jtag_dp_scan_cmd(struct adiv5_dap *dap, struct dap_cmd *cmd, uint8_t *ack)
+{
+ struct jtag_tap *tap = dap->tap;
+ int retval;
+
+ retval = arm_jtag_set_instr(tap, cmd->instr, NULL, TAP_IDLE);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* Scan out a read or write operation using some DP or AP register.
+ * For APACC access with any sticky error flag set, this is discarded.
+ */
+ cmd->fields[0].num_bits = 3;
+ buf_set_u32(&cmd->out_addr_buf, 0, 3, ((cmd->reg_addr >> 1) & 0x6) | (cmd->RnW & 0x1));
+ cmd->fields[0].out_value = &cmd->out_addr_buf;
+ cmd->fields[0].in_value = (ack != NULL) ? ack : &cmd->ack;
+
+ /* NOTE: if we receive JTAG_ACK_WAIT, the previous operation did not
+ * complete; data we write is discarded, data we read is unpredictable.
+ * When overrun detect is active, STICKYORUN is set.
+ */
+
+ cmd->fields[1].num_bits = 32;
+ cmd->fields[1].out_value = cmd->outvalue_buf;
+ cmd->fields[1].in_value = cmd->invalue;
+
+ 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.
+ * They provide more time for the (MEM) AP to complete the read ...
+ * See "Minimum Response Time" for JTAG-DP, in the ADIv5 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);
+ }
+
+ return ERROR_OK;
+}
+
+static int adi_jtag_dp_scan_cmd_sync(struct adiv5_dap *dap, struct dap_cmd *cmd, uint8_t *ack)
+{
+ int retval;
+
+ retval = adi_jtag_dp_scan_cmd(dap, cmd, ack);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return jtag_execute_queue();
+}
+
/**
* 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
@@ -80,49 +267,23 @@ static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack);
static int adi_jtag_dp_scan(struct adiv5_dap *dap,
uint8_t instr, uint8_t reg_addr, uint8_t RnW,
- uint8_t *outvalue, uint8_t *invalue, uint8_t *ack,
- uint32_t memaccess_tck)
+ uint8_t *outvalue, uint8_t *invalue,
+ uint32_t memaccess_tck, uint8_t *ack)
{
- struct jtag_tap *tap = dap->tap;
- struct scan_field fields[2];
- uint8_t out_addr_buf;
+ struct dap_cmd *cmd;
int retval;
- retval = arm_jtag_set_instr(tap, instr, NULL, TAP_IDLE);
- if (retval != ERROR_OK)
- return retval;
-
- /* Scan out a read or write operation using some DP or AP register.
- * For APACC access with any sticky error flag set, this is discarded.
- */
- fields[0].num_bits = 3;
- buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1));
- fields[0].out_value = &out_addr_buf;
- fields[0].in_value = ack;
-
- /* NOTE: if we receive JTAG_ACK_WAIT, the previous operation did not
- * complete; data we write is discarded, data we read is unpredictable.
- * When overrun detect is active, STICKYORUN is set.
- */
-
- fields[1].num_bits = 32;
- fields[1].out_value = outvalue;
- fields[1].in_value = invalue;
-
- jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
+ cmd = dap_cmd_new(instr, reg_addr, RnW, outvalue, invalue, memaccess_tck);
+ if (cmd != NULL)
+ cmd->dp_select = dap->select;
+ else
+ return ERROR_JTAG_DEVICE_ERROR;
- /* Add specified number of tck clocks after starting 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.
- */
- if ((instr == JTAG_DP_APACC)
- && ((reg_addr == MEM_AP_REG_DRW)
- || ((reg_addr & 0xF0) == MEM_AP_REG_BD0))
- && memaccess_tck != 0)
- jtag_add_runtest(memaccess_tck, TAP_IDLE);
+ retval = adi_jtag_dp_scan_cmd(dap, cmd, ack);
+ if (retval == ERROR_OK)
+ list_add_tail(&cmd->lh, &dap->cmd_journal);
- return ERROR_OK;
+ return retval;
}
/**
@@ -133,8 +294,8 @@ static int adi_jtag_dp_scan(struct adiv5_dap *dap,
*/
static int adi_jtag_dp_scan_u32(struct adiv5_dap *dap,
uint8_t instr, uint8_t reg_addr, uint8_t RnW,
- uint32_t outvalue, uint32_t *invalue, uint8_t *ack,
- uint32_t memaccess_tck)
+ uint32_t outvalue, uint32_t *invalue,
+ uint32_t memaccess_tck, uint8_t *ack)
{
uint8_t out_value_buf[4];
int retval;
@@ -142,7 +303,7 @@ static int adi_jtag_dp_scan_u32(struct adiv5_dap *dap,
buf_set_u32(out_value_buf, 0, 32, outvalue);
retval = adi_jtag_dp_scan(dap, instr, reg_addr, RnW,
- out_value_buf, (uint8_t *)invalue, ack, memaccess_tck);
+ out_value_buf, (uint8_t *)invalue, memaccess_tck, ack);
if (retval != ERROR_OK)
return retval;
@@ -153,13 +314,17 @@ static int adi_jtag_dp_scan_u32(struct adiv5_dap *dap,
return retval;
}
-static void adi_jtag_finish_read(struct adiv5_dap *dap)
+static int adi_jtag_finish_read(struct adiv5_dap *dap)
{
+ int retval = ERROR_OK;
+
if (dap->last_read != NULL) {
- adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC,
- DP_RDBUFF, DPAP_READ, 0, dap->last_read, &dap->ack, 0);
+ retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC,
+ DP_RDBUFF, DPAP_READ, 0, dap->last_read, 0, NULL);
dap->last_read = NULL;
}
+
+ return retval;
}
static int adi_jtag_scan_inout_check_u32(struct adiv5_dap *dap,
@@ -170,143 +335,265 @@ static int adi_jtag_scan_inout_check_u32(struct adiv5_dap *dap,
/* Issue the read or write */
retval = adi_jtag_dp_scan_u32(dap, instr, reg_addr,
- RnW, outvalue, NULL, NULL, memaccess_tck);
+ RnW, outvalue, NULL, memaccess_tck, NULL);
if (retval != ERROR_OK)
return retval;
/* For reads, collect posted value; RDBUFF has no other effect.
* Assumes read gets acked with OK/FAULT, and CTRL_STAT says "OK".
*/
- if ((RnW == DPAP_READ) && (invalue != NULL))
+ if ((RnW == DPAP_READ) && (invalue != NULL)) {
retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC,
- DP_RDBUFF, DPAP_READ, 0, invalue, &dap->ack, 0);
- return retval;
+ DP_RDBUFF, DPAP_READ, 0, invalue, 0, NULL);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ return jtag_execute_queue();
}
-static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
+static int jtagdp_overrun_check(struct adiv5_dap *dap)
{
int retval;
- uint32_t ctrlstat;
+ struct dap_cmd *el, *tmp, *prev = NULL;
+ int found_wait = 0;
+ int64_t time_now;
+ LIST_HEAD(replay_list);
- /* too expensive to call keep_alive() here */
+ /* make sure all queued transactions are complete */
+ retval = jtag_execute_queue();
+ if (retval != ERROR_OK)
+ goto done;
+
+ /* 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);
+ } 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);
+ retval = ERROR_JTAG_DEVICE_ERROR;
+ goto done;
+ }
+ }
- /* Here be dragons!
- *
- * It is easy to be in a JTAG clock range where the target
- * is not operating in a stable fashion. This happens
- * for a few reasons:
- *
- * - the user may construct a simple test case to try to see
- * if a higher JTAG clock works to eke out more performance.
- * This simple case may pass, but more complex situations can
- * fail.
- *
- * - The mostly works JTAG clock rate and the complete failure
- * JTAG clock rate may be as much as 2-4x apart. This seems
- * to be especially true on RC oscillator driven parts.
- *
- * So: even if calling adi_jtag_scan_inout_check_u32() multiple
- * times here seems to "make things better here", it is just
- * hiding problems with too high a JTAG clock.
- *
- * Note that even if some parts have RCLK/RTCK, that doesn't
- * mean that RCLK/RTCK is the *correct* rate to run the JTAG
- * interface at, i.e. RCLK/RTCK rates can be "too high", especially
- * before the RC oscillator phase is not yet complete.
+ /*
+ * If we found a stalled transaction and a previous transaction
+ * exists, check if it's a READ access.
*/
+ 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);
+ /* 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) {
+ /* recover the read value */
+ log_dap_cmd("FND", tmp);
+ if (el->invalue != el->invalue_buf) {
+ uint32_t invalue = le_to_h_u32(tmp->invalue);
+ memcpy(el->invalue, &invalue, sizeof(uint32_t));
+ }
+ prev = NULL;
+ break;
+ }
+ }
- /* Post CTRL/STAT read; discard any previous posted read value
- * but collect its ACK status.
- */
- retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
- DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
- if (retval != ERROR_OK)
- return retval;
- retval = jtag_execute_queue();
- if (retval != ERROR_OK)
- return retval;
+ if (prev != NULL) {
+ log_dap_cmd("LST", el);
+
+ /*
+ * At this point we're sure that no previous
+ * transaction completed and the DAP/AP is still
+ * in busy state. We know that the next "OK" scan
+ * will return the READ result we need to recover.
+ * To complete the READ, we just keep polling RDBUFF
+ * until the WAIT condition clears
+ */
+ tmp = dap_cmd_new(JTAG_DP_DPACC,
+ DP_RDBUFF, DPAP_READ, NULL, NULL, 0);
+ if (tmp == NULL) {
+ retval = ERROR_JTAG_DEVICE_ERROR;
+ goto done;
+ }
+ /* synchronously retry the command until it succeeds */
+ time_now = timeval_ms();
+ do {
+ 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);
+ if (el->invalue != el->invalue_buf) {
+ uint32_t invalue = le_to_h_u32(tmp->invalue);
+ memcpy(el->invalue, &invalue, sizeof(uint32_t));
+ }
+ break;
+ }
+ if (tmp->ack != JTAG_ACK_WAIT) {
+ LOG_ERROR("Invalid ACK (%1x) in DAP response", tmp->ack);
+ log_dap_cmd("ERR", tmp);
+ retval = ERROR_JTAG_DEVICE_ERROR;
+ break;
+ }
+
+ } while (timeval_ms() - time_now < 1000);
+
+ if (retval == ERROR_OK) {
+ /* timeout happened */
+ if (tmp->ack != JTAG_ACK_OK_FAULT) {
+ LOG_ERROR("Timeout during WAIT recovery");
+ dap->select = DP_SELECT_INVALID;
+ jtag_ap_q_abort(dap, NULL);
+ /* clear the sticky overrun condition */
+ adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+ DP_CTRL_STAT, DPAP_WRITE,
+ dap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);
+ retval = ERROR_JTAG_DEVICE_ERROR;
+ }
+ }
- dap->ack = dap->ack & 0x7;
+ /* we're done with this command, release it */
+ free(tmp);
- /* common code path avoids calling timeval_ms() */
- if (dap->ack != JTAG_ACK_OK_FAULT) {
- long long then = timeval_ms();
+ if (retval != ERROR_OK)
+ goto done;
- while (dap->ack != JTAG_ACK_OK_FAULT) {
- if (dap->ack == JTAG_ACK_WAIT) {
- if ((timeval_ms()-then) > 1000) {
- LOG_WARNING("Timeout (1000ms) waiting "
- "for ACK=OK/FAULT "
- "in JTAG-DP transaction - aborting");
+ }
+ /* make el->invalue point to the default invalue
+ * so that we can safely retry it without clobbering
+ * the result we just recovered */
+ el->invalue = el->invalue_buf;
+ }
+ }
- uint8_t ack;
- int abort_ret = jtag_ap_q_abort(dap, &ack);
+ /* 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);
+ list_move_tail(&el->lh, &replay_list);
+ }
- if (abort_ret != 0)
- LOG_WARNING("Abort failed : return=%d ack=%d", abort_ret, ack);
+ /* we're done with the journal, flush it */
+ flush_journal(&dap->cmd_journal);
- return ERROR_JTAG_DEVICE_ERROR;
- }
- } else {
- LOG_WARNING("Invalid ACK %#x "
- "in JTAG-DP transaction",
- dap->ack);
- return ERROR_JTAG_DEVICE_ERROR;
+ /* check for overrun condition in the last batch of transactions */
+ if (found_wait) {
+ LOG_INFO("DAP transaction stalled (WAIT) - slowing down");
+ /* clear the sticky overrun condition */
+ retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+ DP_CTRL_STAT, DPAP_WRITE,
+ dap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);
+ if (retval != ERROR_OK)
+ goto done;
+
+ /* restore SELECT register first */
+ if (!list_empty(&replay_list)) {
+ el = list_first_entry(&replay_list, struct dap_cmd, lh);
+ tmp = dap_cmd_new(JTAG_DP_DPACC,
+ DP_SELECT, DPAP_WRITE, (uint8_t *)&el->dp_select, NULL, 0);
+ if (tmp == NULL) {
+ retval = ERROR_JTAG_DEVICE_ERROR;
+ goto done;
}
+ list_add(&tmp->lh, &replay_list);
- retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
- DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
- if (retval != ERROR_OK)
- return retval;
- retval = jtag_execute_queue();
- if (retval != ERROR_OK)
- return retval;
- dap->ack = dap->ack & 0x7;
+ dap->select = DP_SELECT_INVALID;
+ }
+
+ list_for_each_entry_safe(el, tmp, &replay_list, lh) {
+ time_now = timeval_ms();
+ do {
+ 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) {
+ if (el->invalue != el->invalue_buf) {
+ uint32_t invalue = le_to_h_u32(el->invalue);
+ memcpy(el->invalue, &invalue, sizeof(uint32_t));
+ }
+ break;
+ }
+ if (el->ack != JTAG_ACK_WAIT) {
+ LOG_ERROR("Invalid ACK (%1x) in DAP response", el->ack);
+ log_dap_cmd("ERR", el);
+ retval = ERROR_JTAG_DEVICE_ERROR;
+ break;
+ }
+ } while (timeval_ms() - time_now < 1000);
+
+ if (retval == ERROR_OK) {
+ if (el->ack != JTAG_ACK_OK_FAULT) {
+ LOG_ERROR("Timeout during WAIT recovery");
+ dap->select = DP_SELECT_INVALID;
+ jtag_ap_q_abort(dap, NULL);
+ /* clear the sticky overrun condition */
+ adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+ DP_CTRL_STAT, DPAP_WRITE,
+ dap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);
+ retval = ERROR_JTAG_DEVICE_ERROR;
+ break;
+ }
+ } else
+ break;
}
}
+ done:
+ flush_journal(&replay_list);
+ flush_journal(&dap->cmd_journal);
+ return retval;
+}
+
+static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
+{
+ int retval;
+ uint32_t ctrlstat;
+
+ /* too expensive to call keep_alive() here */
+
+ /* Post CTRL/STAT read; discard any previous posted read value
+ * but collect its ACK status.
+ */
+ retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+ DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
+ if (retval != ERROR_OK)
+ goto done;
+
/* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */
- /* Check for STICKYERR and STICKYORUN */
- if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) {
- LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
+ /* Check for STICKYERR */
+ if (ctrlstat & SSTICKYERR) {
+ LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
/* Check power to debug regions */
if ((ctrlstat & (CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ | CSYSPWRUPACK)) !=
(CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ | CSYSPWRUPACK)) {
LOG_ERROR("Debug regions are unpowered, an unexpected reset might have happened");
- return ERROR_JTAG_DEVICE_ERROR;
- } else {
- if (ctrlstat & SSTICKYORUN)
- LOG_ERROR("JTAG-DP OVERRUN - check clock, "
- "memaccess, or reduce jtag speed");
-
- if (ctrlstat & SSTICKYERR)
- LOG_ERROR("JTAG-DP STICKY ERROR");
-
- /* Clear Sticky Error Bits */
- retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
- DP_CTRL_STAT, DPAP_WRITE,
- dap->dp_ctrl_stat | SSTICKYORUN
- | SSTICKYERR, NULL, 0);
- if (retval != ERROR_OK)
- return retval;
- retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
- DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
- if (retval != ERROR_OK)
- return retval;
- retval = jtag_execute_queue();
- if (retval != ERROR_OK)
- return retval;
-
- LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
}
- retval = jtag_execute_queue();
+
+ if (ctrlstat & SSTICKYERR)
+ LOG_ERROR("JTAG-DP STICKY ERROR");
+ if (ctrlstat & SSTICKYORUN)
+ LOG_DEBUG("JTAG-DP STICKY OVERRUN");
+
+ /* Clear Sticky Error Bits */
+ retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+ DP_CTRL_STAT, DPAP_WRITE,
+ dap->dp_ctrl_stat | SSTICKYERR, NULL, 0);
if (retval != ERROR_OK)
- return retval;
- return ERROR_JTAG_DEVICE_ERROR;
+ goto done;
+
+ retval = ERROR_JTAG_DEVICE_ERROR;
}
- return ERROR_OK;
+ done:
+ flush_journal(&dap->cmd_journal);
+ return retval;
}
/*--------------------------------------------------------------------------*/
@@ -315,7 +602,7 @@ static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
uint32_t *data)
{
int retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC, reg,
- DPAP_READ, 0, dap->last_read, &dap->ack, 0);
+ DPAP_READ, 0, dap->last_read, 0, NULL);
dap->last_read = data;
return retval;
}
@@ -324,7 +611,7 @@ static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg,
uint32_t data)
{
int retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC,
- reg, DPAP_WRITE, data, dap->last_read, &dap->ack, 0);
+ reg, DPAP_WRITE, data, dap->last_read, 0, NULL);
dap->last_read = NULL;
return retval;
}
@@ -351,8 +638,7 @@ static int jtag_ap_q_read(struct adiv5_ap *ap, unsigned reg,
return retval;
retval = adi_jtag_dp_scan_u32(ap->dap, JTAG_DP_APACC, reg,
- DPAP_READ, 0, ap->dap->last_read, &ap->dap->ack,
- ap->memaccess_tck);
+ DPAP_READ, 0, ap->dap->last_read, ap->memaccess_tck, NULL);
ap->dap->last_read = data;
return retval;
@@ -366,8 +652,7 @@ static int jtag_ap_q_write(struct adiv5_ap *ap, unsigned reg,
return retval;
retval = adi_jtag_dp_scan_u32(ap->dap, JTAG_DP_APACC, reg,
- DPAP_WRITE, data, ap->dap->last_read, &ap->dap->ack,
- ap->memaccess_tck);
+ DPAP_WRITE, data, ap->dap->last_read, ap->memaccess_tck, NULL);
ap->dap->last_read = NULL;
return retval;
}
@@ -375,14 +660,32 @@ static int jtag_ap_q_write(struct adiv5_ap *ap, unsigned reg,
static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack)
{
/* for JTAG, this is the only valid ABORT register operation */
- return adi_jtag_dp_scan_u32(dap, JTAG_DP_ABORT,
- 0, DPAP_WRITE, 1, NULL, ack, 0);
+ int retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_ABORT,
+ 0, DPAP_WRITE, 1, NULL, 0, NULL);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return jtag_execute_queue();
}
static int jtag_dp_run(struct adiv5_dap *dap)
{
- adi_jtag_finish_read(dap);
- return jtagdp_transaction_endcheck(dap);
+ int retval;
+ int retval2 = ERROR_OK;
+
+ retval = adi_jtag_finish_read(dap);
+ if (retval != ERROR_OK)
+ goto done;
+ retval2 = jtagdp_overrun_check(dap);
+ retval = jtagdp_transaction_endcheck(dap);
+
+ done:
+ return (retval2 != ERROR_OK) ? retval2 : retval;
+}
+
+static int jtag_dp_sync(struct adiv5_dap *dap)
+{
+ return jtagdp_overrun_check(dap);
}
/* FIXME don't export ... just initialize as
@@ -395,6 +698,7 @@ const struct dap_ops jtag_dp_ops = {
.queue_ap_write = jtag_ap_q_write,
.queue_ap_abort = jtag_ap_q_abort,
.run = jtag_dp_run,
+ .sync = jtag_dp_sync,
};
diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c
index 6990a8b9c..41ddbd789 100644
--- a/src/target/adi_v5_swd.c
+++ b/src/target/adi_v5_swd.c
@@ -13,9 +13,7 @@
* GNU 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
***************************************************************************/
/**
@@ -99,24 +97,36 @@ static int swd_run_inner(struct adiv5_dap *dap)
static int swd_connect(struct adiv5_dap *dap)
{
- uint32_t idcode;
+ uint32_t dpidr;
int status;
/* FIXME validate transport config ... is the
* configured DAP present (check IDCODE)?
* Is *only* one DAP configured?
*
- * MUST READ IDCODE
+ * MUST READ DPIDR
*/
+ /* Check if we should reset srst already when connecting, but not if reconnecting. */
+ if (!dap->do_reconnect) {
+ enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+ if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
+ if (jtag_reset_config & RESET_SRST_NO_GATING)
+ swd_add_reset(1);
+ else
+ LOG_WARNING("\'srst_nogate\' reset_config option is required");
+ }
+ }
+
/* Note, debugport_init() does setup too */
jtag_interface->swd->switch_seq(JTAG_TO_SWD);
- /* Make sure we don't try to perform any other accesses before the DPIDR read. */
+ /* Clear link state, including the SELECT cache. */
dap->do_reconnect = false;
- dap->select = 0;
+ dap->select = DP_SELECT_INVALID;
- swd_queue_dp_read(dap, DP_IDCODE, &idcode);
+ swd_queue_dp_read(dap, DP_DPIDR, &dpidr);
/* force clear all sticky faults */
swd_clear_sticky_errors(dap);
@@ -124,7 +134,7 @@ static int swd_connect(struct adiv5_dap *dap)
status = swd_run_inner(dap);
if (status == ERROR_OK) {
- LOG_INFO("SWD IDCODE %#8.8" PRIx32, idcode);
+ LOG_INFO("SWD DPIDR %#8.8" PRIx32, dpidr);
dap->do_reconnect = false;
} else
dap->do_reconnect = true;
@@ -158,7 +168,8 @@ static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
/** Select the DP register bank matching bits 7:4 of reg. */
static void swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned reg)
{
- if (reg == DP_SELECT)
+ /* Only register address 4 is banked. */
+ if ((reg & 0xf) != 4)
return;
uint32_t select_dp_bank = (reg & 0x000000F0) >> 4;
@@ -341,61 +352,6 @@ int dap_to_swd(struct target *target)
return retval;
}
-COMMAND_HANDLER(handle_swd_wcr)
-{
- int retval;
- struct target *target = get_current_target(CMD_CTX);
- struct arm *arm = target_to_arm(target);
- struct adiv5_dap *dap = arm->dap;
- uint32_t wcr;
- unsigned trn, scale = 0;
-
- switch (CMD_ARGC) {
- /* no-args: just dump state */
- case 0:
- /*retval = swd_queue_dp_read(dap, DP_WCR, &wcr); */
- retval = dap_queue_dp_read(dap, DP_WCR, &wcr);
- if (retval == ERROR_OK)
- dap->ops->run(dap);
- if (retval != ERROR_OK) {
- LOG_ERROR("can't read WCR?");
- return retval;
- }
-
- command_print(CMD_CTX,
- "turnaround=%" PRIu32 ", prescale=%" PRIu32,
- WCR_TO_TRN(wcr),
- WCR_TO_PRESCALE(wcr));
- return ERROR_OK;
-
- case 2: /* TRN and prescale */
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], scale);
- if (scale > 7) {
- LOG_ERROR("prescale %d is too big", scale);
- return ERROR_FAIL;
- }
- /* FALL THROUGH */
-
- case 1: /* TRN only */
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], trn);
- if (trn < 1 || trn > 4) {
- LOG_ERROR("turnaround %d is invalid", trn);
- return ERROR_FAIL;
- }
-
- wcr = ((trn - 1) << 8) | scale;
- /* FIXME
- * write WCR ...
- * then, re-init adapter with new TRN
- */
- LOG_ERROR("can't yet modify WCR");
- return ERROR_FAIL;
-
- default: /* too many arguments */
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-}
-
static const struct command_registration swd_commands[] = {
{
/*
@@ -410,15 +366,6 @@ static const struct command_registration swd_commands[] = {
.mode = COMMAND_CONFIG,
.help = "declare a new SWD DAP"
},
- {
- .name = "wcr",
- .handler = handle_swd_wcr,
- .mode = COMMAND_ANY,
- .help = "display or update DAP's WCR register",
- .usage = "turnaround (1..4), prescale (0..7)",
- },
-
- /* REVISIT -- add a command for SWV trace on/off */
COMMAND_REGISTRATION_DONE
};
@@ -477,6 +424,8 @@ static int swd_init(struct command_context *ctx)
/* Force the DAP's ops vector for SWD mode.
* messy - is there a better way? */
arm->dap->ops = &swd_dap_ops;
+ /* First connect after init is not reconnecting. */
+ dap->do_reconnect = false;
return swd_connect(dap);
}
diff --git a/src/target/algorithm.c b/src/target/algorithm.c
index aa8262a6e..9fc938604 100644
--- a/src/target/algorithm.c
+++ b/src/target/algorithm.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/algorithm.h b/src/target/algorithm.h
index 2d510db7a..8894241c0 100644
--- a/src/target/algorithm.h
+++ b/src/target/algorithm.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ALGORITHM_H
-#define ALGORITHM_H
+#ifndef OPENOCD_TARGET_ALGORITHM_H
+#define OPENOCD_TARGET_ALGORITHM_H
enum param_direction {
PARAM_IN,
@@ -28,7 +26,7 @@ enum param_direction {
};
struct mem_param {
- uint32_t address;
+ target_addr_t address;
uint32_t size;
uint8_t *value;
enum param_direction direction;
@@ -49,4 +47,4 @@ void init_reg_param(struct reg_param *param,
char *reg_name, uint32_t size, enum param_direction dir);
void destroy_reg_param(struct reg_param *param);
-#endif /* ALGORITHM_H */
+#endif /* OPENOCD_TARGET_ALGORITHM_H */
diff --git a/src/target/arm.h b/src/target/arm.h
index 27636cc3d..d63ead215 100644
--- a/src/target/arm.h
+++ b/src/target/arm.h
@@ -19,13 +19,11 @@
* GNU 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*/
-#ifndef ARM_H
-#define ARM_H
+#ifndef OPENOCD_TARGET_ARM_H
+#define OPENOCD_TARGET_ARM_H
#include
#include "target.h"
@@ -61,12 +59,22 @@ enum arm_mode {
ARM_MODE_MON = 22,
ARM_MODE_ABT = 23,
ARM_MODE_UND = 27,
+ ARM_MODE_1176_MON = 28,
ARM_MODE_SYS = 31,
ARM_MODE_THREAD = 0,
ARM_MODE_USER_THREAD = 1,
ARM_MODE_HANDLER = 2,
+ /* shift left 4 bits for armv8 64 */
+ ARMV8_64_EL0T = 0x0F,
+ ARMV8_64_EL1T = 0x4F,
+ ARMV8_64_EL1H = 0x5F,
+ ARMV8_64_EL2T = 0x8F,
+ ARMV8_64_EL2H = 0x9F,
+ ARMV8_64_EL3T = 0xCF,
+ ARMV8_64_EL3H = 0xDF,
+
ARM_MODE_ANY = -1
};
@@ -79,6 +87,7 @@ enum arm_state {
ARM_STATE_THUMB,
ARM_STATE_JAZELLE,
ARM_STATE_THUMB_EE,
+ ARM_STATE_AARCH64,
};
#define ARM_COMMON_MAGIC 0x0A450A45
@@ -131,6 +140,18 @@ struct arm {
/** Flag reporting whether semihosting is active. */
bool is_semihosting;
+ /** Flag reporting whether semihosting fileio is active. */
+ bool is_semihosting_fileio;
+
+ /** Flag reporting whether semihosting fileio operation is active. */
+ bool semihosting_hit_fileio;
+
+ /** Current semihosting operation. */
+ int semihosting_op;
+
+ /** Current semihosting result. */
+ int semihosting_result;
+
/** Value to be returned by semihosting SYS_ERRNO request. */
int semihosting_errno;
@@ -202,10 +223,11 @@ struct arm_reg {
enum arm_mode mode;
struct target *target;
struct arm *arm;
- uint8_t value[4];
+ uint8_t value[8];
};
struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm);
+struct reg_cache *armv8_build_reg_cache(struct target *target);
extern const struct command_registration arm_command_handlers[];
@@ -213,6 +235,9 @@ int arm_arch_state(struct target *target);
int arm_get_gdb_reg_list(struct target *target,
struct reg **reg_list[], int *reg_list_size,
enum target_register_class reg_class);
+int armv8_get_gdb_reg_list(struct target *target,
+ struct reg **reg_list[], int *reg_list_size,
+ enum target_register_class reg_class);
int arm_init_arch_info(struct target *target, struct arm *arm);
@@ -220,7 +245,7 @@ int arm_init_arch_info(struct target *target, struct arm *arm);
int armv4_5_run_algorithm(struct target *target,
int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params,
- uint32_t entry_point, uint32_t exit_point,
+ target_addr_t entry_point, target_addr_t exit_point,
int timeout_ms, void *arch_info);
int armv4_5_run_algorithm_inner(struct target *target,
int num_mem_params, struct mem_param *mem_params,
@@ -231,14 +256,15 @@ int armv4_5_run_algorithm_inner(struct target *target,
int timeout_ms, void *arch_info));
int arm_checksum_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *checksum);
+ target_addr_t address, uint32_t count, uint32_t *checksum);
int arm_blank_check_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *blank);
+ target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value);
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 /* ARM_H */
+#endif /* OPENOCD_TARGET_ARM_H */
diff --git a/src/target/arm11.c b/src/target/arm11.c
index 0cb1d8c83..13fbd207a 100644
--- a/src/target/arm11.c
+++ b/src/target/arm11.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -44,7 +42,7 @@
static int arm11_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints);
+ target_addr_t address, int handle_breakpoints);
/** Check and if necessary take control of the system
@@ -392,7 +390,7 @@ static int arm11_halt(struct target *target)
break;
- long long then = 0;
+ int64_t then = 0;
if (i == 1000)
then = timeval_ms();
if (i >= 1000) {
@@ -420,16 +418,38 @@ static uint32_t arm11_nextpc(struct arm11_common *arm11, int current, uint32_t a
{
void *value = arm11->arm.pc->value;
- if (!current)
- buf_set_u32(value, 0, 32, address);
- else
+ /* use the current program counter */
+ if (current)
address = buf_get_u32(value, 0, 32);
+ /* Make sure that the gdb thumb fixup does not
+ * kill the return address
+ */
+ switch (arm11->arm.core_state) {
+ case ARM_STATE_ARM:
+ address &= 0xFFFFFFFC;
+ break;
+ case ARM_STATE_THUMB:
+ /* When the return address is loaded into PC
+ * bit 0 must be 1 to stay in Thumb state
+ */
+ address |= 0x1;
+ break;
+
+ /* catch-all for JAZELLE and THUMB_EE */
+ default:
+ break;
+ }
+
+ buf_set_u32(value, 0, 32, address);
+ arm11->arm.pc->dirty = 1;
+ arm11->arm.pc->valid = 1;
+
return address;
}
static int arm11_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints, int debug_execution)
{
/* LOG_DEBUG("current %d address %08x handle_breakpoints %d debug_execution %d", */
/* current, address, handle_breakpoints, debug_execution); */
@@ -447,7 +467,7 @@ static int arm11_resume(struct target *target, int current,
address = arm11_nextpc(arm11, current, address);
- LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : "");
+ LOG_DEBUG("RESUME PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
/* clear breakpoints/watchpoints and VCR*/
CHECK_RETVAL(arm11_sc7_clear_vbw(arm11));
@@ -461,7 +481,7 @@ static int arm11_resume(struct target *target, int current,
for (bp = target->breakpoints; bp; bp = bp->next) {
if (bp->address == address) {
- LOG_DEBUG("must step over %08" PRIx32 "", bp->address);
+ LOG_DEBUG("must step over %08" TARGET_PRIxADDR "", bp->address);
arm11_step(target, 1, 0, 0);
break;
}
@@ -487,7 +507,7 @@ static int arm11_resume(struct target *target, int current,
CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));
- LOG_DEBUG("Add BP %d at %08" PRIx32, brp_num,
+ LOG_DEBUG("Add BP %d at %08" TARGET_PRIxADDR, brp_num,
bp->address);
brp_num++;
@@ -514,7 +534,7 @@ static int arm11_resume(struct target *target, int current,
break;
- long long then = 0;
+ int64_t then = 0;
if (i == 1000)
then = timeval_ms();
if (i >= 1000) {
@@ -537,7 +557,7 @@ static int arm11_resume(struct target *target, int current,
}
static int arm11_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
LOG_DEBUG("target->state: %s",
target_state_name(target));
@@ -551,7 +571,7 @@ static int arm11_step(struct target *target, int current,
address = arm11_nextpc(arm11, current, address);
- LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : "");
+ LOG_DEBUG("STEP PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
/** \todo TODO: Thumb not supported here */
@@ -563,13 +583,13 @@ static int arm11_step(struct target *target, int current,
/* skip over BKPT */
if ((next_instruction & 0xFFF00070) == 0xe1200070) {
address = arm11_nextpc(arm11, 0, address + 4);
- LOG_DEBUG("Skipping BKPT %08" PRIx32, address);
+ LOG_DEBUG("Skipping BKPT %08" TARGET_PRIxADDR, address);
}
/* skip over Wait for interrupt / Standby
* mcr 15, 0, r?, cr7, cr0, {4} */
else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90) {
address = arm11_nextpc(arm11, 0, address + 4);
- LOG_DEBUG("Skipping WFI %08" PRIx32, address);
+ LOG_DEBUG("Skipping WFI %08" TARGET_PRIxADDR, address);
}
/* ignore B to self */
else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
@@ -694,21 +714,32 @@ static int arm11_assert_reset(struct target *target)
{
struct arm11_common *arm11 = target_to_arm11(target);
- /* optionally catch reset vector */
- if (target->reset_halt && !(arm11->vcr & 1))
- CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));
-
- /* Issue some kind of warm reset. */
- if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
- target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
- else if (jtag_get_reset_config() & RESET_HAS_SRST) {
- /* REVISIT handle "pulls" cases, if there's
- * hardware that needs them to work.
- */
- jtag_add_reset(0, 1);
+ if (!(target_was_examined(target))) {
+ if (jtag_get_reset_config() & RESET_HAS_SRST)
+ jtag_add_reset(0, 1);
+ else {
+ LOG_WARNING("Reset is not asserted because the target is not examined.");
+ LOG_WARNING("Use a reset button or power cycle the target.");
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
} else {
- LOG_ERROR("%s: how to reset?", target_name(target));
- return ERROR_FAIL;
+
+ /* optionally catch reset vector */
+ if (target->reset_halt && !(arm11->vcr & 1))
+ CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));
+
+ /* Issue some kind of warm reset. */
+ if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
+ target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
+ else if (jtag_get_reset_config() & RESET_HAS_SRST) {
+ /* REVISIT handle "pulls" cases, if there's
+ * hardware that needs them to work.
+ */
+ jtag_add_reset(0, 1);
+ } else {
+ LOG_ERROR("%s: how to reset?", target_name(target));
+ return ERROR_FAIL;
+ }
}
/* registers are now invalid */
@@ -856,7 +887,7 @@ static int arm11_read_memory_inner(struct target *target,
}
static int arm11_read_memory(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint32_t count,
uint8_t *buffer)
@@ -1012,7 +1043,7 @@ static int arm11_write_memory_inner(struct target *target,
}
static int arm11_write_memory(struct target *target,
- uint32_t address, uint32_t size,
+ target_addr_t address, uint32_t size,
uint32_t count, const uint8_t *buffer)
{
/* pointer increment matters only for multi-unit writes ...
diff --git a/src/target/arm11.h b/src/target/arm11.h
index d9e45357e..77cc2236d 100644
--- a/src/target/arm11.h
+++ b/src/target/arm11.h
@@ -15,13 +15,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM11_H
-#define ARM11_H
+#ifndef OPENOCD_TARGET_ARM11_H
+#define OPENOCD_TARGET_ARM11_H
#include "arm.h"
#include "arm_dpm.h"
@@ -113,4 +111,4 @@ enum arm11_sc7 {
ARM11_SC7_WCR0 = 112,
};
-#endif /* ARM11_H */
+#endif /* OPENOCD_TARGET_ARM11_H */
diff --git a/src/target/arm11_dbgtap.c b/src/target/arm11_dbgtap.c
index 9271a2b96..2232b3ef6 100644
--- a/src/target/arm11_dbgtap.c
+++ b/src/target/arm11_dbgtap.c
@@ -15,9 +15,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -410,7 +408,7 @@ int arm11_run_instr_no_data(struct arm11_common *arm11,
if (flag)
break;
- long long then = 0;
+ int64_t then = 0;
if (i == 1000)
then = timeval_ms();
@@ -493,7 +491,7 @@ int arm11_run_instr_data_to_core(struct arm11_common *arm11,
JTAG_DEBUG("DTR Ready %d nRetry %d", Ready, nRetry);
- long long then = 0;
+ int64_t then = 0;
if (i == 1000)
then = timeval_ms();
@@ -525,7 +523,7 @@ int arm11_run_instr_data_to_core(struct arm11_common *arm11,
JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d",
(unsigned) Data, Ready, nRetry);
- long long then = 0;
+ int64_t then = 0;
if (i == 1000)
then = timeval_ms();
@@ -789,7 +787,7 @@ int arm11_run_instr_data_from_core(struct arm11_common *arm11,
JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d",
(unsigned) Data, Ready, nRetry);
- long long then = 0;
+ int64_t then = 0;
if (i == 1000)
then = timeval_ms();
@@ -924,7 +922,7 @@ int arm11_sc7_run(struct arm11_common *arm11, struct arm11_sc7_action *actions,
if (Ready)
break;
- long long then = 0;
+ int64_t then = 0;
if (i_n == 1000)
then = timeval_ms();
diff --git a/src/target/arm11_dbgtap.h b/src/target/arm11_dbgtap.h
index 7f48ec4fe..541434edc 100644
--- a/src/target/arm11_dbgtap.h
+++ b/src/target/arm11_dbgtap.h
@@ -15,13 +15,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM11_DBGTAP_H
-#define ARM11_DBGTAP_H
+#ifndef OPENOCD_TARGET_ARM11_DBGTAP_H
+#define OPENOCD_TARGET_ARM11_DBGTAP_H
#include "arm11.h"
@@ -82,4 +80,4 @@ int arm11_read_memory_word(struct arm11_common *arm11,
int arm11_dpm_init(struct arm11_common *arm11, uint32_t didr);
int arm11_bpwp_flush(struct arm11_common *arm11);
-#endif /* ARM11_DBGTAP_H */
+#endif /* OPENOCD_TARGET_ARM11_DBGTAP_H */
diff --git a/src/target/arm720t.c b/src/target/arm720t.c
index a97ad118e..bcbfa9dff 100644
--- a/src/target/arm720t.c
+++ b/src/target/arm720t.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -273,7 +271,7 @@ static int arm720_mmu(struct target *target, int *enabled)
}
static int arm720_virt2phys(struct target *target,
- uint32_t virtual, uint32_t *physical)
+ target_addr_t virtual, target_addr_t *physical)
{
uint32_t cb;
struct arm720t_common *arm720t = target_to_arm720(target);
@@ -288,7 +286,7 @@ static int arm720_virt2phys(struct target *target,
}
static int arm720t_read_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+ target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
{
int retval;
struct arm720t_common *arm720t = target_to_arm720(target);
@@ -311,7 +309,7 @@ static int arm720t_read_memory(struct target *target,
}
static int arm720t_read_phys_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+ target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
{
struct arm720t_common *arm720t = target_to_arm720(target);
@@ -319,7 +317,7 @@ static int arm720t_read_phys_memory(struct target *target,
}
static int arm720t_write_phys_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
+ target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct arm720t_common *arm720t = target_to_arm720(target);
@@ -338,7 +336,7 @@ static int arm720t_soft_reset_halt(struct target *target)
if (retval != ERROR_OK)
return retval;
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
int timeout;
while (!(timeout = ((timeval_ms()-then) > 1000))) {
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {
diff --git a/src/target/arm720t.h b/src/target/arm720t.h
index 35d45ffd4..31dad9c76 100644
--- a/src/target/arm720t.h
+++ b/src/target/arm720t.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM720T_H
-#define ARM720T_H
+#ifndef OPENOCD_TARGET_ARM720T_H
+#define OPENOCD_TARGET_ARM720T_H
#include "arm7tdmi.h"
#include "armv4_5_mmu.h"
@@ -40,4 +38,4 @@ static inline struct arm720t_common *target_to_arm720(struct target *target)
return container_of(target->arch_info, struct arm720t_common, arm7_9_common.arm);
}
-#endif /* ARM720T_H */
+#endif /* OPENOCD_TARGET_ARM720T_H */
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index 7b40f5057..7fd1ed9f8 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -24,9 +24,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -103,7 +101,8 @@ static void arm7_9_assign_wp(struct arm7_9_common *arm7_9, struct breakpoint *br
arm7_9->wp_available--;
} else
LOG_ERROR("BUG: no hardware comparator available");
- LOG_DEBUG("BPID: %" PRId32 " (0x%08" PRIx32 ") using hw wp: %d",
+
+ LOG_DEBUG("BPID: %" PRId32 " (0x%08" TARGET_PRIxADDR ") using hw wp: %d",
breakpoint->unique_id,
breakpoint->address,
breakpoint->set);
@@ -189,7 +188,7 @@ static int arm7_9_set_breakpoint(struct target *target, struct breakpoint *break
struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
int retval = ERROR_OK;
- LOG_DEBUG("BPID: %" PRId32 ", Address: 0x%08" PRIx32 ", Type: %d",
+ LOG_DEBUG("BPID: %" PRId32 ", Address: 0x%08" TARGET_PRIxADDR ", Type: %d",
breakpoint->unique_id,
breakpoint->address,
breakpoint->type);
@@ -246,7 +245,7 @@ static int arm7_9_set_breakpoint(struct target *target, struct breakpoint *break
if (retval != ERROR_OK)
return retval;
if (verify != arm7_9->arm_bkpt) {
- LOG_ERROR("Unable to set 32 bit software breakpoint at address %08" PRIx32
+ LOG_ERROR("Unable to set 32 bit software breakpoint at address %08" TARGET_PRIxADDR
" - check that memory is read/writable", breakpoint->address);
return ERROR_OK;
}
@@ -266,7 +265,7 @@ static int arm7_9_set_breakpoint(struct target *target, struct breakpoint *break
if (retval != ERROR_OK)
return retval;
if (verify != arm7_9->thumb_bkpt) {
- LOG_ERROR("Unable to set thumb software breakpoint at address %08" PRIx32
+ LOG_ERROR("Unable to set thumb software breakpoint at address %08" TARGET_PRIxADDR
" - check that memory is read/writable", breakpoint->address);
return ERROR_OK;
}
@@ -301,7 +300,7 @@ static int arm7_9_unset_breakpoint(struct target *target, struct breakpoint *bre
int retval = ERROR_OK;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
- LOG_DEBUG("BPID: %" PRId32 ", Address: 0x%08" PRIx32,
+ LOG_DEBUG("BPID: %" PRId32 ", Address: 0x%08" TARGET_PRIxADDR,
breakpoint->unique_id,
breakpoint->address);
@@ -350,12 +349,12 @@ static int arm7_9_unset_breakpoint(struct target *target, struct breakpoint *bre
if (retval != ERROR_OK)
return retval;
current_instr = target_buffer_get_u16(target, (uint8_t *)¤t_instr);
- if (current_instr == arm7_9->thumb_bkpt)
+ if (current_instr == arm7_9->thumb_bkpt) {
retval = target_write_memory(target,
breakpoint->address, 2, 1, breakpoint->orig_instr);
if (retval != ERROR_OK)
return retval;
-
+ }
}
if (--arm7_9->sw_breakpoint_count == 0) {
@@ -636,8 +635,8 @@ int arm7_9_execute_sys_speed(struct target *target)
if (retval != ERROR_OK)
return retval;
- long long then = timeval_ms();
- int timeout;
+ int64_t then = timeval_ms();
+ bool timeout;
while (!(timeout = ((timeval_ms()-then) > 1000))) {
/* read debug status register */
embeddedice_read_reg(dbg_stat);
@@ -875,6 +874,13 @@ int arm7_9_assert_reset(struct target *target)
enum reset_types jtag_reset_config = jtag_get_reset_config();
bool use_event = false;
+ /* TODO: apply hw reset signal in not examined state */
+ if (!(target_was_examined(target))) {
+ LOG_WARNING("Reset is not asserted because the target is not examined.");
+ LOG_WARNING("Use a reset button or power cycle the target.");
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
+
LOG_DEBUG("target->state: %s", target_state_name(target));
if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
@@ -1687,7 +1693,7 @@ static void arm7_9_enable_breakpoints(struct target *target)
int arm7_9_resume(struct target *target,
int current,
- uint32_t address,
+ target_addr_t address,
int handle_breakpoints,
int debug_execution)
{
@@ -1719,7 +1725,7 @@ int arm7_9_resume(struct target *target,
breakpoint = breakpoint_find(target,
buf_get_u32(arm->pc->value, 0, 32));
if (breakpoint != NULL) {
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (id: %" PRId32,
+ LOG_DEBUG("unset breakpoint at 0x%8.8" TARGET_PRIxADDR " (id: %" PRId32,
breakpoint->address,
breakpoint->unique_id);
retval = arm7_9_unset_breakpoint(target, breakpoint);
@@ -1778,7 +1784,7 @@ int arm7_9_resume(struct target *target,
LOG_DEBUG("new PC after step: 0x%8.8" PRIx32,
buf_get_u32(arm->pc->value, 0, 32));
- LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+ LOG_DEBUG("set breakpoint at 0x%8.8" TARGET_PRIxADDR "", breakpoint->address);
retval = arm7_9_set_breakpoint(target, breakpoint);
if (retval != ERROR_OK)
return retval;
@@ -1889,7 +1895,7 @@ void arm7_9_disable_eice_step(struct target *target)
embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE]);
}
-int arm7_9_step(struct target *target, int current, uint32_t address, int handle_breakpoints)
+int arm7_9_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
{
struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
struct arm *arm = &arm7_9->arm;
@@ -2089,7 +2095,7 @@ static int arm7_9_write_core_reg(struct target *target, struct reg *r,
}
int arm7_9_read_memory(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint32_t count,
uint8_t *buffer)
@@ -2104,7 +2110,7 @@ int arm7_9_read_memory(struct target *target,
int retval;
int last_reg = 0;
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
+ LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
address, size, count);
if (target->state != TARGET_HALTED) {
@@ -2242,7 +2248,8 @@ int arm7_9_read_memory(struct target *target,
if (((cpsr & 0x1f) == ARM_MODE_ABT) && (arm->core_mode != ARM_MODE_ABT)) {
LOG_WARNING(
- "memory read caused data abort (address: 0x%8.8" PRIx32 ", size: 0x%" PRIx32 ", count: 0x%" PRIx32 ")",
+ "memory read caused data abort "
+ "(address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%" PRIx32 ", count: 0x%" PRIx32 ")",
address,
size,
count);
@@ -2258,7 +2265,7 @@ int arm7_9_read_memory(struct target *target,
}
int arm7_9_write_memory(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint32_t count,
const uint8_t *buffer)
@@ -2455,7 +2462,8 @@ int arm7_9_write_memory(struct target *target,
if (((cpsr & 0x1f) == ARM_MODE_ABT) && (arm->core_mode != ARM_MODE_ABT)) {
LOG_WARNING(
- "memory write caused data abort (address: 0x%8.8" PRIx32 ", size: 0x%" PRIx32 ", count: 0x%" PRIx32 ")",
+ "memory write caused data abort "
+ "(address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%" PRIx32 ", count: 0x%" PRIx32 ")",
address,
size,
count);
@@ -2471,7 +2479,7 @@ int arm7_9_write_memory(struct target *target,
}
int arm7_9_write_memory_opt(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint32_t count,
const uint8_t *buffer)
@@ -2571,7 +2579,7 @@ static const uint32_t dcc_code[] = {
};
int arm7_9_bulk_write_memory(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t count,
const uint8_t *buffer)
{
@@ -2627,7 +2635,7 @@ int arm7_9_bulk_write_memory(struct target *target,
uint32_t endaddress = buf_get_u32(reg_params[0].value, 0, 32);
if (endaddress != (address + count*4)) {
LOG_ERROR(
- "DCC write failed, expected end address 0x%08" PRIx32 " got 0x%0" PRIx32 "",
+ "DCC write failed, expected end address 0x%08" TARGET_PRIxADDR " got 0x%0" PRIx32 "",
(address + count*4),
endaddress);
retval = ERROR_FAIL;
diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h
index 5821e132b..811f9c593 100644
--- a/src/target/arm7_9_common.h
+++ b/src/target/arm7_9_common.h
@@ -22,13 +22,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM7_9_COMMON_H
-#define ARM7_9_COMMON_H
+#ifndef OPENOCD_TARGET_ARM7_9_COMMON_H
+#define OPENOCD_TARGET_ARM7_9_COMMON_H
#include "arm.h"
#include "arm_jtag.h"
@@ -124,13 +122,13 @@ struct arm7_9_common {
* Used as a fallback when bulk writes are unavailable, or for writing data needed to
* do the bulk writes.
*/
- int (*write_memory)(struct target *target, uint32_t address,
+ int (*write_memory)(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
/**
* Write target memory in multiples of 4 bytes, optimized for
* writing large quantities of data.
*/
- int (*bulk_write_memory)(struct target *target, uint32_t address,
+ int (*bulk_write_memory)(struct target *target, target_addr_t address,
uint32_t count, const uint8_t *buffer);
};
@@ -157,19 +155,19 @@ int arm7_9_early_halt(struct target *target);
int arm7_9_soft_reset_halt(struct target *target);
int arm7_9_halt(struct target *target);
-int arm7_9_resume(struct target *target, int current, uint32_t address,
+int arm7_9_resume(struct target *target, int current, target_addr_t address,
int handle_breakpoints, int debug_execution);
-int arm7_9_step(struct target *target, int current, uint32_t address,
+int arm7_9_step(struct target *target, int current, target_addr_t address,
int handle_breakpoints);
-int arm7_9_read_memory(struct target *target, uint32_t address,
+int arm7_9_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer);
-int arm7_9_write_memory(struct target *target, uint32_t address,
+int arm7_9_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
-int arm7_9_write_memory_opt(struct target *target, uint32_t address,
+int arm7_9_write_memory_opt(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
int arm7_9_write_memory_no_opt(struct target *target, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
-int arm7_9_bulk_write_memory(struct target *target, uint32_t address,
+int arm7_9_bulk_write_memory(struct target *target, target_addr_t address,
uint32_t count, const uint8_t *buffer);
int arm7_9_run_algorithm(struct target *target, int num_mem_params,
@@ -194,4 +192,4 @@ int arm7_9_endianness_callback(jtag_callback_data_t pu8_in,
jtag_callback_data_t i_size, jtag_callback_data_t i_be,
jtag_callback_data_t i_flip);
-#endif /* ARM7_9_COMMON_H */
+#endif /* OPENOCD_TARGET_ARM7_9_COMMON_H */
diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c
index 490ecfc0b..9dcb302d9 100644
--- a/src/target/arm7tdmi.c
+++ b/src/target/arm7tdmi.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -32,6 +30,7 @@
#include "target_type.h"
#include "register.h"
#include "arm_opcodes.h"
+#include "arm_semihosting.h"
/*
* For information about ARM7TDMI, see ARM DDI 0210C (r4p1)
@@ -617,7 +616,7 @@ static void arm7tdmi_build_reg_cache(struct target *target)
int arm7tdmi_init_target(struct command_context *cmd_ctx, struct target *target)
{
arm7tdmi_build_reg_cache(target);
-
+ arm_semihosting_init(target);
return ERROR_OK;
}
diff --git a/src/target/arm7tdmi.h b/src/target/arm7tdmi.h
index a44ceee53..053f64df8 100644
--- a/src/target/arm7tdmi.h
+++ b/src/target/arm7tdmi.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM7TDMI_H
-#define ARM7TDMI_H
+#ifndef OPENOCD_TARGET_ARM7TDMI_H
+#define OPENOCD_TARGET_ARM7TDMI_H
#include "embeddedice.h"
@@ -31,4 +29,4 @@ int arm7tdmi_init_arch_info(struct target *target,
int arm7tdmi_init_target(struct command_context *cmd_ctx,
struct target *target);
-#endif /* ARM7TDMI_H */
+#endif /* OPENOCD_TARGET_ARM7TDMI_H */
diff --git a/src/target/arm920t.c b/src/target/arm920t.c
index b1579bca5..7927a2bea 100644
--- a/src/target/arm920t.c
+++ b/src/target/arm920t.c
@@ -14,9 +14,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -555,7 +553,7 @@ static int arm920_mmu(struct target *target, int *enabled)
}
static int arm920_virt2phys(struct target *target,
- uint32_t virt, uint32_t *phys)
+ target_addr_t virt, target_addr_t *phys)
{
uint32_t cb;
struct arm920t_common *arm920t = target_to_arm920(target);
@@ -570,7 +568,7 @@ static int arm920_virt2phys(struct target *target,
}
/** Reads a buffer, in the specified word size, with current MMU settings. */
-int arm920t_read_memory(struct target *target, uint32_t address,
+int arm920t_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
int retval;
@@ -582,7 +580,7 @@ int arm920t_read_memory(struct target *target, uint32_t address,
static int arm920t_read_phys_memory(struct target *target,
- uint32_t address, uint32_t size,
+ target_addr_t address, uint32_t size,
uint32_t count, uint8_t *buffer)
{
struct arm920t_common *arm920t = target_to_arm920(target);
@@ -592,7 +590,7 @@ static int arm920t_read_phys_memory(struct target *target,
}
static int arm920t_write_phys_memory(struct target *target,
- uint32_t address, uint32_t size,
+ target_addr_t address, uint32_t size,
uint32_t count, const uint8_t *buffer)
{
struct arm920t_common *arm920t = target_to_arm920(target);
@@ -602,7 +600,7 @@ static int arm920t_write_phys_memory(struct target *target,
}
/** Writes a buffer, in the specified word size, with current MMU settings. */
-int arm920t_write_memory(struct target *target, uint32_t address,
+int arm920t_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
int retval;
@@ -753,8 +751,8 @@ int arm920t_soft_reset_halt(struct target *target)
if (retval != ERROR_OK)
return retval;
- long long then = timeval_ms();
- int timeout;
+ int64_t then = timeval_ms();
+ bool timeout;
while (!(timeout = ((timeval_ms()-then) > 1000))) {
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {
embeddedice_read_reg(dbg_stat);
diff --git a/src/target/arm920t.h b/src/target/arm920t.h
index 71876a69b..2e3b08ca3 100644
--- a/src/target/arm920t.h
+++ b/src/target/arm920t.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM920T_H
-#define ARM920T_H
+#ifndef OPENOCD_TARGET_ARM920T_H
+#define OPENOCD_TARGET_ARM920T_H
#include "arm9tdmi.h"
#include "armv4_5_mmu.h"
@@ -57,9 +55,9 @@ struct arm920t_tlb_entry {
int arm920t_arch_state(struct target *target);
int arm920t_soft_reset_halt(struct target *target);
int arm920t_read_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+ target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);
int arm920t_write_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
+ target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
int arm920t_post_debug_entry(struct target *target);
void arm920t_pre_restore_context(struct target *target);
int arm920t_get_ttb(struct target *target, uint32_t *result);
@@ -70,4 +68,4 @@ int arm920t_enable_mmu_caches(struct target *target,
extern const struct command_registration arm920t_command_handlers[];
-#endif /* ARM920T_H */
+#endif /* OPENOCD_TARGET_ARM920T_H */
diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c
index d8bf2d046..58de77850 100644
--- a/src/target/arm926ejs.c
+++ b/src/target/arm926ejs.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -89,7 +87,7 @@ static int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2
jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
for (;;) {
/* rescan with NOP, to wait for the access to complete */
@@ -175,7 +173,7 @@ static int arm926ejs_cp15_write(struct target *target, uint32_t op1, uint32_t op
jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
for (;;) {
/* rescan with NOP, to wait for the access to complete */
@@ -548,7 +546,7 @@ int arm926ejs_soft_reset_halt(struct target *target)
if (retval != ERROR_OK)
return retval;
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
int timeout;
while (!(timeout = ((timeval_ms()-then) > 1000))) {
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {
@@ -596,7 +594,7 @@ int arm926ejs_soft_reset_halt(struct target *target)
}
/** Writes a buffer, in the specified word size, with current MMU settings. */
-int arm926ejs_write_memory(struct target *target, uint32_t address,
+int arm926ejs_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
int retval;
@@ -625,7 +623,7 @@ int arm926ejs_write_memory(struct target *target, uint32_t address,
return retval;
}
- uint32_t pa;
+ target_addr_t pa;
retval = target->type->virt2phys(target, address, &pa);
if (retval != ERROR_OK)
return retval;
@@ -657,7 +655,7 @@ int arm926ejs_write_memory(struct target *target, uint32_t address,
}
static int arm926ejs_write_phys_memory(struct target *target,
- uint32_t address, uint32_t size,
+ target_addr_t address, uint32_t size,
uint32_t count, const uint8_t *buffer)
{
struct arm926ejs_common *arm926ejs = target_to_arm926(target);
@@ -667,7 +665,7 @@ static int arm926ejs_write_phys_memory(struct target *target,
}
static int arm926ejs_read_phys_memory(struct target *target,
- uint32_t address, uint32_t size,
+ target_addr_t address, uint32_t size,
uint32_t count, uint8_t *buffer)
{
struct arm926ejs_common *arm926ejs = target_to_arm926(target);
@@ -738,7 +736,7 @@ COMMAND_HANDLER(arm926ejs_handle_cache_info_command)
return armv4_5_handle_cache_info_command(CMD_CTX, &arm926ejs->armv4_5_mmu.armv4_5_cache);
}
-static int arm926ejs_virt2phys(struct target *target, uint32_t virtual, uint32_t *physical)
+static int arm926ejs_virt2phys(struct target *target, target_addr_t virtual, target_addr_t *physical)
{
uint32_t cb;
struct arm926ejs_common *arm926ejs = target_to_arm926(target);
diff --git a/src/target/arm926ejs.h b/src/target/arm926ejs.h
index cc19c9fc5..d4fd0cb6e 100644
--- a/src/target/arm926ejs.h
+++ b/src/target/arm926ejs.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM926EJS_H
-#define ARM926EJS_H
+#ifndef OPENOCD_TARGET_ARM926EJS_H
+#define OPENOCD_TARGET_ARM926EJS_H
#include "arm9tdmi.h"
#include "armv4_5_mmu.h"
@@ -49,9 +47,9 @@ int arm926ejs_init_arch_info(struct target *target,
struct arm926ejs_common *arm926ejs, struct jtag_tap *tap);
int arm926ejs_arch_state(struct target *target);
int arm926ejs_write_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
+ target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
int arm926ejs_soft_reset_halt(struct target *target);
extern const struct command_registration arm926ejs_command_handlers[];
-#endif /* ARM926EJS_H */
+#endif /* OPENOCD_TARGET_ARM926EJS_H */
diff --git a/src/target/arm946e.c b/src/target/arm946e.c
index c21ff95f7..06c9fc30d 100644
--- a/src/target/arm946e.c
+++ b/src/target/arm946e.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -489,7 +487,7 @@ uint32_t arm946e_invalidate_icache(struct target *target, uint32_t address,
}
/** Writes a buffer, in the specified word size, with current MMU settings. */
-int arm946e_write_memory(struct target *target, uint32_t address,
+int arm946e_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
int retval;
@@ -537,7 +535,7 @@ int arm946e_write_memory(struct target *target, uint32_t address,
}
-int arm946e_read_memory(struct target *target, uint32_t address,
+int arm946e_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
int retval;
diff --git a/src/target/arm946e.h b/src/target/arm946e.h
index fd45f05af..ee1ef3235 100644
--- a/src/target/arm946e.h
+++ b/src/target/arm946e.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM946E_H
-#define ARM946E_H
+#ifndef OPENOCD_TARGET_ARM946E_H
+#define OPENOCD_TARGET_ARM946E_H
#include "arm9tdmi.h"
@@ -50,4 +48,4 @@ int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value);
extern const struct command_registration arm946e_command_handlers[];
-#endif /* ARM946E_H */
+#endif /* OPENOCD_TARGET_ARM946E_H */
diff --git a/src/target/arm966e.c b/src/target/arm966e.c
index a174eab40..0429c54b5 100644
--- a/src/target/arm966e.c
+++ b/src/target/arm966e.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm966e.h b/src/target/arm966e.h
index e7ace9299..aa2e9bb27 100644
--- a/src/target/arm966e.h
+++ b/src/target/arm966e.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM966E_H
-#define ARM966E_H
+#ifndef OPENOCD_TARGET_ARM966E_H
+#define OPENOCD_TARGET_ARM966E_H
#include "arm9tdmi.h"
@@ -47,4 +45,4 @@ int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value);
extern const struct command_registration arm966e_command_handlers[];
-#endif /* ARM966E_H */
+#endif /* OPENOCD_TARGET_ARM966E_H */
diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c
index ca000a7fe..82b430f88 100644
--- a/src/target/arm9tdmi.c
+++ b/src/target/arm9tdmi.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -32,6 +30,7 @@
#include "target_type.h"
#include "register.h"
#include "arm_opcodes.h"
+#include "arm_semihosting.h"
/*
* NOTE: this holds code that's used with multiple ARM9 processors:
@@ -716,6 +715,7 @@ int arm9tdmi_init_target(struct command_context *cmd_ctx,
struct target *target)
{
arm9tdmi_build_reg_cache(target);
+ arm_semihosting_init(target);
return ERROR_OK;
}
diff --git a/src/target/arm9tdmi.h b/src/target/arm9tdmi.h
index 366cd1294..c6f0ccf0f 100644
--- a/src/target/arm9tdmi.h
+++ b/src/target/arm9tdmi.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM9TDMI_H
-#define ARM9TDMI_H
+#ifndef OPENOCD_TARGET_ARM9TDMI_H
+#define OPENOCD_TARGET_ARM9TDMI_H
#include "embeddedice.h"
@@ -55,4 +53,4 @@ void arm9tdmi_branch_resume(struct target *target);
void arm9tdmi_enable_single_step(struct target *target, uint32_t next_pc);
void arm9tdmi_disable_single_step(struct target *target);
-#endif /* ARM9TDMI_H */
+#endif /* OPENOCD_TARGET_ARM9TDMI_H */
diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index 6efc0af13..eafc2ddc0 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -24,9 +24,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/**
@@ -75,7 +73,9 @@
#include "jtag/interface.h"
#include "arm.h"
#include "arm_adi_v5.h"
+#include
#include
+#include
/* ARM ADI Specification requires at least 10 bits used for TAR autoincrement */
@@ -586,6 +586,7 @@ struct adiv5_dap *dap_init(void)
/* Number of bits for tar autoincrement, impl. dep. at least 10 */
dap->ap[i].tar_autoincr_block = (1<<10);
}
+ INIT_LIST_HEAD(&dap->cmd_journal);
return dap;
}
@@ -611,60 +612,58 @@ int dap_dp_init(struct adiv5_dap *dap)
dap->select = DP_SELECT_INVALID;
dap->last_read = NULL;
- for (size_t i = 0; i < 10; i++) {
+ for (size_t i = 0; i < 30; i++) {
/* DP initialization */
- retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
- if (retval != ERROR_OK)
- continue;
-
- retval = dap_queue_dp_write(dap, DP_CTRL_STAT, SSTICKYERR);
- if (retval != ERROR_OK)
- continue;
+ retval = dap_dp_read_atomic(dap, DP_CTRL_STAT, NULL);
+ if (retval == ERROR_OK)
+ break;
+ }
- retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
- if (retval != ERROR_OK)
- continue;
+ retval = dap_queue_dp_write(dap, DP_CTRL_STAT, SSTICKYERR);
+ if (retval != ERROR_OK)
+ return retval;
- dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
- retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
- if (retval != ERROR_OK)
- continue;
+ retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
+ if (retval != ERROR_OK)
+ return retval;
- /* Check that we have debug power domains activated */
- LOG_DEBUG("DAP: wait CDBGPWRUPACK");
- retval = dap_dp_poll_register(dap, DP_CTRL_STAT,
- CDBGPWRUPACK, CDBGPWRUPACK,
- DAP_POWER_DOMAIN_TIMEOUT);
- if (retval != ERROR_OK)
- continue;
+ dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
+ retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
+ if (retval != ERROR_OK)
+ return retval;
- LOG_DEBUG("DAP: wait CSYSPWRUPACK");
- retval = dap_dp_poll_register(dap, DP_CTRL_STAT,
- CSYSPWRUPACK, CSYSPWRUPACK,
- DAP_POWER_DOMAIN_TIMEOUT);
- if (retval != ERROR_OK)
- continue;
+ /* Check that we have debug power domains activated */
+ LOG_DEBUG("DAP: wait CDBGPWRUPACK");
+ retval = dap_dp_poll_register(dap, DP_CTRL_STAT,
+ CDBGPWRUPACK, CDBGPWRUPACK,
+ DAP_POWER_DOMAIN_TIMEOUT);
+ if (retval != ERROR_OK)
+ return retval;
- retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
- if (retval != ERROR_OK)
- continue;
+ LOG_DEBUG("DAP: wait CSYSPWRUPACK");
+ retval = dap_dp_poll_register(dap, DP_CTRL_STAT,
+ CSYSPWRUPACK, CSYSPWRUPACK,
+ DAP_POWER_DOMAIN_TIMEOUT);
+ if (retval != ERROR_OK)
+ return retval;
- /* With debug power on we can activate OVERRUN checking */
- dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;
- retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
- if (retval != ERROR_OK)
- continue;
- retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
- if (retval != ERROR_OK)
- continue;
+ retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
+ if (retval != ERROR_OK)
+ return retval;
- retval = dap_run(dap);
- if (retval != ERROR_OK)
- continue;
+ /* With debug power on we can activate OVERRUN checking */
+ dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;
+ retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
+ if (retval != ERROR_OK)
+ return retval;
- break;
- }
+ retval = dap_run(dap);
+ if (retval != ERROR_OK)
+ return retval;
return retval;
}
@@ -737,10 +736,9 @@ static const char *class_description[16] = {
"Generic IP component", "PrimeCell or System component"
};
-static bool is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0)
+static bool is_dap_cid_ok(uint32_t cid)
{
- return cid3 == 0xb1 && cid2 == 0x05
- && ((cid1 & 0x0f) == 0) && cid0 == 0x0d;
+ return (cid & 0xffff0fff) == 0xb105000d;
}
/*
@@ -874,6 +872,61 @@ int dap_lookup_cs_component(struct adiv5_ap *ap,
return ERROR_OK;
}
+static int dap_read_part_id(struct adiv5_ap *ap, uint32_t component_base, uint32_t *cid, uint64_t *pid)
+{
+ assert((component_base & 0xFFF) == 0);
+ assert(ap != NULL && cid != NULL && pid != NULL);
+
+ uint32_t cid0, cid1, cid2, cid3;
+ uint32_t pid0, pid1, pid2, pid3, pid4;
+ int retval;
+
+ /* IDs are in last 4K section */
+ retval = mem_ap_read_u32(ap, component_base + 0xFE0, &pid0);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(ap, component_base + 0xFE4, &pid1);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(ap, component_base + 0xFE8, &pid2);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(ap, component_base + 0xFEC, &pid3);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(ap, component_base + 0xFD0, &pid4);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(ap, component_base + 0xFF0, &cid0);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(ap, component_base + 0xFF4, &cid1);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(ap, component_base + 0xFF8, &cid2);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(ap, component_base + 0xFFC, &cid3);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = dap_run(ap->dap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ *cid = (cid3 & 0xff) << 24
+ | (cid2 & 0xff) << 16
+ | (cid1 & 0xff) << 8
+ | (cid0 & 0xff);
+ *pid = (uint64_t)(pid4 & 0xff) << 32
+ | (pid3 & 0xff) << 24
+ | (pid2 & 0xff) << 16
+ | (pid1 & 0xff) << 8
+ | (pid0 & 0xff);
+
+ return ERROR_OK;
+}
+
/* The designer identity code is encoded as:
* bits 11:8 : JEP106 Bank (number of continuation codes), only valid when bit 7 is 1.
* bit 7 : Set when bits 6:0 represent a JEP106 ID and cleared when bits 6:0 represent
@@ -905,62 +958,101 @@ static const struct {
const char *type;
const char *full;
} dap_partnums[] = {
- { ARM_ID, 0x000, "Cortex-M3 SCS", "(System Control Space)", },
- { ARM_ID, 0x001, "Cortex-M3 ITM", "(Instrumentation Trace Module)", },
- { ARM_ID, 0x002, "Cortex-M3 DWT", "(Data Watchpoint and Trace)", },
- { ARM_ID, 0x003, "Cortex-M3 FBP", "(Flash Patch and Breakpoint)", },
- { ARM_ID, 0x008, "Cortex-M0 SCS", "(System Control Space)", },
- { ARM_ID, 0x00a, "Cortex-M0 DWT", "(Data Watchpoint and Trace)", },
- { ARM_ID, 0x00b, "Cortex-M0 BPU", "(Breakpoint Unit)", },
- { ARM_ID, 0x00c, "Cortex-M4 SCS", "(System Control Space)", },
- { ARM_ID, 0x00d, "CoreSight ETM11", "(Embedded Trace)", },
- { ARM_ID, 0x490, "Cortex-A15 GIC", "(Generic Interrupt Controller)", },
- { ARM_ID, 0x4c7, "Cortex-M7 PPB", "(Private Peripheral Bus ROM Table)", },
- { ARM_ID, 0x906, "CoreSight CTI", "(Cross Trigger)", },
- { ARM_ID, 0x907, "CoreSight ETB", "(Trace Buffer)", },
- { ARM_ID, 0x908, "CoreSight CSTF", "(Trace Funnel)", },
- { ARM_ID, 0x910, "CoreSight ETM9", "(Embedded Trace)", },
- { ARM_ID, 0x912, "CoreSight TPIU", "(Trace Port Interface Unit)", },
- { ARM_ID, 0x913, "CoreSight ITM", "(Instrumentation Trace Macrocell)", },
- { ARM_ID, 0x914, "CoreSight SWO", "(Single Wire Output)", },
- { ARM_ID, 0x917, "CoreSight HTM", "(AHB Trace Macrocell)", },
- { ARM_ID, 0x920, "CoreSight ETM11", "(Embedded Trace)", },
- { ARM_ID, 0x921, "Cortex-A8 ETM", "(Embedded Trace)", },
- { ARM_ID, 0x922, "Cortex-A8 CTI", "(Cross Trigger)", },
- { ARM_ID, 0x923, "Cortex-M3 TPIU", "(Trace Port Interface Unit)", },
- { ARM_ID, 0x924, "Cortex-M3 ETM", "(Embedded Trace)", },
- { ARM_ID, 0x925, "Cortex-M4 ETM", "(Embedded Trace)", },
- { ARM_ID, 0x930, "Cortex-R4 ETM", "(Embedded Trace)", },
- { ARM_ID, 0x941, "CoreSight TPIU-Lite", "(Trace Port Interface Unit)", },
- { ARM_ID, 0x950, "CoreSight Component", "(unidentified Cortex-A9 component)", },
- { ARM_ID, 0x955, "CoreSight Component", "(unidentified Cortex-A5 component)", },
- { ARM_ID, 0x95f, "Cortex-A15 PTM", "(Program Trace Macrocell)", },
- { ARM_ID, 0x961, "CoreSight TMC", "(Trace Memory Controller)", },
- { ARM_ID, 0x962, "CoreSight STM", "(System Trace Macrocell)", },
- { ARM_ID, 0x9a0, "CoreSight PMU", "(Performance Monitoring Unit)", },
- { ARM_ID, 0x9a1, "Cortex-M4 TPIU", "(Trace Port Interface Unit)", },
- { ARM_ID, 0x9a5, "Cortex-A5 ETM", "(Embedded Trace)", },
- { ARM_ID, 0x9a7, "Cortex-A7 PMU", "(Performance Monitor Unit)", },
- { ARM_ID, 0x9af, "Cortex-A15 PMU", "(Performance Monitor Unit)", },
- { ARM_ID, 0xc05, "Cortex-A5 Debug", "(Debug Unit)", },
- { ARM_ID, 0xc07, "Cortex-A7 Debug", "(Debug Unit)", },
- { ARM_ID, 0xc08, "Cortex-A8 Debug", "(Debug Unit)", },
- { ARM_ID, 0xc09, "Cortex-A9 Debug", "(Debug Unit)", },
- { ARM_ID, 0xc0f, "Cortex-A15 Debug", "(Debug Unit)", },
- { ARM_ID, 0xc14, "Cortex-R4 Debug", "(Debug Unit)", },
- { 0x0E5, 0x000, "SHARC+/Blackfin+", "", },
+ { ARM_ID, 0x000, "Cortex-M3 SCS", "(System Control Space)", },
+ { ARM_ID, 0x001, "Cortex-M3 ITM", "(Instrumentation Trace Module)", },
+ { ARM_ID, 0x002, "Cortex-M3 DWT", "(Data Watchpoint and Trace)", },
+ { ARM_ID, 0x003, "Cortex-M3 FPB", "(Flash Patch and Breakpoint)", },
+ { ARM_ID, 0x008, "Cortex-M0 SCS", "(System Control Space)", },
+ { ARM_ID, 0x00a, "Cortex-M0 DWT", "(Data Watchpoint and Trace)", },
+ { ARM_ID, 0x00b, "Cortex-M0 BPU", "(Breakpoint Unit)", },
+ { ARM_ID, 0x00c, "Cortex-M4 SCS", "(System Control Space)", },
+ { ARM_ID, 0x00d, "CoreSight ETM11", "(Embedded Trace)", },
+ { ARM_ID, 0x00e, "Cortex-M7 FPB", "(Flash Patch and Breakpoint)", },
+ { ARM_ID, 0x490, "Cortex-A15 GIC", "(Generic Interrupt Controller)", },
+ { ARM_ID, 0x4a1, "Cortex-A53 ROM", "(v8 Memory Map ROM Table)", },
+ { ARM_ID, 0x4a2, "Cortex-A57 ROM", "(ROM Table)", },
+ { ARM_ID, 0x4a3, "Cortex-A53 ROM", "(v7 Memory Map ROM Table)", },
+ { ARM_ID, 0x4a4, "Cortex-A72 ROM", "(ROM Table)", },
+ { ARM_ID, 0x4af, "Cortex-A15 ROM", "(ROM Table)", },
+ { ARM_ID, 0x4c0, "Cortex-M0+ ROM", "(ROM Table)", },
+ { ARM_ID, 0x4c3, "Cortex-M3 ROM", "(ROM Table)", },
+ { ARM_ID, 0x4c4, "Cortex-M4 ROM", "(ROM Table)", },
+ { ARM_ID, 0x4c7, "Cortex-M7 PPB ROM", "(Private Peripheral Bus ROM Table)", },
+ { ARM_ID, 0x4c8, "Cortex-M7 ROM", "(ROM Table)", },
+ { ARM_ID, 0x470, "Cortex-M1 ROM", "(ROM Table)", },
+ { ARM_ID, 0x471, "Cortex-M0 ROM", "(ROM Table)", },
+ { ARM_ID, 0x906, "CoreSight CTI", "(Cross Trigger)", },
+ { ARM_ID, 0x907, "CoreSight ETB", "(Trace Buffer)", },
+ { ARM_ID, 0x908, "CoreSight CSTF", "(Trace Funnel)", },
+ { ARM_ID, 0x909, "CoreSight ATBR", "(Advanced Trace Bus Replicator)", },
+ { ARM_ID, 0x910, "CoreSight ETM9", "(Embedded Trace)", },
+ { ARM_ID, 0x912, "CoreSight TPIU", "(Trace Port Interface Unit)", },
+ { ARM_ID, 0x913, "CoreSight ITM", "(Instrumentation Trace Macrocell)", },
+ { ARM_ID, 0x914, "CoreSight SWO", "(Single Wire Output)", },
+ { ARM_ID, 0x917, "CoreSight HTM", "(AHB Trace Macrocell)", },
+ { ARM_ID, 0x920, "CoreSight ETM11", "(Embedded Trace)", },
+ { ARM_ID, 0x921, "Cortex-A8 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x922, "Cortex-A8 CTI", "(Cross Trigger)", },
+ { ARM_ID, 0x923, "Cortex-M3 TPIU", "(Trace Port Interface Unit)", },
+ { ARM_ID, 0x924, "Cortex-M3 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x925, "Cortex-M4 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x930, "Cortex-R4 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x931, "Cortex-R5 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x932, "CoreSight MTB-M0+", "(Micro Trace Buffer)", },
+ { ARM_ID, 0x941, "CoreSight TPIU-Lite", "(Trace Port Interface Unit)", },
+ { ARM_ID, 0x950, "Cortex-A9 PTM", "(Program Trace Macrocell)", },
+ { ARM_ID, 0x955, "Cortex-A5 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x95a, "Cortex-A72 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x95b, "Cortex-A17 PTM", "(Program Trace Macrocell)", },
+ { ARM_ID, 0x95d, "Cortex-A53 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x95e, "Cortex-A57 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x95f, "Cortex-A15 PTM", "(Program Trace Macrocell)", },
+ { ARM_ID, 0x961, "CoreSight TMC", "(Trace Memory Controller)", },
+ { ARM_ID, 0x962, "CoreSight STM", "(System Trace Macrocell)", },
+ { ARM_ID, 0x975, "Cortex-M7 ETM", "(Embedded Trace)", },
+ { ARM_ID, 0x9a0, "CoreSight PMU", "(Performance Monitoring Unit)", },
+ { ARM_ID, 0x9a1, "Cortex-M4 TPIU", "(Trace Port Interface Unit)", },
+ { ARM_ID, 0x9a4, "CoreSight GPR", "(Granular Power Requester)", },
+ { ARM_ID, 0x9a5, "Cortex-A5 PMU", "(Performance Monitor Unit)", },
+ { ARM_ID, 0x9a7, "Cortex-A7 PMU", "(Performance Monitor Unit)", },
+ { ARM_ID, 0x9a8, "Cortex-A53 CTI", "(Cross Trigger)", },
+ { ARM_ID, 0x9a9, "Cortex-M7 TPIU", "(Trace Port Interface Unit)", },
+ { ARM_ID, 0x9ae, "Cortex-A17 PMU", "(Performance Monitor Unit)", },
+ { ARM_ID, 0x9af, "Cortex-A15 PMU", "(Performance Monitor Unit)", },
+ { ARM_ID, 0x9b7, "Cortex-R7 PMU", "(Performance Monitoring Unit)", },
+ { ARM_ID, 0x9d3, "Cortex-A53 PMU", "(Performance Monitor Unit)", },
+ { ARM_ID, 0x9d7, "Cortex-A57 PMU", "(Performance Monitor Unit)", },
+ { ARM_ID, 0x9d8, "Cortex-A72 PMU", "(Performance Monitor Unit)", },
+ { ARM_ID, 0xc05, "Cortex-A5 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xc07, "Cortex-A7 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xc08, "Cortex-A8 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xc09, "Cortex-A9 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xc0e, "Cortex-A17 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xc0f, "Cortex-A15 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xc14, "Cortex-R4 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xc15, "Cortex-R5 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xc17, "Cortex-R7 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xd03, "Cortex-A53 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xd07, "Cortex-A57 Debug", "(Debug Unit)", },
+ { ARM_ID, 0xd08, "Cortex-A72 Debug", "(Debug Unit)", },
+ { 0x097, 0x9af, "MSP432 ROM", "(ROM Table)" },
+ { 0x09f, 0xcd0, "Atmel CPU with DSU", "(CPU)" },
+ { 0x0c1, 0x1db, "XMC4500 ROM", "(ROM Table)" },
+ { 0x0c1, 0x1df, "XMC4700/4800 ROM", "(ROM Table)" },
+ { 0x0c1, 0x1ed, "XMC1000 ROM", "(ROM Table)" },
+ { 0x0E5, 0x000, "SHARC+/Blackfin+", "", },
+ { 0x0F0, 0x440, "Qualcomm QDSS Component v1", "(Qualcomm Designed CoreSight Component v1)", },
/* legacy comment: 0x113: what? */
- { ANY_ID, 0x120, "TI SDTI", "(System Debug Trace Interface)", }, /* from OMAP3 memmap */
- { ANY_ID, 0x343, "TI DAPCTL", "", }, /* from OMAP3 memmap */
+ { ANY_ID, 0x120, "TI SDTI", "(System Debug Trace Interface)", }, /* from OMAP3 memmap */
+ { ANY_ID, 0x343, "TI DAPCTL", "", }, /* from OMAP3 memmap */
};
static int dap_rom_display(struct command_context *cmd_ctx,
struct adiv5_ap *ap, uint32_t dbgbase, int depth)
{
- struct adiv5_dap *dap = ap->dap;
int retval;
- uint32_t cid0, cid1, cid2, cid3, memtype, romentry;
- uint16_t entry_offset;
+ uint64_t pid;
+ uint32_t cid;
char tabs[7] = "";
if (depth > 16) {
@@ -971,330 +1063,241 @@ static int dap_rom_display(struct command_context *cmd_ctx,
if (depth)
snprintf(tabs, sizeof(tabs), "[L%02d] ", depth);
- /* bit 16 of apid indicates a memory access port */
- if (dbgbase & 0x02)
- command_print(cmd_ctx, "\t%sValid ROM table present", tabs);
- else
- command_print(cmd_ctx, "\t%sROM table in legacy format", tabs);
+ uint32_t base_addr = dbgbase & 0xFFFFF000;
+ command_print(cmd_ctx, "\t\tComponent base address 0x%08" PRIx32, base_addr);
- /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
- retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
- if (retval != ERROR_OK)
- return retval;
- retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFF4, &cid1);
- if (retval != ERROR_OK)
- return retval;
- retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFF8, &cid2);
- if (retval != ERROR_OK)
- return retval;
- retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFFC, &cid3);
- if (retval != ERROR_OK)
- return retval;
- retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFCC, &memtype);
- if (retval != ERROR_OK)
- return retval;
- retval = dap_run(dap);
- if (retval != ERROR_OK)
- return retval;
+ retval = dap_read_part_id(ap, base_addr, &cid, &pid);
+ if (retval != ERROR_OK) {
+ command_print(cmd_ctx, "\t\tCan't read component, the corresponding core might be turned off");
+ return ERROR_OK; /* Don't abort recursion */
+ }
- if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
- command_print(cmd_ctx, "\t%sCID3 0x%02x"
- ", CID2 0x%02x"
- ", CID1 0x%02x"
- ", CID0 0x%02x",
- tabs,
- (unsigned)cid3, (unsigned)cid2,
- (unsigned)cid1, (unsigned)cid0);
- if (memtype & 0x01)
- command_print(cmd_ctx, "\t%sMEMTYPE system memory present on bus", tabs);
- else
- command_print(cmd_ctx, "\t%sMEMTYPE system memory not present: dedicated debug bus", tabs);
+ if (!is_dap_cid_ok(cid)) {
+ command_print(cmd_ctx, "\t\tInvalid CID 0x%08" PRIx32, cid);
+ return ERROR_OK; /* Don't abort recursion */
+ }
+
+ /* component may take multiple 4K pages */
+ uint32_t size = (pid >> 36) & 0xf;
+ if (size > 0)
+ command_print(cmd_ctx, "\t\tStart address 0x%08" PRIx32, (uint32_t)(base_addr - 0x1000 * size));
- /* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
- for (entry_offset = 0; ; entry_offset += 4) {
- retval = mem_ap_read_atomic_u32(ap, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
+ command_print(cmd_ctx, "\t\tPeripheral ID 0x%010" PRIx64, pid);
+
+ uint8_t class = (cid >> 12) & 0xf;
+ uint16_t part_num = pid & 0xfff;
+ uint16_t designer_id = ((pid >> 32) & 0xf) << 8 | ((pid >> 12) & 0xff);
+
+ if (designer_id & 0x80) {
+ /* JEP106 code */
+ command_print(cmd_ctx, "\t\tDesigner is 0x%03" PRIx16 ", %s",
+ designer_id, jep106_manufacturer(designer_id >> 8, designer_id & 0x7f));
+ } else {
+ /* Legacy ASCII ID, clear invalid bits */
+ designer_id &= 0x7f;
+ command_print(cmd_ctx, "\t\tDesigner ASCII code 0x%02" PRIx16 ", %s",
+ designer_id, designer_id == 0x41 ? "ARM" : "");
+ }
+
+ /* default values to be overwritten upon finding a match */
+ const char *type = "Unrecognized";
+ const char *full = "";
+
+ /* search dap_partnums[] array for a match */
+ for (unsigned entry = 0; entry < ARRAY_SIZE(dap_partnums); entry++) {
+
+ if ((dap_partnums[entry].designer_id != designer_id) && (dap_partnums[entry].designer_id != ANY_ID))
+ continue;
+
+ if (dap_partnums[entry].part_num != part_num)
+ continue;
+
+ type = dap_partnums[entry].type;
+ full = dap_partnums[entry].full;
+ break;
+ }
+
+ command_print(cmd_ctx, "\t\tPart is 0x%" PRIx16", %s %s", part_num, type, full);
+ command_print(cmd_ctx, "\t\tComponent class is 0x%" PRIx8 ", %s", class, class_description[class]);
+
+ if (class == 1) { /* ROM Table */
+ uint32_t memtype;
+ retval = mem_ap_read_atomic_u32(ap, base_addr | 0xFCC, &memtype);
if (retval != ERROR_OK)
return retval;
- command_print(cmd_ctx, "\t%sROMTABLE[0x%x] = 0x%" PRIx32 "",
- tabs, entry_offset, romentry);
- if (romentry & 0x01) {
- uint32_t c_cid0, c_cid1, c_cid2, c_cid3;
- uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4;
- uint32_t component_base;
- uint16_t part_num, designer_id;
- const char *type, *full;
-
- component_base = (dbgbase & 0xFFFFF000) + (romentry & 0xFFFFF000);
-
- /* IDs are in last 4K section */
- retval = mem_ap_read_atomic_u32(ap, component_base + 0xFE0, &c_pid0);
- if (retval != ERROR_OK) {
- command_print(cmd_ctx, "\t%s\tCan't read component with base address 0x%" PRIx32
- ", the corresponding core might be turned off", tabs, component_base);
- continue;
- }
- c_pid0 &= 0xff;
- retval = mem_ap_read_atomic_u32(ap, component_base + 0xFE4, &c_pid1);
- if (retval != ERROR_OK)
- return retval;
- c_pid1 &= 0xff;
- retval = mem_ap_read_atomic_u32(ap, component_base + 0xFE8, &c_pid2);
- if (retval != ERROR_OK)
- return retval;
- c_pid2 &= 0xff;
- retval = mem_ap_read_atomic_u32(ap, component_base + 0xFEC, &c_pid3);
- if (retval != ERROR_OK)
- return retval;
- c_pid3 &= 0xff;
- retval = mem_ap_read_atomic_u32(ap, component_base + 0xFD0, &c_pid4);
- if (retval != ERROR_OK)
- return retval;
- c_pid4 &= 0xff;
- retval = mem_ap_read_atomic_u32(ap, component_base + 0xFF0, &c_cid0);
- if (retval != ERROR_OK)
- return retval;
- c_cid0 &= 0xff;
- retval = mem_ap_read_atomic_u32(ap, component_base + 0xFF4, &c_cid1);
- if (retval != ERROR_OK)
- return retval;
- c_cid1 &= 0xff;
- retval = mem_ap_read_atomic_u32(ap, component_base + 0xFF8, &c_cid2);
- if (retval != ERROR_OK)
- return retval;
- c_cid2 &= 0xff;
- retval = mem_ap_read_atomic_u32(ap, component_base + 0xFFC, &c_cid3);
+ if (memtype & 0x01)
+ command_print(cmd_ctx, "\t\tMEMTYPE system memory present on bus");
+ else
+ command_print(cmd_ctx, "\t\tMEMTYPE system memory not present: dedicated debug bus");
+
+ /* Read ROM table entries from base address until we get 0x00000000 or reach the reserved area */
+ for (uint16_t entry_offset = 0; entry_offset < 0xF00; entry_offset += 4) {
+ uint32_t romentry;
+ retval = mem_ap_read_atomic_u32(ap, base_addr | entry_offset, &romentry);
if (retval != ERROR_OK)
return retval;
- c_cid3 &= 0xff;
-
- command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32 ", "
- "start address 0x%" PRIx32, component_base,
- /* component may take multiple 4K pages */
- (uint32_t)(component_base - 0x1000*(c_pid4 >> 4)));
- command_print(cmd_ctx, "\t\tComponent class is 0x%" PRIx8 ", %s",
- (uint8_t)((c_cid1 >> 4) & 0xf),
- /* See ARM IHI 0029B Table 3-3 */
- class_description[(c_cid1 >> 4) & 0xf]);
-
- /* CoreSight component? */
- if (((c_cid1 >> 4) & 0x0f) == 9) {
- uint32_t devtype;
- unsigned minor;
- const char *major = "Reserved", *subtype = "Reserved";
-
- retval = mem_ap_read_atomic_u32(ap,
- (component_base & 0xfffff000) | 0xfcc,
- &devtype);
+ command_print(cmd_ctx, "\t%sROMTABLE[0x%x] = 0x%" PRIx32 "",
+ tabs, entry_offset, romentry);
+ if (romentry & 0x01) {
+ /* Recurse */
+ retval = dap_rom_display(cmd_ctx, ap, base_addr + (romentry & 0xFFFFF000), depth + 1);
if (retval != ERROR_OK)
return retval;
- minor = (devtype >> 4) & 0x0f;
- switch (devtype & 0x0f) {
- case 0:
- major = "Miscellaneous";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 4:
- subtype = "Validation component";
- break;
- }
- break;
- case 1:
- major = "Trace Sink";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Port";
- break;
- case 2:
- subtype = "Buffer";
- break;
- case 3:
- subtype = "Router";
- break;
- }
- break;
- case 2:
- major = "Trace Link";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Funnel, router";
- break;
- case 2:
- subtype = "Filter";
- break;
- case 3:
- subtype = "FIFO, buffer";
- break;
- }
- break;
- case 3:
- major = "Trace Source";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Processor";
- break;
- case 2:
- subtype = "DSP";
- break;
- case 3:
- subtype = "Engine/Coprocessor";
- break;
- case 4:
- subtype = "Bus";
- break;
- case 6:
- subtype = "Software";
- break;
- }
- break;
- case 4:
- major = "Debug Control";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Trigger Matrix";
- break;
- case 2:
- subtype = "Debug Auth";
- break;
- case 3:
- subtype = "Power Requestor";
- break;
- }
- break;
- case 5:
- major = "Debug Logic";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Processor";
- break;
- case 2:
- subtype = "DSP";
- break;
- case 3:
- subtype = "Engine/Coprocessor";
- break;
- case 4:
- subtype = "Bus";
- break;
- case 5:
- subtype = "Memory";
- break;
- }
- break;
- case 6:
- major = "Perfomance Monitor";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Processor";
- break;
- case 2:
- subtype = "DSP";
- break;
- case 3:
- subtype = "Engine/Coprocessor";
- break;
- case 4:
- subtype = "Bus";
- break;
- case 5:
- subtype = "Memory";
- break;
- }
- break;
- }
- command_print(cmd_ctx, "\t\tType is 0x%02" PRIx8 ", %s, %s",
- (uint8_t)(devtype & 0xff),
- major, subtype);
- /* REVISIT also show 0xfc8 DevId */
+ } else if (romentry != 0) {
+ command_print(cmd_ctx, "\t\tComponent not present");
+ } else {
+ command_print(cmd_ctx, "\t%s\tEnd of ROM table", tabs);
+ break;
}
+ }
+ } else if (class == 9) { /* CoreSight component */
+ const char *major = "Reserved", *subtype = "Reserved";
- if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
- command_print(cmd_ctx,
- "\t\tCID3 0%02x"
- ", CID2 0%02x"
- ", CID1 0%02x"
- ", CID0 0%02x",
- (int)c_cid3,
- (int)c_cid2,
- (int)c_cid1,
- (int)c_cid0);
- command_print(cmd_ctx,
- "\t\tPeripheral ID[4..0] = hex "
- "%02x %02x %02x %02x %02x",
- (int)c_pid4, (int)c_pid3, (int)c_pid2,
- (int)c_pid1, (int)c_pid0);
-
- part_num = (c_pid0 & 0xff);
- part_num |= (c_pid1 & 0x0f) << 8;
- designer_id = (c_pid1 & 0xf0) >> 4;
- designer_id |= (c_pid2 & 0x0f) << 4;
- designer_id |= (c_pid4 & 0x0f) << 8;
- if ((designer_id & 0x80) == 0) {
- /* Legacy ASCII ID, clear invalid bits */
- designer_id &= 0x7f;
+ uint32_t devtype;
+ retval = mem_ap_read_atomic_u32(ap, base_addr | 0xFCC, &devtype);
+ if (retval != ERROR_OK)
+ return retval;
+ unsigned minor = (devtype >> 4) & 0x0f;
+ switch (devtype & 0x0f) {
+ case 0:
+ major = "Miscellaneous";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 4:
+ subtype = "Validation component";
+ break;
}
-
- /* default values to be overwritten upon finding a match */
- type = NULL;
- full = "";
-
- /* search dap_partnums[] array for a match */
- unsigned entry;
- for (entry = 0; entry < ARRAY_SIZE(dap_partnums); entry++) {
-
- if ((dap_partnums[entry].designer_id != designer_id) && (dap_partnums[entry].designer_id != ANY_ID))
- continue;
-
- if (dap_partnums[entry].part_num != part_num)
- continue;
-
- type = dap_partnums[entry].type;
- full = dap_partnums[entry].full;
+ break;
+ case 1:
+ major = "Trace Sink";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Port";
+ break;
+ case 2:
+ subtype = "Buffer";
+ break;
+ case 3:
+ subtype = "Router";
break;
}
-
- if (type) {
- command_print(cmd_ctx, "\t\tPart is %s %s",
- type, full);
- } else {
- command_print(cmd_ctx, "\t\tUnrecognized (Part 0x%" PRIx16 ", designer 0x%" PRIx16 ")",
- part_num, designer_id);
+ break;
+ case 2:
+ major = "Trace Link";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Funnel, router";
+ break;
+ case 2:
+ subtype = "Filter";
+ break;
+ case 3:
+ subtype = "FIFO, buffer";
+ break;
}
-
- /* ROM Table? */
- if (((c_cid1 >> 4) & 0x0f) == 1) {
- retval = dap_rom_display(cmd_ctx, ap, component_base, depth + 1);
- if (retval != ERROR_OK)
- return retval;
+ break;
+ case 3:
+ major = "Trace Source";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Processor";
+ break;
+ case 2:
+ subtype = "DSP";
+ break;
+ case 3:
+ subtype = "Engine/Coprocessor";
+ break;
+ case 4:
+ subtype = "Bus";
+ break;
+ case 6:
+ subtype = "Software";
+ break;
}
- } else {
- if (romentry)
- command_print(cmd_ctx, "\t\tComponent not present");
- else
+ break;
+ case 4:
+ major = "Debug Control";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Trigger Matrix";
+ break;
+ case 2:
+ subtype = "Debug Auth";
+ break;
+ case 3:
+ subtype = "Power Requestor";
break;
+ }
+ break;
+ case 5:
+ major = "Debug Logic";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Processor";
+ break;
+ case 2:
+ subtype = "DSP";
+ break;
+ case 3:
+ subtype = "Engine/Coprocessor";
+ break;
+ case 4:
+ subtype = "Bus";
+ break;
+ case 5:
+ subtype = "Memory";
+ break;
+ }
+ break;
+ case 6:
+ major = "Perfomance Monitor";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Processor";
+ break;
+ case 2:
+ subtype = "DSP";
+ break;
+ case 3:
+ subtype = "Engine/Coprocessor";
+ break;
+ case 4:
+ subtype = "Bus";
+ break;
+ case 5:
+ subtype = "Memory";
+ break;
+ }
+ break;
}
+ command_print(cmd_ctx, "\t\tType is 0x%02" PRIx8 ", %s, %s",
+ (uint8_t)(devtype & 0xff),
+ major, subtype);
+ /* REVISIT also show 0xfc8 DevId */
}
- command_print(cmd_ctx, "\t%s\tEnd of ROM table", tabs);
+
return ERROR_OK;
}
@@ -1303,7 +1306,6 @@ static int dap_info_command(struct command_context *cmd_ctx,
{
int retval;
uint32_t dbgbase, apid;
- int romtable_present = 0;
uint8_t mem_ap;
/* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
@@ -1342,16 +1344,56 @@ static int dap_info_command(struct command_context *cmd_ctx,
if (mem_ap) {
command_print(cmd_ctx, "MEM-AP BASE 0x%8.8" PRIx32, dbgbase);
- romtable_present = dbgbase != 0xFFFFFFFF;
- if (romtable_present)
- dap_rom_display(cmd_ctx, ap, dbgbase, 0);
- else
+ if (dbgbase == 0xFFFFFFFF || (dbgbase & 0x3) == 0x2) {
command_print(cmd_ctx, "\tNo ROM table present");
+ } else {
+ if (dbgbase & 0x01)
+ command_print(cmd_ctx, "\tValid ROM table present");
+ else
+ command_print(cmd_ctx, "\tROM table in legacy format");
+
+ dap_rom_display(cmd_ctx, ap, dbgbase & 0xFFFFF000, 0);
+ }
}
return ERROR_OK;
}
+int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi)
+{
+ struct adiv5_private_config *pc;
+ const char *arg;
+ jim_wide ap_num;
+ int e;
+
+ /* check if argv[0] is for us */
+ arg = Jim_GetString(goi->argv[0], NULL);
+ if (strcmp(arg, "-ap-num"))
+ return JIM_CONTINUE;
+
+ e = Jim_GetOpt_String(goi, &arg, NULL);
+ if (e != JIM_OK)
+ return e;
+
+ if (goi->argc == 0) {
+ Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-ap-num ?ap-number? ...");
+ return JIM_ERR;
+ }
+
+ e = Jim_GetOpt_Wide(goi, &ap_num);
+ if (e != JIM_OK)
+ return e;
+
+ if (target->private_config == NULL) {
+ pc = calloc(1, sizeof(struct adiv5_private_config));
+ target->private_config = pc;
+ pc->ap_num = ap_num;
+ }
+
+
+ return JIM_OK;
+}
+
COMMAND_HANDLER(handle_dap_info_command)
{
struct target *target = get_current_target(CMD_CTX);
@@ -1547,6 +1589,45 @@ COMMAND_HANDLER(dap_apid_command)
return retval;
}
+COMMAND_HANDLER(dap_apreg_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, 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 >= 256)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg);
+ if (reg >= 256 || (reg & 3))
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (CMD_ARGC == 3) {
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
+ retval = dap_queue_ap_write(dap_ap(dap, apsel), reg, value);
+ } else {
+ retval = dap_queue_ap_read(dap_ap(dap, apsel), reg, &value);
+ }
+ if (retval == ERROR_OK)
+ retval = dap_run(dap);
+
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (CMD_ARGC == 2)
+ command_print(CMD_CTX, "0x%08" PRIx32, value);
+
+ return retval;
+}
+
COMMAND_HANDLER(dap_ti_be_32_quirks_command)
{
struct target *target = get_current_target(CMD_CTX);
@@ -1606,6 +1687,14 @@ static const struct command_registration dap_commands[] = {
"(default currently selected AP)",
.usage = "[ap_num]",
},
+ {
+ .name = "apreg",
+ .handler = dap_apreg_command,
+ .mode = COMMAND_EXEC,
+ .help = "read/write a register from AP "
+ "(reg is byte address of a word register, like 0 4 8...)",
+ .usage = "ap_num reg [value]",
+ },
{
.name = "baseaddr",
.handler = dap_baseaddr_command,
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index fed25ec2e..bf9cb5cce 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM_ADI_V5_H
-#define ARM_ADI_V5_H
+#ifndef OPENOCD_TARGET_ARM_ADI_V5_H
+#define OPENOCD_TARGET_ARM_ADI_V5_H
/**
* @file
@@ -31,14 +29,9 @@
* resources accessed through a MEM-AP.
*/
+#include
#include "arm_jtag.h"
-/* FIXME remove these JTAG-specific decls when mem_ap_read_buf_u32()
- * is no longer JTAG-specific
- */
-#define JTAG_DP_DPACC 0xA
-#define JTAG_DP_APACC 0xB
-
/* three-bit ACK values for SWD access (sent LSB first) */
#define SWD_ACK_OK 0x1
#define SWD_ACK_WAIT 0x2
@@ -52,18 +45,21 @@
/* A[3:0] for DP registers; A[1:0] are always zero.
* - JTAG accesses all of these via JTAG_DP_DPACC, except for
* IDCODE (JTAG_DP_IDCODE) and ABORT (JTAG_DP_ABORT).
- * - SWD accesses these directly, sometimes needing SELECT.CTRLSEL
+ * - SWD accesses these directly, sometimes needing SELECT.DPBANKSEL
*/
-#define DP_IDCODE BANK_REG(0x0, 0x0) /* SWD: read */
-#define DP_ABORT BANK_REG(0x0, 0x0) /* SWD: write */
-#define DP_CTRL_STAT BANK_REG(0x0, 0x4) /* r/w */
-#define DP_RESEND BANK_REG(0x0, 0x8) /* SWD: read */
-#define DP_SELECT BANK_REG(0x0, 0x8) /* JTAG: r/w; SWD: write */
-#define DP_RDBUFF BANK_REG(0x0, 0xC) /* read-only */
-#define DP_WCR BANK_REG(0x1, 0x4) /* SWD: r/w */
-
-#define WCR_TO_TRN(wcr) ((uint32_t)(1 + (3 & ((wcr)) >> 8))) /* 1..4 clocks */
-#define WCR_TO_PRESCALE(wcr) ((uint32_t)(7 & ((wcr)))) /* impl defined */
+#define DP_DPIDR BANK_REG(0x0, 0x0) /* DPv1+: ro */
+#define DP_ABORT BANK_REG(0x0, 0x0) /* DPv1+: SWD: wo */
+#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_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 */
+#define DP_TARGETSEL BANK_REG(0x0, 0xC) /* DPv2: SWD: wo */
+
+#define DLCR_TO_TRN(dlcr) ((uint32_t)(1 + ((3 & (dlcr)) >> 8))) /* 1..4 clocks */
/* Fields of the DP's AP ABORT register */
#define DAPABORT (1UL << 0)
@@ -206,6 +202,9 @@ struct adiv5_ap {
struct adiv5_dap {
const struct dap_ops *ops;
+ /* dap transaction list for WAIT support */
+ struct list_head cmd_journal;
+
struct jtag_tap *tap;
/* Control config */
uint32_t dp_ctrl_stat;
@@ -270,6 +269,10 @@ struct dap_ops {
/** Executes all queued DAP operations. */
int (*run)(struct adiv5_dap *dap);
+
+ /** Executes all queued DAP operations but doesn't check
+ * sticky error conditions */
+ int (*sync)(struct adiv5_dap *dap);
};
/*
@@ -393,6 +396,14 @@ static inline int dap_run(struct adiv5_dap *dap)
return dap->ops->run(dap);
}
+static inline int dap_sync(struct adiv5_dap *dap)
+{
+ assert(dap->ops != NULL);
+ if (dap->ops->sync)
+ return dap->ops->sync(dap);
+ return ERROR_OK;
+}
+
static inline int dap_dp_read_atomic(struct adiv5_dap *dap, unsigned reg,
uint32_t *value)
{
@@ -493,4 +504,10 @@ int dap_to_jtag(struct target *target);
extern const struct command_registration dap_command_handlers[];
-#endif
+struct adiv5_private_config {
+ int ap_num;
+};
+
+extern int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi);
+
+#endif /* OPENOCD_TARGET_ARM_ADI_V5_H */
diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c
index 65086c2fd..5277b94d8 100644
--- a/src/target/arm_disassembler.c
+++ b/src/target/arm_disassembler.c
@@ -15,9 +15,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -278,7 +276,7 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,
uint8_t cp_num = (opcode & 0xf00) >> 8;
/* MCRR or MRRC */
- if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000)) {
+ if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c500000)) {
uint8_t cp_opcode, Rd, Rn, CRm;
char *mnemonic;
diff --git a/src/target/arm_disassembler.h b/src/target/arm_disassembler.h
index 4aee3519d..6f8f65d44 100644
--- a/src/target/arm_disassembler.h
+++ b/src/target/arm_disassembler.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM_DISASSEMBLER_H
-#define ARM_DISASSEMBLER_H
+#ifndef OPENOCD_TARGET_ARM_DISASSEMBLER_H
+#define OPENOCD_TARGET_ARM_DISASSEMBLER_H
enum arm_instruction_type {
ARM_UNKNOWN_INSTUCTION,
@@ -203,4 +201,4 @@ int arm_access_size(struct arm_instruction *instruction);
#define COND(opcode) (arm_condition_strings[(opcode & 0xf0000000) >> 28])
-#endif /* ARM_DISASSEMBLER_H */
+#endif /* OPENOCD_TARGET_ARM_DISASSEMBLER_H */
diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c
index 5df625f03..3e8180c36 100644
--- a/src/target/arm_dpm.c
+++ b/src/target/arm_dpm.c
@@ -12,9 +12,7 @@
* GNU 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*/
#ifdef HAVE_CONFIG_H
@@ -23,6 +21,7 @@
#include "arm.h"
#include "arm_dpm.h"
+#include "armv8_dpm.h"
#include
#include "register.h"
#include "breakpoints.h"
@@ -167,6 +166,9 @@ static int dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
/* core-specific ... ? */
LOG_WARNING("Jazelle PC adjustment unknown");
break;
+ default:
+ LOG_WARNING("unknow core state");
+ break;
}
break;
default:
@@ -230,6 +232,18 @@ static int dpm_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
return retval;
}
+/**
+ * Write to program counter and switch the core state (arm/thumb) according to
+ * the address.
+ */
+static int dpm_write_pc_core_state(struct arm_dpm *dpm, struct reg *r)
+{
+ uint32_t value = buf_get_u32(r->value, 0, 32);
+
+ /* read r0 from DCC; then "BX r0" */
+ return dpm->instr_write_data_r0(dpm, ARMV4_5_BX(0), value);
+}
+
/**
* Read basic registers of the the current context: R0 to R15, and CPSR;
* sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
@@ -423,20 +437,20 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
/* cope with special cases */
switch (regnum) {
- case 8 ... 12:
- /* r8..r12 "anything but FIQ" case;
- * we "know" core mode is accurate
- * since we haven't changed it yet
- */
- if (arm->core_mode == ARM_MODE_FIQ
- && ARM_MODE_ANY
- != mode)
- tmode = ARM_MODE_USR;
- break;
- case 16:
- /* SPSR */
- regnum++;
- break;
+ case 8 ... 12:
+ /* r8..r12 "anything but FIQ" case;
+ * we "know" core mode is accurate
+ * since we haven't changed it yet
+ */
+ if (arm->core_mode == ARM_MODE_FIQ
+ && ARM_MODE_ANY
+ != mode)
+ tmode = ARM_MODE_USR;
+ break;
+ case 16:
+ /* SPSR */
+ regnum++;
+ break;
}
/* REVISIT error checks */
@@ -450,8 +464,8 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
continue;
retval = dpm_write_reg(dpm,
- &cache->reg_list[i],
- regnum);
+ &cache->reg_list[i],
+ regnum);
if (retval != ERROR_OK)
goto done;
}
@@ -467,6 +481,19 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
goto done;
arm->cpsr->dirty = false;
+ /* restore the PC, make sure to also switch the core state
+ * to whatever it was set to with "arm core_state" command.
+ * target code will have set PC to an appropriate resume address.
+ */
+ retval = dpm_write_pc_core_state(dpm, arm->pc);
+ if (retval != ERROR_OK)
+ goto done;
+ /* on Cortex-A5 (as found on NXP VF610 SoC), BX instruction
+ * executed in debug state doesn't appear to set the PC,
+ * explicitly set it with a "MOV pc, r0". This doesn't influence
+ * CPSR on Cortex-A9 so it should be OK. Maybe due to different
+ * debug version?
+ */
retval = dpm_write_reg(dpm, arm->pc, 15);
if (retval != ERROR_OK)
goto done;
@@ -882,6 +909,7 @@ void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr)
addr -= 4;
break;
case ARM_STATE_JAZELLE:
+ case ARM_STATE_AARCH64:
/* ?? */
break;
}
@@ -902,20 +930,16 @@ void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
/* Examine debug reason */
switch (DSCR_ENTRY(dscr)) {
- case 6: /* Data abort (v6 only) */
- case 7: /* Prefetch abort (v6 only) */
- /* FALL THROUGH -- assume a v6 core in abort mode */
- case 0: /* HALT request from debugger */
- case 4: /* EDBGRQ */
+ case DSCR_ENTRY_HALT_REQ: /* HALT request from debugger */
+ case DSCR_ENTRY_EXT_DBG_REQ: /* EDBGRQ */
target->debug_reason = DBG_REASON_DBGRQ;
break;
- case 1: /* HW breakpoint */
- case 3: /* SW BKPT */
- case 5: /* vector catch */
+ case DSCR_ENTRY_BREAKPOINT: /* HW breakpoint */
+ case DSCR_ENTRY_BKPT_INSTR: /* vector catch */
target->debug_reason = DBG_REASON_BREAKPOINT;
break;
- case 2: /* asynch watchpoint */
- case 10:/* precise watchpoint */
+ case DSCR_ENTRY_IMPRECISE_WATCHPT: /* asynch watchpoint */
+ case DSCR_ENTRY_PRECISE_WATCHPT:/* precise watchpoint */
target->debug_reason = DBG_REASON_WATCHPOINT;
break;
default:
@@ -940,7 +964,7 @@ int arm_dpm_setup(struct arm_dpm *dpm)
{
struct arm *arm = dpm->arm;
struct target *target = arm->target;
- struct reg_cache *cache;
+ struct reg_cache *cache = 0;
arm->dpm = dpm;
@@ -949,11 +973,13 @@ int arm_dpm_setup(struct arm_dpm *dpm)
arm->read_core_reg = arm_dpm_read_core_reg;
arm->write_core_reg = arm_dpm_write_core_reg;
- cache = arm_build_reg_cache(target, arm);
- if (!cache)
- return ERROR_FAIL;
+ if (arm->core_cache == NULL) {
+ cache = arm_build_reg_cache(target, arm);
+ if (!cache)
+ return ERROR_FAIL;
- *register_get_last_cache_p(&target->reg_cache) = cache;
+ *register_get_last_cache_p(&target->reg_cache) = cache;
+ }
/* coprocessor access setup */
arm->mrc = dpm_mrc;
@@ -972,9 +998,8 @@ int arm_dpm_setup(struct arm_dpm *dpm)
/* FIXME add vector catch support */
dpm->nbp = 1 + ((dpm->didr >> 24) & 0xf);
- dpm->dbp = calloc(dpm->nbp, sizeof *dpm->dbp);
-
dpm->nwp = 1 + ((dpm->didr >> 28) & 0xf);
+ dpm->dbp = calloc(dpm->nbp, sizeof *dpm->dbp);
dpm->dwp = calloc(dpm->nwp, sizeof *dpm->dwp);
if (!dpm->dbp || !dpm->dwp) {
diff --git a/src/target/arm_dpm.h b/src/target/arm_dpm.h
index 73ed1bcf0..f8d124813 100644
--- a/src/target/arm_dpm.h
+++ b/src/target/arm_dpm.h
@@ -12,13 +12,11 @@
* GNU 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*/
-#ifndef __ARM_DPM_H
-#define __ARM_DPM_H
+#ifndef OPENOCD_TARGET_ARM_DPM_H
+#define OPENOCD_TARGET_ARM_DPM_H
/**
* @file
@@ -61,7 +59,7 @@ struct arm_dpm {
struct arm *arm;
/** Cache of DIDR */
- uint32_t didr;
+ uint64_t didr;
/** Invoke before a series of instruction operations */
int (*prepare)(struct arm_dpm *);
@@ -69,16 +67,26 @@ struct arm_dpm {
/** Invoke after a series of instruction operations */
int (*finish)(struct arm_dpm *);
+ /** Runs one instruction. */
+ int (*instr_execute)(struct arm_dpm *, uint32_t opcode);
+
/* WRITE TO CPU */
/** Runs one instruction, writing data to DCC before execution. */
int (*instr_write_data_dcc)(struct arm_dpm *,
uint32_t opcode, uint32_t data);
+ int (*instr_write_data_dcc_64)(struct arm_dpm *,
+ uint32_t opcode, uint64_t data);
+
/** Runs one instruction, writing data to R0 before execution. */
int (*instr_write_data_r0)(struct arm_dpm *,
uint32_t opcode, uint32_t data);
+ /** Runs one instruction, writing data to R0 before execution. */
+ int (*instr_write_data_r0_64)(struct arm_dpm *,
+ uint32_t opcode, uint64_t data);
+
/** Optional core-specific operation invoked after CPSR writes. */
int (*instr_cpsr_sync)(struct arm_dpm *dpm);
@@ -88,10 +96,19 @@ struct arm_dpm {
int (*instr_read_data_dcc)(struct arm_dpm *,
uint32_t opcode, uint32_t *data);
+ int (*instr_read_data_dcc_64)(struct arm_dpm *,
+ uint32_t opcode, uint64_t *data);
+
/** Runs one instruction, reading data from r0 after execution. */
int (*instr_read_data_r0)(struct arm_dpm *,
uint32_t opcode, uint32_t *data);
+ int (*instr_read_data_r0_64)(struct arm_dpm *,
+ uint32_t opcode, uint64_t *data);
+
+ struct reg *(*arm_reg_current)(struct arm *arm,
+ unsigned regnum);
+
/* BREAKPOINT/WATCHPOINT SUPPORT */
/**
@@ -121,11 +138,14 @@ struct arm_dpm {
struct dpm_wp *dwp;
/** Address of the instruction which triggered a watchpoint. */
- uint32_t wp_pc;
+ target_addr_t wp_pc;
/** Recent value of DSCR. */
uint32_t dscr;
+ /** Recent exception level on armv8 */
+ unsigned int last_el;
+
/* FIXME -- read/write DCSR methods and symbols */
};
@@ -135,7 +155,6 @@ int arm_dpm_initialize(struct arm_dpm *dpm);
int arm_dpm_read_current_registers(struct arm_dpm *);
int dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode);
-
int arm_dpm_write_dirty_registers(struct arm_dpm *, bool bpwp);
void arm_dpm_report_wfar(struct arm_dpm *, uint32_t wfar);
@@ -168,21 +187,21 @@ void arm_dpm_report_wfar(struct arm_dpm *, uint32_t wfar);
#define DSCR_DTR_TX_FULL (0x1 << 29)
#define DSCR_DTR_RX_FULL (0x1 << 30) /* bit 31 is reserved */
-#define DSCR_ENTRY(dscr) (((dscr) >> 2) & 0xf)
-#define DSCR_RUN_MODE(dscr) ((dscr) & (DSCR_CORE_HALTED | DSCR_CORE_RESTARTED))
+#define DSCR_ENTRY(dscr) ((dscr) & 0x3f)
+#define DSCR_RUN_MODE(dscr) ((dscr) & 0x03)
/* Methods of entry into debug mode */
-#define DSCR_ENTRY_HALT_REQ (0x0 << 2)
-#define DSCR_ENTRY_BREAKPOINT (0x1 << 2)
-#define DSCR_ENTRY_IMPRECISE_WATCHPT (0x2 << 2)
-#define DSCR_ENTRY_BKPT_INSTR (0x3 << 2)
-#define DSCR_ENTRY_EXT_DBG_REQ (0x4 << 2)
-#define DSCR_ENTRY_VECT_CATCH (0x5 << 2)
-#define DSCR_ENTRY_D_SIDE_ABORT (0x6 << 2) /* v6 only */
-#define DSCR_ENTRY_I_SIDE_ABORT (0x7 << 2) /* v6 only */
-#define DSCR_ENTRY_OS_UNLOCK (0x8 << 2)
-#define DSCR_ENTRY_PRECISE_WATCHPT (0xA << 2)
+#define DSCR_ENTRY_HALT_REQ (0x03)
+#define DSCR_ENTRY_BREAKPOINT (0x07)
+#define DSCR_ENTRY_IMPRECISE_WATCHPT (0x0B)
+#define DSCR_ENTRY_BKPT_INSTR (0x0F)
+#define DSCR_ENTRY_EXT_DBG_REQ (0x13)
+#define DSCR_ENTRY_VECT_CATCH (0x17)
+#define DSCR_ENTRY_D_SIDE_ABORT (0x1B) /* v6 only */
+#define DSCR_ENTRY_I_SIDE_ABORT (0x1F) /* v6 only */
+#define DSCR_ENTRY_OS_UNLOCK (0x23)
+#define DSCR_ENTRY_PRECISE_WATCHPT (0x2B)
/* DTR modes */
#define DSCR_EXT_DCC_NON_BLOCKING (0x0 << 20)
@@ -200,4 +219,25 @@ void arm_dpm_report_wfar(struct arm_dpm *, uint32_t wfar);
void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dcsr);
-#endif /* __ARM_DPM_H */
+/* PRCR (Device Power-down and Reset Control Register) bits */
+#define PRCR_DEBUG_NO_POWER_DOWN (1 << 0)
+#define PRCR_WARM_RESET (1 << 1)
+#define PRCR_HOLD_NON_DEBUG_RESET (1 << 2)
+
+/* PRSR (Device Power-down and Reset Status Register) bits */
+#define PRSR_POWERUP_STATUS (1 << 0)
+#define PRSR_STICKY_POWERDOWN_STATUS (1 << 1)
+#define PRSR_RESET_STATUS (1 << 2)
+#define PRSR_STICKY_RESET_STATUS (1 << 3)
+#define PRSR_HALTED (1 << 4) /* v7.1 Debug only */
+#define PRSR_OSLK (1 << 5) /* v7.1 Debug only */
+#define PRSR_DLK (1 << 6) /* v7.1 Debug only */
+
+/* OSLSR (OS Lock Status Register) bits */
+#define OSLSR_OSLM0 (1 << 0)
+#define OSLSR_OSLK (1 << 1)
+#define OSLSR_nTT (1 << 2)
+#define OSLSR_OSLM1 (1 << 3)
+#define OSLSR_OSLM (OSLSR_OSLM0|OSLSR_OSLM1)
+
+#endif /* OPENOCD_TARGET_ARM_DPM_H */
diff --git a/src/target/arm_jtag.c b/src/target/arm_jtag.c
index d2b9feeed..9b73d4ea8 100644
--- a/src/target/arm_jtag.c
+++ b/src/target/arm_jtag.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm_jtag.h b/src/target/arm_jtag.h
index dbfec857b..bb92abb84 100644
--- a/src/target/arm_jtag.h
+++ b/src/target/arm_jtag.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM_JTAG
-#define ARM_JTAG
+#ifndef OPENOCD_TARGET_ARM_JTAG_H
+#define OPENOCD_TARGET_ARM_JTAG_H
#include
@@ -77,4 +75,4 @@ static inline void arm_le_to_h_u32(jtag_callback_data_t arg)
*((uint32_t *)arg) = le_to_h_u32(in);
}
-#endif /* ARM_JTAG */
+#endif /* OPENOCD_TARGET_ARM_JTAG_H */
diff --git a/src/target/arm_opcodes.h b/src/target/arm_opcodes.h
index 81c4766ad..a53fee71e 100644
--- a/src/target/arm_opcodes.h
+++ b/src/target/arm_opcodes.h
@@ -22,12 +22,11 @@
* GNU 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*/
-#ifndef __ARM_OPCODES_H
-#define __ARM_OPCODES_H
+
+#ifndef OPENOCD_TARGET_ARM_OPCODES_H
+#define OPENOCD_TARGET_ARM_OPCODES_H
/**
* @file
@@ -311,4 +310,4 @@
((0xB660 | (0 << 8) | ((IF)&0x3)) \
| ((0xB660 | (0 << 8) | ((IF)&0x3)) << 16))
-#endif /* __ARM_OPCODES_H */
+#endif /* OPENOCD_TARGET_ARM_OPCODES_H */
diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c
index 21b7809c2..252511962 100644
--- a/src/target/arm_semihosting.c
+++ b/src/target/arm_semihosting.c
@@ -5,6 +5,9 @@
* Copyright (C) 2010 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
+ * Copyright (C) 2016 by Square, Inc. *
+ * Steven Stallion *
+ * *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
@@ -16,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/**
@@ -41,8 +42,11 @@
#include "armv4_5.h"
#include "arm7_9_common.h"
#include "armv7m.h"
+#include "armv7a.h"
#include "cortex_m.h"
#include "register.h"
+#include "arm_opcodes.h"
+#include "target_type.h"
#include "arm_semihosting.h"
#include
#include
@@ -63,13 +67,59 @@ static const int open_modeflags[12] = {
O_RDWR | O_CREAT | O_APPEND | O_BINARY
};
+static int post_result(struct target *target)
+{
+ struct arm *arm = target_to_arm(target);
+
+ /* REVISIT this looks wrong ... ARM11 and Cortex-A8
+ * should work this way at least sometimes.
+ */
+ if (is_arm7_9(target_to_arm7_9(target)) ||
+ is_armv7a(target_to_armv7a(target))) {
+ uint32_t spsr;
+
+ /* return value in R0 */
+ buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, arm->semihosting_result);
+ arm->core_cache->reg_list[0].dirty = 1;
+
+ /* LR --> PC */
+ buf_set_u32(arm->core_cache->reg_list[15].value, 0, 32,
+ buf_get_u32(arm_reg_current(arm, 14)->value, 0, 32));
+ arm->core_cache->reg_list[15].dirty = 1;
+
+ /* saved PSR --> current PSR */
+ spsr = buf_get_u32(arm->spsr->value, 0, 32);
+
+ /* REVISIT should this be arm_set_cpsr(arm, spsr)
+ * instead of a partially unrolled version?
+ */
+
+ buf_set_u32(arm->cpsr->value, 0, 32, spsr);
+ arm->cpsr->dirty = 1;
+ arm->core_mode = spsr & 0x1f;
+ if (spsr & 0x20)
+ arm->core_state = ARM_STATE_THUMB;
+
+ } else {
+ /* resume execution, this will be pc+2 to skip over the
+ * bkpt instruction */
+
+ /* return result in R0 */
+ buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, arm->semihosting_result);
+ arm->core_cache->reg_list[0].dirty = 1;
+ }
+
+ return ERROR_OK;
+}
+
static int do_semihosting(struct target *target)
{
struct arm *arm = target_to_arm(target);
+ struct gdb_fileio_info *fileio_info = target->fileio_info;
uint32_t r0 = buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32);
uint32_t r1 = buf_get_u32(arm->core_cache->reg_list[1].value, 0, 32);
uint8_t params[16];
- int retval, result;
+ int retval;
/*
* TODO: lots of security issues are not considered yet, such as:
@@ -77,10 +127,10 @@ static int do_semihosting(struct target *target)
* - no safety checks on opened/deleted/renamed file paths
* Beware the target app you use this support with.
*
- * TODO: explore mapping requests to GDB's "File-I/O Remote
- * Protocol Extension" ... when GDB is active.
+ * TODO: unsupported semihosting fileio operations could be
+ * implemented if we had a small working area at our disposal.
*/
- switch (r0) {
+ switch ((arm->semihosting_op = r0)) {
case 0x01: /* SYS_OPEN */
retval = target_read_memory(target, r1, 4, 3, params);
if (retval != ERROR_OK)
@@ -89,27 +139,40 @@ static int do_semihosting(struct target *target)
uint32_t a = target_buffer_get_u32(target, params+0);
uint32_t m = target_buffer_get_u32(target, params+4);
uint32_t l = target_buffer_get_u32(target, params+8);
- if (l <= 255 && m <= 11) {
- uint8_t fn[256];
- retval = target_read_memory(target, a, 1, l, fn);
- if (retval != ERROR_OK)
- return retval;
- fn[l] = 0;
- if (strcmp((char *)fn, ":tt") == 0) {
- if (m < 4)
- result = dup(STDIN_FILENO);
- else
- result = dup(STDOUT_FILENO);
- } else {
- /* cygwin requires the permission setting
- * otherwise it will fail to reopen a previously
- * written file */
- result = open((char *)fn, open_modeflags[m], 0644);
+ uint8_t fn[256];
+ retval = target_read_memory(target, a, 1, l, fn);
+ if (retval != ERROR_OK)
+ return retval;
+ fn[l] = 0;
+ if (arm->is_semihosting_fileio) {
+ if (strcmp((char *)fn, ":tt") == 0)
+ arm->semihosting_result = 0;
+ else {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "open";
+ fileio_info->param_1 = a;
+ fileio_info->param_2 = l;
+ fileio_info->param_3 = open_modeflags[m];
+ fileio_info->param_4 = 0644;
}
- arm->semihosting_errno = errno;
} else {
- result = -1;
- arm->semihosting_errno = EINVAL;
+ if (l <= 255 && m <= 11) {
+ if (strcmp((char *)fn, ":tt") == 0) {
+ if (m < 4)
+ arm->semihosting_result = dup(STDIN_FILENO);
+ else
+ arm->semihosting_result = dup(STDOUT_FILENO);
+ } else {
+ /* cygwin requires the permission setting
+ * otherwise it will fail to reopen a previously
+ * written file */
+ arm->semihosting_result = open((char *)fn, open_modeflags[m], 0644);
+ }
+ arm->semihosting_errno = errno;
+ } else {
+ arm->semihosting_result = -1;
+ arm->semihosting_errno = EINVAL;
+ }
}
}
break;
@@ -120,33 +183,63 @@ static int do_semihosting(struct target *target)
return retval;
else {
int fd = target_buffer_get_u32(target, params+0);
- result = close(fd);
- arm->semihosting_errno = errno;
+ if (arm->is_semihosting_fileio) {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "close";
+ fileio_info->param_1 = fd;
+ } else {
+ arm->semihosting_result = close(fd);
+ arm->semihosting_errno = errno;
+ }
}
break;
case 0x03: /* SYS_WRITEC */
- {
+ if (arm->is_semihosting_fileio) {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "write";
+ fileio_info->param_1 = 1;
+ fileio_info->param_2 = r1;
+ fileio_info->param_3 = 1;
+ } else {
unsigned char c;
retval = target_read_memory(target, r1, 1, 1, &c);
if (retval != ERROR_OK)
return retval;
putchar(c);
- result = 0;
+ arm->semihosting_result = 0;
}
break;
case 0x04: /* SYS_WRITE0 */
- do {
- unsigned char c;
- retval = target_read_memory(target, r1++, 1, 1, &c);
- if (retval != ERROR_OK)
- return retval;
- if (!c)
- break;
- putchar(c);
- } while (1);
- result = 0;
+ if (arm->is_semihosting_fileio) {
+ size_t count = 0;
+ for (uint32_t a = r1;; a++) {
+ unsigned char c;
+ retval = target_read_memory(target, a, 1, 1, &c);
+ if (retval != ERROR_OK)
+ return retval;
+ if (c == '\0')
+ break;
+ count++;
+ }
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "write";
+ fileio_info->param_1 = 1;
+ fileio_info->param_2 = r1;
+ fileio_info->param_3 = count;
+ } else {
+ do {
+ unsigned char c;
+ retval = target_read_memory(target, r1++, 1, 1, &c);
+ if (retval != ERROR_OK)
+ return retval;
+ if (!c)
+ break;
+ putchar(c);
+ } while (1);
+ arm->semihosting_result = 0;
+ }
break;
case 0x05: /* SYS_WRITE */
@@ -157,21 +250,29 @@ static int do_semihosting(struct target *target)
int fd = target_buffer_get_u32(target, params+0);
uint32_t a = target_buffer_get_u32(target, params+4);
size_t l = target_buffer_get_u32(target, params+8);
- uint8_t *buf = malloc(l);
- if (!buf) {
- result = -1;
- arm->semihosting_errno = ENOMEM;
+ if (arm->is_semihosting_fileio) {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "write";
+ fileio_info->param_1 = fd;
+ fileio_info->param_2 = a;
+ fileio_info->param_3 = l;
} else {
- retval = target_read_buffer(target, a, l, buf);
- if (retval != ERROR_OK) {
+ uint8_t *buf = malloc(l);
+ if (!buf) {
+ arm->semihosting_result = -1;
+ arm->semihosting_errno = ENOMEM;
+ } else {
+ retval = target_read_buffer(target, a, l, buf);
+ if (retval != ERROR_OK) {
+ free(buf);
+ return retval;
+ }
+ arm->semihosting_result = write(fd, buf, l);
+ arm->semihosting_errno = errno;
+ if (arm->semihosting_result >= 0)
+ arm->semihosting_result = l - arm->semihosting_result;
free(buf);
- return retval;
}
- result = write(fd, buf, l);
- arm->semihosting_errno = errno;
- if (result >= 0)
- result = l - result;
- free(buf);
}
}
break;
@@ -184,42 +285,60 @@ static int do_semihosting(struct target *target)
int fd = target_buffer_get_u32(target, params+0);
uint32_t a = target_buffer_get_u32(target, params+4);
ssize_t l = target_buffer_get_u32(target, params+8);
- uint8_t *buf = malloc(l);
- if (!buf) {
- result = -1;
- arm->semihosting_errno = ENOMEM;
+ if (arm->is_semihosting_fileio) {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "read";
+ fileio_info->param_1 = fd;
+ fileio_info->param_2 = a;
+ fileio_info->param_3 = l;
} else {
- result = read(fd, buf, l);
- arm->semihosting_errno = errno;
- if (result >= 0) {
- retval = target_write_buffer(target, a, result, buf);
- if (retval != ERROR_OK) {
- free(buf);
- return retval;
+ uint8_t *buf = malloc(l);
+ if (!buf) {
+ arm->semihosting_result = -1;
+ arm->semihosting_errno = ENOMEM;
+ } else {
+ arm->semihosting_result = read(fd, buf, l);
+ arm->semihosting_errno = errno;
+ if (arm->semihosting_result >= 0) {
+ retval = target_write_buffer(target, a, arm->semihosting_result, buf);
+ if (retval != ERROR_OK) {
+ free(buf);
+ return retval;
+ }
+ arm->semihosting_result = l - arm->semihosting_result;
}
- result = l - result;
+ free(buf);
}
- free(buf);
}
}
break;
case 0x07: /* SYS_READC */
- result = getchar();
+ if (arm->is_semihosting_fileio) {
+ LOG_ERROR("SYS_READC not supported by semihosting fileio");
+ return ERROR_FAIL;
+ }
+ arm->semihosting_result = getchar();
break;
case 0x08: /* SYS_ISERROR */
retval = target_read_memory(target, r1, 4, 1, params);
if (retval != ERROR_OK)
return retval;
- result = (target_buffer_get_u32(target, params+0) != 0);
+ arm->semihosting_result = (target_buffer_get_u32(target, params+0) != 0);
break;
case 0x09: /* SYS_ISTTY */
- retval = target_read_memory(target, r1, 4, 1, params);
- if (retval != ERROR_OK)
- return retval;
- result = isatty(target_buffer_get_u32(target, params+0));
+ if (arm->is_semihosting_fileio) {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "isatty";
+ fileio_info->param_1 = r1;
+ } else {
+ retval = target_read_memory(target, r1, 4, 1, params);
+ if (retval != ERROR_OK)
+ return retval;
+ arm->semihosting_result = isatty(target_buffer_get_u32(target, params+0));
+ }
break;
case 0x0a: /* SYS_SEEK */
@@ -229,27 +348,39 @@ static int do_semihosting(struct target *target)
else {
int fd = target_buffer_get_u32(target, params+0);
off_t pos = target_buffer_get_u32(target, params+4);
- result = lseek(fd, pos, SEEK_SET);
- arm->semihosting_errno = errno;
- if (result == pos)
- result = 0;
+ if (arm->is_semihosting_fileio) {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "lseek";
+ fileio_info->param_1 = fd;
+ fileio_info->param_2 = pos;
+ fileio_info->param_3 = SEEK_SET;
+ } else {
+ arm->semihosting_result = lseek(fd, pos, SEEK_SET);
+ arm->semihosting_errno = errno;
+ if (arm->semihosting_result == pos)
+ arm->semihosting_result = 0;
+ }
}
break;
case 0x0c: /* SYS_FLEN */
+ if (arm->is_semihosting_fileio) {
+ LOG_ERROR("SYS_FLEN not supported by semihosting fileio");
+ return ERROR_FAIL;
+ }
retval = target_read_memory(target, r1, 4, 1, params);
if (retval != ERROR_OK)
return retval;
else {
int fd = target_buffer_get_u32(target, params+0);
struct stat buf;
- result = fstat(fd, &buf);
- if (result == -1) {
+ arm->semihosting_result = fstat(fd, &buf);
+ if (arm->semihosting_result == -1) {
arm->semihosting_errno = errno;
- result = -1;
+ arm->semihosting_result = -1;
break;
}
- result = buf.st_size;
+ arm->semihosting_result = buf.st_size;
}
break;
@@ -260,17 +391,24 @@ static int do_semihosting(struct target *target)
else {
uint32_t a = target_buffer_get_u32(target, params+0);
uint32_t l = target_buffer_get_u32(target, params+4);
- if (l <= 255) {
- uint8_t fn[256];
- retval = target_read_memory(target, a, 1, l, fn);
- if (retval != ERROR_OK)
- return retval;
- fn[l] = 0;
- result = remove((char *)fn);
- arm->semihosting_errno = errno;
+ if (arm->is_semihosting_fileio) {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "unlink";
+ fileio_info->param_1 = a;
+ fileio_info->param_2 = l;
} else {
- result = -1;
- arm->semihosting_errno = EINVAL;
+ if (l <= 255) {
+ uint8_t fn[256];
+ retval = target_read_memory(target, a, 1, l, fn);
+ if (retval != ERROR_OK)
+ return retval;
+ fn[l] = 0;
+ arm->semihosting_result = remove((char *)fn);
+ arm->semihosting_errno = errno;
+ } else {
+ arm->semihosting_result = -1;
+ arm->semihosting_errno = EINVAL;
+ }
}
}
break;
@@ -284,31 +422,40 @@ static int do_semihosting(struct target *target)
uint32_t l1 = target_buffer_get_u32(target, params+4);
uint32_t a2 = target_buffer_get_u32(target, params+8);
uint32_t l2 = target_buffer_get_u32(target, params+12);
- if (l1 <= 255 && l2 <= 255) {
- uint8_t fn1[256], fn2[256];
- retval = target_read_memory(target, a1, 1, l1, fn1);
- if (retval != ERROR_OK)
- return retval;
- retval = target_read_memory(target, a2, 1, l2, fn2);
- if (retval != ERROR_OK)
- return retval;
- fn1[l1] = 0;
- fn2[l2] = 0;
- result = rename((char *)fn1, (char *)fn2);
- arm->semihosting_errno = errno;
+ if (arm->is_semihosting_fileio) {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "rename";
+ fileio_info->param_1 = a1;
+ fileio_info->param_2 = l1;
+ fileio_info->param_3 = a2;
+ fileio_info->param_4 = l2;
} else {
- result = -1;
- arm->semihosting_errno = EINVAL;
+ if (l1 <= 255 && l2 <= 255) {
+ uint8_t fn1[256], fn2[256];
+ retval = target_read_memory(target, a1, 1, l1, fn1);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_read_memory(target, a2, 1, l2, fn2);
+ if (retval != ERROR_OK)
+ return retval;
+ fn1[l1] = 0;
+ fn2[l2] = 0;
+ arm->semihosting_result = rename((char *)fn1, (char *)fn2);
+ arm->semihosting_errno = errno;
+ } else {
+ arm->semihosting_result = -1;
+ arm->semihosting_errno = EINVAL;
+ }
}
}
break;
case 0x11: /* SYS_TIME */
- result = time(NULL);
+ arm->semihosting_result = time(NULL);
break;
case 0x13: /* SYS_ERRNO */
- result = arm->semihosting_errno;
+ arm->semihosting_result = arm->semihosting_errno;
break;
case 0x15: /* SYS_GET_CMDLINE */
@@ -321,12 +468,12 @@ static int do_semihosting(struct target *target)
char *arg = "foobar";
uint32_t s = strlen(arg) + 1;
if (l < s)
- result = -1;
+ arm->semihosting_result = -1;
else {
retval = target_write_buffer(target, a, s, (uint8_t *)arg);
if (retval != ERROR_OK)
return retval;
- result = 0;
+ arm->semihosting_result = 0;
}
}
break;
@@ -342,7 +489,7 @@ static int do_semihosting(struct target *target)
retval = target_write_memory(target, a, 4, 4, params);
if (retval != ERROR_OK)
return retval;
- result = 0;
+ arm->semihosting_result = 0;
}
break;
@@ -386,17 +533,24 @@ static int do_semihosting(struct target *target)
else {
uint32_t len = target_buffer_get_u32(target, params+4);
uint32_t c_ptr = target_buffer_get_u32(target, params);
- uint8_t cmd[256];
- if (len > 255) {
- result = -1;
- arm->semihosting_errno = EINVAL;
+ if (arm->is_semihosting_fileio) {
+ arm->semihosting_hit_fileio = true;
+ fileio_info->identifier = "system";
+ fileio_info->param_1 = c_ptr;
+ fileio_info->param_2 = len;
} else {
- memset(cmd, 0x0, 256);
- retval = target_read_memory(target, c_ptr, 1, len, cmd);
- if (retval != ERROR_OK)
- return retval;
- else
- result = system((const char *)cmd);
+ uint8_t cmd[256];
+ if (len > 255) {
+ arm->semihosting_result = -1;
+ arm->semihosting_errno = EINVAL;
+ } else {
+ memset(cmd, 0x0, 256);
+ retval = target_read_memory(target, c_ptr, 1, len, cmd);
+ if (retval != ERROR_OK)
+ return retval;
+ else
+ arm->semihosting_result = system((const char *)cmd);
+ }
}
}
break;
@@ -408,50 +562,84 @@ static int do_semihosting(struct target *target)
default:
fprintf(stderr, "semihosting: unsupported call %#x\n",
(unsigned) r0);
- result = -1;
+ arm->semihosting_result = -1;
arm->semihosting_errno = ENOTSUP;
}
- /* resume execution to the original mode */
+ return ERROR_OK;
+}
- /* REVISIT this looks wrong ... ARM11 and Cortex-A8
- * should work this way at least sometimes.
+static int get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info)
+{
+ struct arm *arm = target_to_arm(target);
+
+ /* To avoid uneccessary duplication, semihosting prepares the
+ * fileio_info structure out-of-band when the target halts. See
+ * do_semihosting for more detail.
*/
- if (is_arm7_9(target_to_arm7_9(target))) {
- uint32_t spsr;
+ if (!arm->is_semihosting_fileio || !arm->semihosting_hit_fileio)
+ return ERROR_FAIL;
- /* return value in R0 */
- buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, result);
- arm->core_cache->reg_list[0].dirty = 1;
+ return ERROR_OK;
+}
- /* LR --> PC */
- buf_set_u32(arm->core_cache->reg_list[15].value, 0, 32,
- buf_get_u32(arm_reg_current(arm, 14)->value, 0, 32));
- arm->core_cache->reg_list[15].dirty = 1;
+static int gdb_fileio_end(struct target *target, int result, int fileio_errno, bool ctrl_c)
+{
+ struct arm *arm = target_to_arm(target);
+ struct gdb_fileio_info *fileio_info = target->fileio_info;
- /* saved PSR --> current PSR */
- spsr = buf_get_u32(arm->spsr->value, 0, 32);
+ /* clear pending status */
+ arm->semihosting_hit_fileio = false;
- /* REVISIT should this be arm_set_cpsr(arm, spsr)
- * instead of a partially unrolled version?
- */
+ arm->semihosting_result = result;
+ arm->semihosting_errno = fileio_errno;
- buf_set_u32(arm->cpsr->value, 0, 32, spsr);
- arm->cpsr->dirty = 1;
- arm->core_mode = spsr & 0x1f;
- if (spsr & 0x20)
- arm->core_state = ARM_STATE_THUMB;
+ /* Some fileio results do not match up with what the semihosting
+ * operation expects; for these operations, we munge the results
+ * below:
+ */
+ switch (arm->semihosting_op) {
+ case 0x05: /* SYS_WRITE */
+ if (result < 0)
+ arm->semihosting_result = fileio_info->param_3;
+ else
+ arm->semihosting_result = 0;
+ break;
- } else {
- /* resume execution, this will be pc+2 to skip over the
- * bkpt instruction */
+ case 0x06: /* SYS_READ */
+ if (result == (int)fileio_info->param_3)
+ arm->semihosting_result = 0;
+ if (result <= 0)
+ arm->semihosting_result = fileio_info->param_3;
+ break;
- /* return result in R0 */
- buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, result);
- arm->core_cache->reg_list[0].dirty = 1;
+ case 0x0a: /* SYS_SEEK */
+ if (result > 0)
+ arm->semihosting_result = 0;
+ break;
}
- return target_resume(target, 1, 0, 0, 0);
+ return post_result(target);
+}
+
+/**
+ * Initialize ARM semihosting support.
+ *
+ * @param target Pointer to the ARM target to initialize.
+ * @return An error status if there is a problem during initialization.
+ */
+int arm_semihosting_init(struct target *target)
+{
+ target->fileio_info = malloc(sizeof(*target->fileio_info));
+ if (target->fileio_info == NULL) {
+ LOG_ERROR("out of memory");
+ return ERROR_FAIL;
+ }
+
+ target->type->get_gdb_fileio_info = get_gdb_fileio_info;
+ target->type->gdb_fileio_end = gdb_fileio_end;
+
+ return ERROR_OK;
}
/**
@@ -470,20 +658,42 @@ static int do_semihosting(struct target *target)
int arm_semihosting(struct target *target, int *retval)
{
struct arm *arm = target_to_arm(target);
+ struct armv7a_common *armv7a = target_to_armv7a(target);
uint32_t pc, lr, spsr;
struct reg *r;
if (!arm->is_semihosting)
return 0;
- if (is_arm7_9(target_to_arm7_9(target))) {
+ if (is_arm7_9(target_to_arm7_9(target)) ||
+ is_armv7a(armv7a)) {
+ uint32_t vbar = 0x00000000;
+
if (arm->core_mode != ARM_MODE_SVC)
return 0;
+ if (is_armv7a(armv7a)) {
+ struct arm_dpm *dpm = armv7a->arm.dpm;
+
+ *retval = dpm->prepare(dpm);
+ if (*retval == ERROR_OK) {
+ *retval = dpm->instr_read_data_r0(dpm,
+ ARMV4_5_MRC(15, 0, 0, 12, 0, 0),
+ &vbar);
+
+ dpm->finish(dpm);
+
+ if (*retval != ERROR_OK)
+ return 1;
+ } else {
+ return 1;
+ }
+ }
+
/* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */
r = arm->pc;
pc = buf_get_u32(r->value, 0, 32);
- if (pc != 0x00000008 && pc != 0xffff0008)
+ if (pc != (vbar + 0x00000008) && pc != 0xffff0008)
return 0;
r = arm_reg_current(arm, 14);
@@ -553,6 +763,35 @@ int arm_semihosting(struct target *target, int *retval)
return 0;
}
- *retval = do_semihosting(target);
- return 1;
+ /* Perform semihosting if we are not waiting on a fileio
+ * operation to complete.
+ */
+ if (!arm->semihosting_hit_fileio) {
+ *retval = do_semihosting(target);
+ if (*retval != ERROR_OK) {
+ LOG_ERROR("Failed semihosting operation");
+ return 0;
+ }
+ }
+
+ /* Post result to target if we are not waiting on a fileio
+ * operation to complete:
+ */
+ if (!arm->semihosting_hit_fileio) {
+ *retval = post_result(target);
+ if (*retval != ERROR_OK) {
+ LOG_ERROR("Failed to post semihosting result");
+ return 0;
+ }
+
+ *retval = target_resume(target, 1, 0, 0, 0);
+ if (*retval != ERROR_OK) {
+ LOG_ERROR("Failed to resume target");
+ return 0;
+ }
+
+ return 1;
+ }
+
+ return 0;
}
diff --git a/src/target/arm_semihosting.h b/src/target/arm_semihosting.h
index 58b343266..011f19f00 100644
--- a/src/target/arm_semihosting.h
+++ b/src/target/arm_semihosting.h
@@ -13,14 +13,13 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM_SEMIHOSTING_H
-#define ARM_SEMIHOSTING_H
+#ifndef OPENOCD_TARGET_ARM_SEMIHOSTING_H
+#define OPENOCD_TARGET_ARM_SEMIHOSTING_H
+int arm_semihosting_init(struct target *target);
int arm_semihosting(struct target *target, int *retval);
-#endif
+#endif /* OPENOCD_TARGET_ARM_SEMIHOSTING_H */
diff --git a/src/target/arm_simulator.c b/src/target/arm_simulator.c
index 26f5b8e16..245e108ac 100644
--- a/src/target/arm_simulator.c
+++ b/src/target/arm_simulator.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/arm_simulator.h b/src/target/arm_simulator.h
index 3aedaee2e..5bdbf562c 100644
--- a/src/target/arm_simulator.h
+++ b/src/target/arm_simulator.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM_SIMULATOR_H
-#define ARM_SIMULATOR_H
+#ifndef OPENOCD_TARGET_ARM_SIMULATOR_H
+#define OPENOCD_TARGET_ARM_SIMULATOR_H
struct target;
@@ -38,4 +36,4 @@ struct arm_sim_interface {
/* armv4_5 version */
int arm_simulate_step(struct target *target, uint32_t *dry_run_pc);
-#endif /* ARM_SIMULATOR_H */
+#endif /* OPENOCD_TARGET_ARM_SIMULATOR_H */
diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c
index e75fe99c4..2029ca92a 100644
--- a/src/target/armv4_5.c
+++ b/src/target/armv4_5.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -140,6 +138,12 @@ static const struct {
.n_indices = ARRAY_SIZE(arm_mon_indices),
.indices = arm_mon_indices,
},
+ {
+ .name = "Secure Monitor ARM1176JZF-S",
+ .psr = ARM_MODE_1176_MON,
+ .n_indices = ARRAY_SIZE(arm_mon_indices),
+ .indices = arm_mon_indices,
+ },
/* These special modes are currently only supported
* by ARMv6M and ARMv7M profiles */
@@ -199,6 +203,7 @@ int arm_mode_to_number(enum arm_mode mode)
case ARM_MODE_SYS:
return 6;
case ARM_MODE_MON:
+ case ARM_MODE_1176_MON:
return 7;
default:
LOG_ERROR("invalid mode value encountered %d", mode);
@@ -661,14 +666,19 @@ int arm_arch_state(struct target *target)
return ERROR_FAIL;
}
+ /* avoid filling log waiting for fileio reply */
+ if (arm->semihosting_hit_fileio)
+ return ERROR_OK;
+
LOG_USER("target halted in %s state due to %s, current mode: %s\n"
- "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s",
+ "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s%s",
arm_state_strings[arm->core_state],
debug_reason_name(target),
arm_mode_name(arm->core_mode),
buf_get_u32(arm->cpsr->value, 0, 32),
buf_get_u32(arm->pc->value, 0, 32),
- arm->is_semihosting ? ", semihosting" : "");
+ arm->is_semihosting ? ", semihosting" : "",
+ arm->is_semihosting_fileio ? " fileio" : "");
return ERROR_OK;
}
@@ -806,7 +816,7 @@ COMMAND_HANDLER(handle_arm_disassemble_command)
}
struct arm *arm = target_to_arm(target);
- uint32_t address;
+ target_addr_t address;
int count = 1;
int thumb = 0;
@@ -830,7 +840,7 @@ COMMAND_HANDLER(handle_arm_disassemble_command)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
/* FALL THROUGH */
case 1:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
if (address & 0x01) {
if (!thumb) {
command_print(CMD_CTX, "Disassemble as Thumb");
@@ -1050,6 +1060,37 @@ COMMAND_HANDLER(handle_arm_semihosting_command)
return ERROR_OK;
}
+COMMAND_HANDLER(handle_arm_semihosting_fileio_command)
+{
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (target == NULL) {
+ LOG_ERROR("No target selected");
+ return ERROR_FAIL;
+ }
+
+ struct arm *arm = target_to_arm(target);
+
+ if (!is_arm(arm)) {
+ command_print(CMD_CTX, "current target isn't an ARM");
+ return ERROR_FAIL;
+ }
+
+ if (!arm->is_semihosting) {
+ command_print(CMD_CTX, "semihosting is not enabled");
+ return ERROR_FAIL;
+ }
+
+ if (CMD_ARGC > 0)
+ COMMAND_PARSE_ENABLE(CMD_ARGV[0], arm->is_semihosting_fileio);
+
+ command_print(CMD_CTX, "semihosting fileio is %s",
+ arm->is_semihosting_fileio
+ ? "enabled" : "disabled");
+
+ return ERROR_OK;
+}
+
static const struct command_registration arm_exec_command_handlers[] = {
{
.name = "reg",
@@ -1092,6 +1133,13 @@ static const struct command_registration arm_exec_command_handlers[] = {
.usage = "['enable'|'disable']",
.help = "activate support for semihosting operations",
},
+ {
+ "semihosting_fileio",
+ .handler = handle_arm_semihosting_fileio_command,
+ .mode = COMMAND_EXEC,
+ .usage = "['enable'|'disable']",
+ .help = "activate support for semihosting fileio operations",
+ },
COMMAND_REGISTRATION_DONE
};
@@ -1386,8 +1434,8 @@ int armv4_5_run_algorithm(struct target *target,
struct mem_param *mem_params,
int num_reg_params,
struct reg_param *reg_params,
- uint32_t entry_point,
- uint32_t exit_point,
+ target_addr_t entry_point,
+ target_addr_t exit_point,
int timeout_ms,
void *arch_info)
{
@@ -1396,8 +1444,8 @@ int armv4_5_run_algorithm(struct target *target,
mem_params,
num_reg_params,
reg_params,
- entry_point,
- exit_point,
+ (uint32_t)entry_point,
+ (uint32_t)exit_point,
timeout_ms,
arch_info,
armv4_5_run_algorithm_completion);
@@ -1408,7 +1456,7 @@ int armv4_5_run_algorithm(struct target *target,
*
*/
int arm_checksum_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *checksum)
+ target_addr_t address, uint32_t count, uint32_t *checksum)
{
struct working_area *crc_algorithm;
struct arm_algorithm arm_algo;
@@ -1418,49 +1466,24 @@ int arm_checksum_memory(struct target *target,
uint32_t i;
uint32_t exit_var = 0;
- /* see contrib/loaders/checksum/armv4_5_crc.s for src */
-
- static const uint32_t arm_crc_code[] = {
- 0xE1A02000, /* mov r2, r0 */
- 0xE3E00000, /* mov r0, #0xffffffff */
- 0xE1A03001, /* mov r3, r1 */
- 0xE3A04000, /* mov r4, #0 */
- 0xEA00000B, /* b ncomp */
- /* nbyte: */
- 0xE7D21004, /* ldrb r1, [r2, r4] */
- 0xE59F7030, /* ldr r7, CRC32XOR */
- 0xE0200C01, /* eor r0, r0, r1, asl 24 */
- 0xE3A05000, /* mov r5, #0 */
- /* loop: */
- 0xE3500000, /* cmp r0, #0 */
- 0xE1A06080, /* mov r6, r0, asl #1 */
- 0xE2855001, /* add r5, r5, #1 */
- 0xE1A00006, /* mov r0, r6 */
- 0xB0260007, /* eorlt r0, r6, r7 */
- 0xE3550008, /* cmp r5, #8 */
- 0x1AFFFFF8, /* bne loop */
- 0xE2844001, /* add r4, r4, #1 */
- /* ncomp: */
- 0xE1540003, /* cmp r4, r3 */
- 0x1AFFFFF1, /* bne nbyte */
- /* end: */
- 0xe1200070, /* bkpt #0 */
- /* CRC32XOR: */
- 0x04C11DB7 /* .word 0x04C11DB7 */
+ static const uint8_t arm_crc_code_le[] = {
+#include "../../contrib/loaders/checksum/armv4_5_crc.inc"
};
+ assert(sizeof(arm_crc_code_le) % 4 == 0);
+
retval = target_alloc_working_area(target,
- sizeof(arm_crc_code), &crc_algorithm);
+ sizeof(arm_crc_code_le), &crc_algorithm);
if (retval != ERROR_OK)
return retval;
/* convert code into a buffer in target endianness */
- for (i = 0; i < ARRAY_SIZE(arm_crc_code); i++) {
+ for (i = 0; i < ARRAY_SIZE(arm_crc_code_le) / 4; i++) {
retval = target_write_u32(target,
crc_algorithm->address + i * sizeof(uint32_t),
- arm_crc_code[i]);
+ le_to_h_u32(&arm_crc_code_le[i * 4]));
if (retval != ERROR_OK)
- return retval;
+ goto cleanup;
}
arm_algo.common_magic = ARM_COMMON_MAGIC;
@@ -1478,28 +1501,25 @@ int arm_checksum_memory(struct target *target,
/* armv4 must exit using a hardware breakpoint */
if (arm->is_armv4)
- exit_var = crc_algorithm->address + sizeof(arm_crc_code) - 8;
+ exit_var = crc_algorithm->address + sizeof(arm_crc_code_le) - 8;
retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
crc_algorithm->address,
exit_var,
timeout, &arm_algo);
- if (retval != ERROR_OK) {
- LOG_ERROR("error executing ARM crc algorithm");
- destroy_reg_param(®_params[0]);
- destroy_reg_param(®_params[1]);
- target_free_working_area(target, crc_algorithm);
- return retval;
- }
- *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+ if (retval == ERROR_OK)
+ *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+ else
+ LOG_ERROR("error executing ARM crc algorithm");
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
+cleanup:
target_free_working_area(target, crc_algorithm);
- return ERROR_OK;
+ return retval;
}
/**
@@ -1509,7 +1529,7 @@ int arm_checksum_memory(struct target *target,
*
*/
int arm_blank_check_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *blank)
+ target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
{
struct working_area *check_algorithm;
struct reg_param reg_params[3];
@@ -1519,32 +1539,32 @@ int arm_blank_check_memory(struct target *target,
uint32_t i;
uint32_t exit_var = 0;
- /* see contrib/loaders/erase_check/armv4_5_erase_check.s for src */
-
- static const uint32_t check_code[] = {
- /* loop: */
- 0xe4d03001, /* ldrb r3, [r0], #1 */
- 0xe0022003, /* and r2, r2, r3 */
- 0xe2511001, /* subs r1, r1, #1 */
- 0x1afffffb, /* bne loop */
- /* end: */
- 0xe1200070, /* bkpt #0 */
+ static const uint8_t check_code_le[] = {
+#include "../../contrib/loaders/erase_check/armv4_5_erase_check.inc"
};
+ assert(sizeof(check_code_le) % 4 == 0);
+
+ if (erased_value != 0xff) {
+ LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for ARMv4/v5 targets",
+ erased_value);
+ return ERROR_FAIL;
+ }
+
/* make sure we have a working area */
retval = target_alloc_working_area(target,
- sizeof(check_code), &check_algorithm);
+ sizeof(check_code_le), &check_algorithm);
if (retval != ERROR_OK)
return retval;
/* convert code into a buffer in target endianness */
- for (i = 0; i < ARRAY_SIZE(check_code); i++) {
+ for (i = 0; i < ARRAY_SIZE(check_code_le) / 4; i++) {
retval = target_write_u32(target,
check_algorithm->address
+ i * sizeof(uint32_t),
- check_code[i]);
+ le_to_h_u32(&check_code_le[i * 4]));
if (retval != ERROR_OK)
- return retval;
+ goto cleanup;
}
arm_algo.common_magic = ARM_COMMON_MAGIC;
@@ -1558,33 +1578,28 @@ int arm_blank_check_memory(struct target *target,
buf_set_u32(reg_params[1].value, 0, 32, count);
init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT);
- buf_set_u32(reg_params[2].value, 0, 32, 0xff);
+ buf_set_u32(reg_params[2].value, 0, 32, erased_value);
/* armv4 must exit using a hardware breakpoint */
if (arm->is_armv4)
- exit_var = check_algorithm->address + sizeof(check_code) - 4;
+ exit_var = check_algorithm->address + sizeof(check_code_le) - 4;
retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
check_algorithm->address,
exit_var,
10000, &arm_algo);
- if (retval != ERROR_OK) {
- destroy_reg_param(®_params[0]);
- destroy_reg_param(®_params[1]);
- destroy_reg_param(®_params[2]);
- target_free_working_area(target, check_algorithm);
- return retval;
- }
- *blank = buf_get_u32(reg_params[2].value, 0, 32);
+ if (retval == ERROR_OK)
+ *blank = buf_get_u32(reg_params[2].value, 0, 32);
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
destroy_reg_param(®_params[2]);
+cleanup:
target_free_working_area(target, check_algorithm);
- return ERROR_OK;
+ return retval;
}
static int arm_full_context(struct target *target)
diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h
index 250d95bbd..3ce4ed0e5 100644
--- a/src/target/armv4_5.h
+++ b/src/target/armv4_5.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARMV4_5_H
-#define ARMV4_5_H
+#ifndef OPENOCD_TARGET_ARMV4_5_H
+#define OPENOCD_TARGET_ARMV4_5_H
/* This stuff "knows" that its callers aren't talking
* to microcontroller profile (current Cortex-M) parts.
@@ -48,4 +46,4 @@ extern const int armv4_5_core_reg_map[8][17];
/* offset into armv4_5 core register cache -- OBSOLETE, DO NOT USE! */
enum { ARMV4_5_CPSR = 31, };
-#endif /* ARMV4_5_H */
+#endif /* OPENOCD_TARGET_ARMV4_5_H */
diff --git a/src/target/armv4_5_cache.c b/src/target/armv4_5_cache.c
index 66dac3c20..bd0091d80 100644
--- a/src/target/armv4_5_cache.c
+++ b/src/target/armv4_5_cache.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv4_5_cache.h b/src/target/armv4_5_cache.h
index a1777e802..2fd1ca387 100644
--- a/src/target/armv4_5_cache.h
+++ b/src/target/armv4_5_cache.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARMV4_5_CACHE_H
-#define ARMV4_5_CACHE_H
+#ifndef OPENOCD_TARGET_ARMV4_5_CACHE_H
+#define OPENOCD_TARGET_ARMV4_5_CACHE_H
struct command_context;
@@ -54,4 +52,4 @@ enum {
ARMV4_5_CACHE_RR_BIT = 0x5000,
};
-#endif /* ARMV4_5_CACHE_H */
+#endif /* OPENOCD_TARGET_ARMV4_5_CACHE_H */
diff --git a/src/target/armv4_5_mmu.c b/src/target/armv4_5_mmu.c
index ad9040fb4..115a48950 100644
--- a/src/target/armv4_5_mmu.c
+++ b/src/target/armv4_5_mmu.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv4_5_mmu.h b/src/target/armv4_5_mmu.h
index e2dde7fe7..7beaf4ee9 100644
--- a/src/target/armv4_5_mmu.h
+++ b/src/target/armv4_5_mmu.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARMV4_5_MMU_H
-#define ARMV4_5_MMU_H
+#ifndef OPENOCD_TARGET_ARMV4_5_MMU_H
+#define OPENOCD_TARGET_ARMV4_5_MMU_H
#include "armv4_5_cache.h"
@@ -27,8 +25,9 @@ struct target;
struct armv4_5_mmu_common {
int (*get_ttb)(struct target *target, uint32_t *result);
- int (*read_memory)(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
- int (*write_memory)(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
+ int (*read_memory)(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+ int (*write_memory)(struct target *target, target_addr_t address,
+ uint32_t size, uint32_t count, const uint8_t *buffer);
int (*disable_mmu_caches)(struct target *target, int mmu, int d_u_cache, int i_cache);
int (*enable_mmu_caches)(struct target *target, int mmu, int d_u_cache, int i_cache);
struct armv4_5_cache_common armv4_5_cache;
@@ -55,4 +54,4 @@ enum {
ARMV4_5_MMU_R_BIT = 0x200
};
-#endif /* ARMV4_5_MMU_H */
+#endif /* OPENOCD_TARGET_ARMV4_5_MMU_H */
diff --git a/src/target/armv7a.c b/src/target/armv7a.c
index b9320d143..6021def4e 100644
--- a/src/target/armv7a.c
+++ b/src/target/armv7a.c
@@ -14,9 +14,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -177,7 +175,7 @@ static int armv7a_read_ttbcr(struct target *target)
return retval;
}
-/* method adapted to cortex A : reused arm v4 v5 method*/
+/* method adapted to Cortex-A : reused ARM v4 v5 method */
int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val)
{
uint32_t first_lvl_descriptor = 0x0;
@@ -681,11 +679,40 @@ int armv7a_identify_cache(struct target *target)
}
+static int armv7a_setup_semihosting(struct target *target, int enable)
+{
+ struct armv7a_common *armv7a = target_to_armv7a(target);
+ uint32_t vcr;
+ int ret;
+
+ ret = mem_ap_read_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_VCR,
+ &vcr);
+ if (ret < 0) {
+ LOG_ERROR("Failed to read VCR register\n");
+ return ret;
+ }
+
+ if (enable)
+ vcr |= DBG_VCR_SVC_MASK;
+ else
+ vcr &= ~DBG_VCR_SVC_MASK;
+
+ ret = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_VCR,
+ vcr);
+ if (ret < 0)
+ LOG_ERROR("Failed to write VCR register\n");
+
+ return ret;
+}
+
int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a)
{
struct arm *arm = &armv7a->arm;
arm->arch_info = armv7a;
target->arch_info = &armv7a->arm;
+ arm->setup_semihosting = armv7a_setup_semihosting;
/* target is useful in all function arm v4 5 compatible */
armv7a->arm.target = target;
armv7a->arm.common_magic = ARM_COMMON_MAGIC;
diff --git a/src/target/armv7a.h b/src/target/armv7a.h
index 5ca4eb86e..14112e4ed 100644
--- a/src/target/armv7a.h
+++ b/src/target/armv7a.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARMV7A_H
-#define ARMV7A_H
+#ifndef OPENOCD_TARGET_ARMV7A_H
+#define OPENOCD_TARGET_ARMV7A_H
#include "arm_adi_v5.h"
#include "armv7a_cache.h"
@@ -50,7 +48,6 @@ struct armv7a_l2x_cache {
};
struct armv7a_cachesize {
- uint32_t level_num;
/* cache dimensionning */
uint32_t linelen;
uint32_t associativity;
@@ -93,7 +90,7 @@ struct armv7a_mmu_common {
uint32_t ttbr_mask[2];
uint32_t ttbr_range[2];
- int (*read_physical_memory)(struct target *target, uint32_t address, uint32_t size,
+ int (*read_physical_memory)(struct target *target, target_addr_t address, uint32_t size,
uint32_t count, uint8_t *buffer);
struct armv7a_cache_common armv7a_cache;
uint32_t mmu_enabled;
@@ -136,6 +133,12 @@ target_to_armv7a(struct target *target)
return container_of(target->arch_info, struct armv7a_common, arm);
}
+static inline bool is_armv7a(struct armv7a_common *armv7a)
+{
+ return armv7a->common_magic == ARMV7_COMMON_MAGIC;
+}
+
+
/* register offsets from armv7a.debug_base */
/* See ARMv7a arch spec section C10.2 */
@@ -174,6 +177,13 @@ target_to_armv7a(struct target *target)
/* See ARMv7a arch spec section C10.8 */
#define CPUDBG_AUTHSTATUS 0xFB8
+/* Masks for Vector Catch register */
+#define DBG_VCR_FIQ_MASK ((1 << 31) | (1 << 7))
+#define DBG_VCR_IRQ_MASK ((1 << 30) | (1 << 6))
+#define DBG_VCR_DATA_ABORT_MASK ((1 << 28) | (1 << 4))
+#define DBG_VCR_PREF_ABORT_MASK ((1 << 27) | (1 << 3))
+#define DBG_VCR_SVC_MASK ((1 << 26) | (1 << 2))
+
int armv7a_arch_state(struct target *target);
int armv7a_identify_cache(struct target *target);
int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a);
@@ -186,4 +196,4 @@ int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,
extern const struct command_registration armv7a_command_handlers[];
-#endif /* ARMV4_5_H */
+#endif /* OPENOCD_TARGET_ARMV7A_H */
diff --git a/src/target/armv7a_cache.c b/src/target/armv7a_cache.c
index 9237e73fe..7af3e6d4e 100644
--- a/src/target/armv7a_cache.c
+++ b/src/target/armv7a_cache.c
@@ -11,6 +11,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv7a_cache.h b/src/target/armv7a_cache.h
index e0ebb618b..e0f7eb3a5 100644
--- a/src/target/armv7a_cache.h
+++ b/src/target/armv7a_cache.h
@@ -11,10 +11,13 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM7A_CACHE_H
-#define ARM7A_CACHE_H
+#ifndef OPENOCD_TARGET_ARM7A_CACHE_H
+#define OPENOCD_TARGET_ARM7A_CACHE_H
#include "arm_jtag.h"
#include "armv7a_cache_l2x.h"
@@ -40,4 +43,4 @@ extern const struct command_registration arm7a_cache_command_handlers[];
#define CACHE_LEVEL_HAS_D_CACHE 0x2
#define CACHE_LEVEL_HAS_I_CACHE 0x1
-#endif
+#endif /* OPENOCD_TARGET_ARM7A_CACHE_H */
diff --git a/src/target/armv7a_cache_l2x.c b/src/target/armv7a_cache_l2x.c
index 8b35fd89b..e181f268d 100644
--- a/src/target/armv7a_cache_l2x.c
+++ b/src/target/armv7a_cache_l2x.c
@@ -11,6 +11,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -60,12 +63,12 @@ int arm7a_l2x_flush_all_data(struct target *target)
l2_way_val = (1 << l2x_cache->way) - 1;
- return target_write_phys_memory(target,
+ return target_write_phys_u32(target,
l2x_cache->base + L2X0_CLEAN_INV_WAY,
- 4, 1, (uint8_t *)&l2_way_val);
+ l2_way_val);
}
-int armv7a_l2x_cache_flush_virt(struct target *target, uint32_t virt,
+int armv7a_l2x_cache_flush_virt(struct target *target, target_addr_t virt,
uint32_t size)
{
struct armv7a_common *armv7a = target_to_armv7a(target);
@@ -80,16 +83,15 @@ int armv7a_l2x_cache_flush_virt(struct target *target, uint32_t virt,
return retval;
for (i = 0; i < size; i += linelen) {
- uint32_t pa, offs = virt + i;
+ target_addr_t pa, offs = virt + i;
/* FIXME: use less verbose virt2phys? */
retval = target->type->virt2phys(target, offs, &pa);
if (retval != ERROR_OK)
goto done;
- retval = target_write_phys_memory(target,
- l2x_cache->base + L2X0_CLEAN_INV_LINE_PA,
- 4, 1, (uint8_t *)&pa);
+ retval = target_write_phys_u32(target,
+ l2x_cache->base + L2X0_CLEAN_INV_LINE_PA, pa);
if (retval != ERROR_OK)
goto done;
}
@@ -101,7 +103,7 @@ int armv7a_l2x_cache_flush_virt(struct target *target, uint32_t virt,
return retval;
}
-static int armv7a_l2x_cache_inval_virt(struct target *target, uint32_t virt,
+static int armv7a_l2x_cache_inval_virt(struct target *target, target_addr_t virt,
uint32_t size)
{
struct armv7a_common *armv7a = target_to_armv7a(target);
@@ -116,16 +118,15 @@ static int armv7a_l2x_cache_inval_virt(struct target *target, uint32_t virt,
return retval;
for (i = 0; i < size; i += linelen) {
- uint32_t pa, offs = virt + i;
+ target_addr_t pa, offs = virt + i;
/* FIXME: use less verbose virt2phys? */
retval = target->type->virt2phys(target, offs, &pa);
if (retval != ERROR_OK)
goto done;
- retval = target_write_phys_memory(target,
- l2x_cache->base + L2X0_INV_LINE_PA,
- 4, 1, (uint8_t *)&pa);
+ retval = target_write_phys_u32(target,
+ l2x_cache->base + L2X0_INV_LINE_PA, pa);
if (retval != ERROR_OK)
goto done;
}
@@ -137,7 +138,7 @@ static int armv7a_l2x_cache_inval_virt(struct target *target, uint32_t virt,
return retval;
}
-static int armv7a_l2x_cache_clean_virt(struct target *target, uint32_t virt,
+static int armv7a_l2x_cache_clean_virt(struct target *target, target_addr_t virt,
unsigned int size)
{
struct armv7a_common *armv7a = target_to_armv7a(target);
@@ -152,16 +153,15 @@ static int armv7a_l2x_cache_clean_virt(struct target *target, uint32_t virt,
return retval;
for (i = 0; i < size; i += linelen) {
- uint32_t pa, offs = virt + i;
+ target_addr_t pa, offs = virt + i;
/* FIXME: use less verbose virt2phys? */
retval = target->type->virt2phys(target, offs, &pa);
if (retval != ERROR_OK)
goto done;
- retval = target_write_phys_memory(target,
- l2x_cache->base + L2X0_CLEAN_LINE_PA,
- 4, 1, (uint8_t *)&pa);
+ retval = target_write_phys_u32(target,
+ l2x_cache->base + L2X0_CLEAN_LINE_PA, pa);
if (retval != ERROR_OK)
goto done;
}
@@ -249,7 +249,8 @@ COMMAND_HANDLER(arm7a_l2x_cache_flush_all_command)
COMMAND_HANDLER(arm7a_l2x_cache_flush_virt_cmd)
{
struct target *target = get_current_target(CMD_CTX);
- uint32_t virt, size;
+ target_addr_t virt;
+ uint32_t size;
if (CMD_ARGC == 0 || CMD_ARGC > 2)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -259,7 +260,7 @@ COMMAND_HANDLER(arm7a_l2x_cache_flush_virt_cmd)
else
size = 1;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt);
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], virt);
return armv7a_l2x_cache_flush_virt(target, virt, size);
}
@@ -267,7 +268,8 @@ COMMAND_HANDLER(arm7a_l2x_cache_flush_virt_cmd)
COMMAND_HANDLER(arm7a_l2x_cache_inval_virt_cmd)
{
struct target *target = get_current_target(CMD_CTX);
- uint32_t virt, size;
+ target_addr_t virt;
+ uint32_t size;
if (CMD_ARGC == 0 || CMD_ARGC > 2)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -277,7 +279,7 @@ COMMAND_HANDLER(arm7a_l2x_cache_inval_virt_cmd)
else
size = 1;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt);
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], virt);
return armv7a_l2x_cache_inval_virt(target, virt, size);
}
@@ -285,7 +287,8 @@ COMMAND_HANDLER(arm7a_l2x_cache_inval_virt_cmd)
COMMAND_HANDLER(arm7a_l2x_cache_clean_virt_cmd)
{
struct target *target = get_current_target(CMD_CTX);
- uint32_t virt, size;
+ target_addr_t virt;
+ uint32_t size;
if (CMD_ARGC == 0 || CMD_ARGC > 2)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -295,7 +298,7 @@ COMMAND_HANDLER(arm7a_l2x_cache_clean_virt_cmd)
else
size = 1;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt);
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], virt);
return armv7a_l2x_cache_clean_virt(target, virt, size);
}
diff --git a/src/target/armv7a_cache_l2x.h b/src/target/armv7a_cache_l2x.h
index 99fbe8aa6..f98b55446 100644
--- a/src/target/armv7a_cache_l2x.h
+++ b/src/target/armv7a_cache_l2x.h
@@ -11,10 +11,13 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARM7A_CACHE_L2X_H
-#define ARM7A_CACHE_L2X_H
+#ifndef OPENOCD_TARGET_ARM7A_CACHE_L2X_H
+#define OPENOCD_TARGET_ARM7A_CACHE_L2X_H
#define L2X0_CACHE_LINE_SIZE 32
@@ -148,8 +151,8 @@ struct l2c_init_data {
extern const struct command_registration arm7a_l2x_cache_command_handler[];
-int armv7a_l2x_cache_flush_virt(struct target *target, uint32_t virt,
+int armv7a_l2x_cache_flush_virt(struct target *target, target_addr_t virt,
uint32_t size);
int arm7a_l2x_flush_all_data(struct target *target);
-#endif
+#endif /* OPENOCD_TARGET_ARM7A_CACHE_L2X_H */
diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index 15de8cd9c..e0911c30f 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -22,9 +22,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
* *
* ARMv7-M Architecture, Application Level Reference Manual *
* ARM DDI 0405C (September 2008) *
@@ -320,7 +318,7 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
int armv7m_run_algorithm(struct target *target,
int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params,
- uint32_t entry_point, uint32_t exit_point,
+ target_addr_t entry_point, target_addr_t exit_point,
int timeout_ms, void *arch_info)
{
int retval;
@@ -345,7 +343,7 @@ int armv7m_run_algorithm(struct target *target,
int armv7m_start_algorithm(struct target *target,
int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params,
- uint32_t entry_point, uint32_t exit_point,
+ target_addr_t entry_point, target_addr_t exit_point,
void *arch_info)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
@@ -433,7 +431,7 @@ int armv7m_start_algorithm(struct target *target,
int armv7m_wait_algorithm(struct target *target,
int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params,
- uint32_t exit_point, int timeout_ms,
+ target_addr_t exit_point, int timeout_ms,
void *arch_info)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
@@ -463,7 +461,7 @@ int armv7m_wait_algorithm(struct target *target,
armv7m->load_core_reg_u32(target, 15, &pc);
if (exit_point && (pc != exit_point)) {
- LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" PRIx32,
+ LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" TARGET_PRIxADDR,
pc,
exit_point);
return ERROR_TARGET_TIMEOUT;
@@ -538,11 +536,15 @@ int armv7m_arch_state(struct target *target)
struct arm *arm = &armv7m->arm;
uint32_t ctrl, sp;
+ /* avoid filling log waiting for fileio reply */
+ if (arm->semihosting_hit_fileio)
+ return ERROR_OK;
+
ctrl = buf_get_u32(arm->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 32);
sp = buf_get_u32(arm->core_cache->reg_list[ARMV7M_R13].value, 0, 32);
LOG_USER("target halted due to %s, current mode: %s %s\n"
- "xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32 "%s",
+ "xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32 "%s%s",
debug_reason_name(target),
arm_mode_name(arm->core_mode),
armv7m_exception_string(armv7m->exception_number),
@@ -550,7 +552,8 @@ int armv7m_arch_state(struct target *target)
buf_get_u32(arm->pc->value, 0, 32),
(ctrl & 0x02) ? 'p' : 'm',
sp,
- arm->is_semihosting ? ", semihosting" : "");
+ arm->is_semihosting ? ", semihosting" : "",
+ arm->is_semihosting_fileio ? " fileio" : "");
return ERROR_OK;
}
@@ -679,47 +682,15 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m)
/** Generates a CRC32 checksum of a memory region. */
int armv7m_checksum_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *checksum)
+ target_addr_t address, uint32_t count, uint32_t *checksum)
{
struct working_area *crc_algorithm;
struct armv7m_algorithm armv7m_info;
struct reg_param reg_params[2];
int retval;
- /* see contrib/loaders/checksum/armv7m_crc.s for src */
-
static const uint8_t cortex_m_crc_code[] = {
- /* main: */
- 0x02, 0x46, /* mov r2, r0 */
- 0x00, 0x20, /* movs r0, #0 */
- 0xC0, 0x43, /* mvns r0, r0 */
- 0x0A, 0x4E, /* ldr r6, CRC32XOR */
- 0x0B, 0x46, /* mov r3, r1 */
- 0x00, 0x24, /* movs r4, #0 */
- 0x0D, 0xE0, /* b ncomp */
- /* nbyte: */
- 0x11, 0x5D, /* ldrb r1, [r2, r4] */
- 0x09, 0x06, /* lsls r1, r1, #24 */
- 0x48, 0x40, /* eors r0, r0, r1 */
- 0x00, 0x25, /* movs r5, #0 */
- /* loop: */
- 0x00, 0x28, /* cmp r0, #0 */
- 0x02, 0xDA, /* bge notset */
- 0x40, 0x00, /* lsls r0, r0, #1 */
- 0x70, 0x40, /* eors r0, r0, r6 */
- 0x00, 0xE0, /* b cont */
- /* notset: */
- 0x40, 0x00, /* lsls r0, r0, #1 */
- /* cont: */
- 0x01, 0x35, /* adds r5, r5, #1 */
- 0x08, 0x2D, /* cmp r5, #8 */
- 0xF6, 0xD1, /* bne loop */
- 0x01, 0x34, /* adds r4, r4, #1 */
- /* ncomp: */
- 0x9C, 0x42, /* cmp r4, r3 */
- 0xEF, 0xD1, /* bne nbyte */
- 0x00, 0xBE, /* bkpt #0 */
- 0xB7, 0x1D, 0xC1, 0x04 /* CRC32XOR: .word 0x04c11db7 */
+#include "../../contrib/loaders/checksum/armv7m_crc.inc"
};
retval = target_alloc_working_area(target, sizeof(cortex_m_crc_code), &crc_algorithm);
@@ -760,36 +731,44 @@ int armv7m_checksum_memory(struct target *target,
return retval;
}
-/** Checks whether a memory region is zeroed. */
+/** Checks whether a memory region is erased. */
int armv7m_blank_check_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *blank)
+ target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
{
struct working_area *erase_check_algorithm;
struct reg_param reg_params[3];
struct armv7m_algorithm armv7m_info;
+ const uint8_t *code;
+ uint32_t code_size;
int retval;
- /* see contrib/loaders/erase_check/armv7m_erase_check.s for src */
-
static const uint8_t erase_check_code[] = {
- /* loop: */
- 0x03, 0x78, /* ldrb r3, [r0] */
- 0x01, 0x30, /* adds r0, #1 */
- 0x1A, 0x40, /* ands r2, r2, r3 */
- 0x01, 0x39, /* subs r1, r1, #1 */
- 0xFA, 0xD1, /* bne loop */
- 0x00, 0xBE /* bkpt #0 */
+#include "../../contrib/loaders/erase_check/armv7m_erase_check.inc"
+ };
+ static const uint8_t zero_erase_check_code[] = {
+#include "../../contrib/loaders/erase_check/armv7m_0_erase_check.inc"
};
+ switch (erased_value) {
+ case 0x00:
+ code = zero_erase_check_code;
+ code_size = sizeof(zero_erase_check_code);
+ break;
+ case 0xff:
+ default:
+ code = erase_check_code;
+ code_size = sizeof(erase_check_code);
+ }
+
/* make sure we have a working area */
- if (target_alloc_working_area(target, sizeof(erase_check_code),
+ if (target_alloc_working_area(target, code_size,
&erase_check_algorithm) != ERROR_OK)
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
retval = target_write_buffer(target, erase_check_algorithm->address,
- sizeof(erase_check_code), (uint8_t *)erase_check_code);
+ code_size, code);
if (retval != ERROR_OK)
- return retval;
+ goto cleanup;
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
armv7m_info.core_mode = ARM_MODE_THREAD;
@@ -801,7 +780,7 @@ int armv7m_blank_check_memory(struct target *target,
buf_set_u32(reg_params[1].value, 0, 32, count);
init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT);
- buf_set_u32(reg_params[2].value, 0, 32, 0xff);
+ buf_set_u32(reg_params[2].value, 0, 32, erased_value);
retval = target_run_algorithm(target,
0,
@@ -809,7 +788,7 @@ int armv7m_blank_check_memory(struct target *target,
3,
reg_params,
erase_check_algorithm->address,
- erase_check_algorithm->address + (sizeof(erase_check_code) - 2),
+ erase_check_algorithm->address + (code_size - 2),
10000,
&armv7m_info);
@@ -820,6 +799,7 @@ int armv7m_blank_check_memory(struct target *target,
destroy_reg_param(®_params[1]);
destroy_reg_param(®_params[2]);
+cleanup:
target_free_working_area(target, erase_check_algorithm);
return retval;
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index 65a2ef059..284bb9caa 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARMV7M_COMMON_H
-#define ARMV7M_COMMON_H
+#ifndef OPENOCD_TARGET_ARMV7M_H
+#define OPENOCD_TARGET_ARMV7M_H
#include "arm_adi_v5.h"
#include "arm.h"
@@ -134,6 +132,8 @@ enum {
enum {
FP_NONE = 0,
FPv4_SP,
+ FPv5_SP,
+ FPv5_DP,
};
#define ARMV7M_NUM_CORE_REGS (ARMV7M_xPSR + 1)
@@ -203,19 +203,19 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m);
int armv7m_run_algorithm(struct target *target,
int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params,
- uint32_t entry_point, uint32_t exit_point,
+ target_addr_t entry_point, target_addr_t exit_point,
int timeout_ms, void *arch_info);
int armv7m_start_algorithm(struct target *target,
int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params,
- uint32_t entry_point, uint32_t exit_point,
+ target_addr_t entry_point, target_addr_t exit_point,
void *arch_info);
int armv7m_wait_algorithm(struct target *target,
int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params,
- uint32_t exit_point, int timeout_ms,
+ target_addr_t exit_point, int timeout_ms,
void *arch_info);
int armv7m_invalidate_core_regs(struct target *target);
@@ -223,12 +223,12 @@ int armv7m_invalidate_core_regs(struct target *target);
int armv7m_restore_context(struct target *target);
int armv7m_checksum_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *checksum);
+ target_addr_t address, uint32_t count, uint32_t *checksum);
int armv7m_blank_check_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *blank);
+ target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value);
int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found);
extern const struct command_registration armv7m_command_handlers[];
-#endif /* ARMV7M_H */
+#endif /* OPENOCD_TARGET_ARMV7M_H */
diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c
index 3592bad0f..c1e4f5baa 100644
--- a/src/target/armv7m_trace.c
+++ b/src/target/armv7m_trace.c
@@ -10,6 +10,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/armv7m_trace.h b/src/target/armv7m_trace.h
index eae72f557..4f9939464 100644
--- a/src/target/armv7m_trace.h
+++ b/src/target/armv7m_trace.h
@@ -10,10 +10,13 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ARMV7M_TRACE_H
-#define ARMV7M_TRACE_H
+#ifndef OPENOCD_TARGET_ARMV7M_TRACE_H
+#define OPENOCD_TARGET_ARMV7M_TRACE_H
#include
#include
@@ -85,4 +88,4 @@ int armv7m_trace_tpiu_config(struct target *target);
*/
int armv7m_trace_itm_config(struct target *target);
-#endif
+#endif /* OPENOCD_TARGET_ARMV7M_TRACE_H */
diff --git a/src/target/avr32_ap7k.c b/src/target/avr32_ap7k.c
index 55d1efb4c..f8da8d5ac 100644
--- a/src/target/avr32_ap7k.c
+++ b/src/target/avr32_ap7k.c
@@ -15,9 +15,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -314,7 +312,7 @@ static int avr32_ap7k_deassert_reset(struct target *target)
}
static int avr32_ap7k_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints, int debug_execution)
{
struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
struct breakpoint *breakpoint = NULL;
@@ -350,7 +348,7 @@ static int avr32_ap7k_resume(struct target *target, int current,
/* Single step past breakpoint at current address */
breakpoint = breakpoint_find(target, resume_pc);
if (breakpoint) {
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+ LOG_DEBUG("unset breakpoint at 0x%8.8" TARGET_PRIxADDR "", breakpoint->address);
#if 0
avr32_ap7k_unset_breakpoint(target, breakpoint);
avr32_ap7k_single_step_core(target);
@@ -396,7 +394,7 @@ static int avr32_ap7k_resume(struct target *target, int current,
}
static int avr32_ap7k_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
LOG_ERROR("%s: implement me", __func__);
@@ -433,12 +431,12 @@ static int avr32_ap7k_remove_watchpoint(struct target *target,
return ERROR_OK;
}
-static int avr32_ap7k_read_memory(struct target *target, uint32_t address,
+static int avr32_ap7k_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
+ LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
address,
size,
count);
@@ -474,12 +472,12 @@ static int avr32_ap7k_read_memory(struct target *target, uint32_t address,
return ERROR_OK;
}
-static int avr32_ap7k_write_memory(struct target *target, uint32_t address,
+static int avr32_ap7k_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
+ LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
address,
size,
count);
diff --git a/src/target/avr32_ap7k.h b/src/target/avr32_ap7k.h
index 1f952eb86..3f27534a3 100644
--- a/src/target/avr32_ap7k.h
+++ b/src/target/avr32_ap7k.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef AVR32_AP7K
-#define AVR32_AP7K
+#ifndef OPENOCD_TARGET_AVR32_AP7K_H
+#define OPENOCD_TARGET_AVR32_AP7K_H
struct target;
@@ -42,4 +40,4 @@ struct avr32_core_reg {
struct avr32_ap7k_common *avr32_common;
};
-#endif /*AVR32_AP7K*/
+#endif /* OPENOCD_TARGET_AVR32_AP7K_H */
diff --git a/src/target/avr32_jtag.c b/src/target/avr32_jtag.c
index 647afd5e4..6526810e2 100644
--- a/src/target/avr32_jtag.c
+++ b/src/target/avr32_jtag.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/avr32_jtag.h b/src/target/avr32_jtag.h
index b5fdeafa7..b431ef4c8 100644
--- a/src/target/avr32_jtag.h
+++ b/src/target/avr32_jtag.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef AVR32_JTAG
-#define AVR32_JTAG
+#ifndef OPENOCD_TARGET_AVR32_JTAG_H
+#define OPENOCD_TARGET_AVR32_JTAG_H
#define AVR32NUMCOREREGS 17
@@ -102,4 +100,4 @@ int avr32_ocd_clearbits(struct avr32_jtag *jtag, int reg, uint32_t bits);
int avr32_jtag_exec(struct avr32_jtag *jtag_info, uint32_t inst);
-#endif /* AVR32_JTAG */
+#endif /* OPENOCD_TARGET_AVR32_JTAG_H */
diff --git a/src/target/avr32_mem.c b/src/target/avr32_mem.c
index a7797a292..71ec0b431 100644
--- a/src/target/avr32_mem.c
+++ b/src/target/avr32_mem.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/avr32_mem.h b/src/target/avr32_mem.h
index 4c36bdb31..f60a12179 100644
--- a/src/target/avr32_mem.h
+++ b/src/target/avr32_mem.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef AVR32_MEM
-#define AVR32_MEM
+#ifndef OPENOCD_TARGET_AVR32_MEM_H
+#define OPENOCD_TARGET_AVR32_MEM_H
int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info,
uint32_t addr, int count, uint32_t *buffer);
@@ -34,4 +32,4 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,
int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,
uint32_t addr, int count, const uint8_t *buffer);
-#endif /* AVR32_MEM */
+#endif /* OPENOCD_TARGET_AVR32_MEM_H */
diff --git a/src/target/avr32_regs.c b/src/target/avr32_regs.c
index 901f4fed7..7273822c2 100644
--- a/src/target/avr32_regs.c
+++ b/src/target/avr32_regs.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/avr32_regs.h b/src/target/avr32_regs.h
index 6590dec9c..cb492a9fe 100644
--- a/src/target/avr32_regs.h
+++ b/src/target/avr32_regs.h
@@ -12,13 +12,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef AVR32_REGS
-#define AVR32_REGS
+#ifndef OPENOCD_TARGET_AVR32_REGS_H
+#define OPENOCD_TARGET_AVR32_REGS_H
enum avr32_reg_nums {
AVR32_REG_R0 = 0,
@@ -43,4 +41,4 @@ enum avr32_reg_nums {
int avr32_jtag_read_regs(struct avr32_jtag *jtag_info, uint32_t *regs);
int avr32_jtag_write_regs(struct avr32_jtag *jtag_info, uint32_t *regs);
-#endif /* AVR32_REGS */
+#endif /* OPENOCD_TARGET_AVR32_REGS_H */
diff --git a/src/target/avrt.c b/src/target/avrt.c
index a4ce46b78..1e1898c7e 100644
--- a/src/target/avrt.c
+++ b/src/target/avrt.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -35,9 +33,9 @@ static int avr_init_target(struct command_context *cmd_ctx, struct target *targe
static int avr_arch_state(struct target *target);
static int avr_poll(struct target *target);
static int avr_halt(struct target *target);
-static int avr_resume(struct target *target, int current, uint32_t address,
+static int avr_resume(struct target *target, int current, target_addr_t address,
int handle_breakpoints, int debug_execution);
-static int avr_step(struct target *target, int current, uint32_t address,
+static int avr_step(struct target *target, int current, target_addr_t address,
int handle_breakpoints);
static int avr_assert_reset(struct target *target);
@@ -118,14 +116,14 @@ static int avr_halt(struct target *target)
return ERROR_OK;
}
-static int avr_resume(struct target *target, int current, uint32_t address,
+static int avr_resume(struct target *target, int current, target_addr_t address,
int handle_breakpoints, int debug_execution)
{
LOG_DEBUG("%s", __func__);
return ERROR_OK;
}
-static int avr_step(struct target *target, int current, uint32_t address, int handle_breakpoints)
+static int avr_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
{
LOG_DEBUG("%s", __func__);
return ERROR_OK;
diff --git a/src/target/avrt.h b/src/target/avrt.h
index 707b48160..3610eb5e3 100644
--- a/src/target/avrt.h
+++ b/src/target/avrt.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef AVRT_H
-#define AVRT_H
+#ifndef OPENOCD_TARGET_AVRT_H
+#define OPENOCD_TARGET_AVRT_H
#include
@@ -36,4 +34,4 @@ int avr_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out);
int avr_jtag_senddat(struct jtag_tap *tap, uint32_t *dr_in, uint32_t dr_out,
int len);
-#endif /* AVRT_H */
+#endif /* OPENOCD_TARGET_AVRT_H */
diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c
index b854f1f05..7cf4a6957 100644
--- a/src/target/breakpoints.c
+++ b/src/target/breakpoints.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -44,7 +42,7 @@ static const char * const watchpoint_rw_strings[] = {
static int bpwp_unique_id;
int breakpoint_add_internal(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t length,
enum breakpoint_type type)
{
@@ -62,7 +60,7 @@ int breakpoint_add_internal(struct target *target,
* breakpoint" ... check all the parameters before
* succeeding.
*/
- LOG_DEBUG("Duplicate Breakpoint address: 0x%08" PRIx32 " (BP %" PRIu32 ")",
+ LOG_DEBUG("Duplicate Breakpoint address: " TARGET_ADDR_FMT " (BP %" PRIu32 ")",
address, breakpoint->unique_id);
return ERROR_OK;
}
@@ -100,7 +98,7 @@ int breakpoint_add_internal(struct target *target,
return retval;
}
- LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %" PRIu32 ")",
+ LOG_DEBUG("added %s breakpoint at " TARGET_ADDR_FMT " of length 0x%8.8x, (BPID: %" PRIu32 ")",
breakpoint_type_strings[(*breakpoint_p)->type],
(*breakpoint_p)->address, (*breakpoint_p)->length,
(*breakpoint_p)->unique_id);
@@ -161,7 +159,7 @@ int context_breakpoint_add_internal(struct target *target,
}
int hybrid_breakpoint_add_internal(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t asid,
uint32_t length,
enum breakpoint_type type)
@@ -182,7 +180,7 @@ int hybrid_breakpoint_add_internal(struct target *target,
asid, breakpoint->unique_id);
return -1;
} else if ((breakpoint->address == address) && (breakpoint->asid == 0)) {
- LOG_DEBUG("Duplicate Breakpoint IVA: 0x%08" PRIx32 " (BP %" PRIu32 ")",
+ LOG_DEBUG("Duplicate Breakpoint IVA: " TARGET_ADDR_FMT " (BP %" PRIu32 ")",
address, breakpoint->unique_id);
return -1;
@@ -210,7 +208,7 @@ int hybrid_breakpoint_add_internal(struct target *target,
return retval;
}
LOG_DEBUG(
- "added %s Hybrid breakpoint at address 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %" PRIu32 ")",
+ "added %s Hybrid breakpoint at address " TARGET_ADDR_FMT " of length 0x%8.8x, (BPID: %" PRIu32 ")",
breakpoint_type_strings[(*breakpoint_p)->type],
(*breakpoint_p)->address,
(*breakpoint_p)->length,
@@ -220,7 +218,7 @@ int hybrid_breakpoint_add_internal(struct target *target,
}
int breakpoint_add(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t length,
enum breakpoint_type type)
{
@@ -265,7 +263,7 @@ int context_breakpoint_add(struct target *target,
return context_breakpoint_add_internal(target, asid, length, type);
}
int hybrid_breakpoint_add(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t asid,
uint32_t length,
enum breakpoint_type type)
@@ -312,7 +310,7 @@ static void breakpoint_free(struct target *target, struct breakpoint *breakpoint
free(breakpoint);
}
-int breakpoint_remove_internal(struct target *target, uint32_t address)
+int breakpoint_remove_internal(struct target *target, target_addr_t address)
{
struct breakpoint *breakpoint = target->breakpoints;
@@ -331,11 +329,11 @@ int breakpoint_remove_internal(struct target *target, uint32_t address)
return 1;
} else {
if (!target->smp)
- LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address);
+ LOG_ERROR("no breakpoint at address " TARGET_ADDR_FMT " found", address);
return 0;
}
}
-void breakpoint_remove(struct target *target, uint32_t address)
+void breakpoint_remove(struct target *target, target_addr_t address)
{
int found = 0;
if (target->smp) {
@@ -348,7 +346,7 @@ void breakpoint_remove(struct target *target, uint32_t address)
head = head->next;
}
if (found == 0)
- LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address);
+ LOG_ERROR("no breakpoint at address " TARGET_ADDR_FMT " found", address);
} else
breakpoint_remove_internal(target, address);
}
@@ -377,7 +375,7 @@ void breakpoint_clear_target(struct target *target)
}
-struct breakpoint *breakpoint_find(struct target *target, uint32_t address)
+struct breakpoint *breakpoint_find(struct target *target, target_addr_t address)
{
struct breakpoint *breakpoint = target->breakpoints;
@@ -390,7 +388,7 @@ struct breakpoint *breakpoint_find(struct target *target, uint32_t address)
return NULL;
}
-int watchpoint_add(struct target *target, uint32_t address, uint32_t length,
+int watchpoint_add(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;
@@ -404,8 +402,8 @@ int watchpoint_add(struct target *target, uint32_t address, uint32_t length,
|| watchpoint->value != value
|| watchpoint->mask != mask
|| watchpoint->rw != rw) {
- LOG_ERROR("address 0x%8.8" PRIx32
- "already has watchpoint %d",
+ LOG_ERROR("address " TARGET_ADDR_FMT
+ " already has watchpoint %d",
address, watchpoint->unique_id);
return ERROR_FAIL;
}
@@ -438,7 +436,7 @@ int watchpoint_add(struct target *target, uint32_t address, uint32_t length,
default:
reason = "unrecognized error";
bye:
- LOG_ERROR("can't add %s watchpoint at 0x%8.8" PRIx32 ", %s",
+ LOG_ERROR("can't add %s watchpoint at " TARGET_ADDR_FMT ", %s",
watchpoint_rw_strings[(*watchpoint_p)->rw],
address, reason);
free(*watchpoint_p);
@@ -446,7 +444,7 @@ int watchpoint_add(struct target *target, uint32_t address, uint32_t length,
return retval;
}
- LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32
+ LOG_DEBUG("added %s watchpoint at " TARGET_ADDR_FMT
" of length 0x%8.8" PRIx32 " (WPID: %d)",
watchpoint_rw_strings[(*watchpoint_p)->rw],
(*watchpoint_p)->address,
@@ -477,7 +475,7 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint
free(watchpoint);
}
-void watchpoint_remove(struct target *target, uint32_t address)
+void watchpoint_remove(struct target *target, target_addr_t address)
{
struct watchpoint *watchpoint = target->watchpoints;
@@ -490,7 +488,7 @@ void watchpoint_remove(struct target *target, uint32_t address)
if (watchpoint)
watchpoint_free(target, watchpoint);
else
- LOG_ERROR("no watchpoint at address 0x%8.8" PRIx32 " found", address);
+ LOG_ERROR("no watchpoint at address " TARGET_ADDR_FMT " found", address);
}
void watchpoint_clear_target(struct target *target)
@@ -501,7 +499,8 @@ void watchpoint_clear_target(struct target *target)
watchpoint_free(target, target->watchpoints);
}
-int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, uint32_t *address)
+int watchpoint_hit(struct target *target, enum watchpoint_rw *rw,
+ target_addr_t *address)
{
int retval;
struct watchpoint *hit_watchpoint;
@@ -513,7 +512,7 @@ int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, uint32_t *addr
*rw = hit_watchpoint->rw;
*address = hit_watchpoint->address;
- LOG_DEBUG("Found hit watchpoint at 0x%8.8" PRIx32 " (WPID: %d)",
+ LOG_DEBUG("Found hit watchpoint at " TARGET_ADDR_FMT " (WPID: %d)",
hit_watchpoint->address,
hit_watchpoint->unique_id);
diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h
index 0246acd3d..51bd05abd 100644
--- a/src/target/breakpoints.h
+++ b/src/target/breakpoints.h
@@ -13,13 +13,13 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef BREAKPOINTS_H
-#define BREAKPOINTS_H
+#ifndef OPENOCD_TARGET_BREAKPOINTS_H
+#define OPENOCD_TARGET_BREAKPOINTS_H
+
+#include
struct target;
@@ -33,7 +33,7 @@ enum watchpoint_rw {
};
struct breakpoint {
- uint32_t address;
+ target_addr_t address;
uint32_t asid;
int length;
enum breakpoint_type type;
@@ -45,7 +45,7 @@ struct breakpoint {
};
struct watchpoint {
- uint32_t address;
+ target_addr_t address;
uint32_t length;
uint32_t mask;
uint32_t value;
@@ -57,22 +57,23 @@ struct watchpoint {
void breakpoint_clear_target(struct target *target);
int breakpoint_add(struct target *target,
- uint32_t address, uint32_t length, enum breakpoint_type type);
+ target_addr_t address, uint32_t length, enum breakpoint_type type);
int context_breakpoint_add(struct target *target,
uint32_t asid, uint32_t length, enum breakpoint_type type);
int hybrid_breakpoint_add(struct target *target,
- uint32_t address, uint32_t asid, uint32_t length, enum breakpoint_type type);
-void breakpoint_remove(struct target *target, uint32_t address);
+ target_addr_t address, uint32_t asid, uint32_t length, enum breakpoint_type type);
+void breakpoint_remove(struct target *target, target_addr_t address);
-struct breakpoint *breakpoint_find(struct target *target, uint32_t address);
+struct breakpoint *breakpoint_find(struct target *target, target_addr_t address);
void watchpoint_clear_target(struct target *target);
int watchpoint_add(struct target *target,
- uint32_t address, uint32_t length,
+ target_addr_t address, uint32_t length,
enum watchpoint_rw rw, uint32_t value, uint32_t mask);
-void watchpoint_remove(struct target *target, uint32_t address);
+void watchpoint_remove(struct target *target, target_addr_t address);
/* report type and address of just hit watchpoint */
-int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, uint32_t *address);
+int watchpoint_hit(struct target *target, enum watchpoint_rw *rw,
+ target_addr_t *address);
-#endif /* BREAKPOINTS_H */
+#endif /* OPENOCD_TARGET_BREAKPOINTS_H */
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 8a0d38bca..5d90e3416 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -18,7 +18,7 @@
* michel.jaouen@stericsson.com : smp minimum support *
* *
* Copyright (C) Broadcom 2012 *
- * ehunter@broadcom.com : Cortex R4 support *
+ * ehunter@broadcom.com : Cortex-R4 support *
* *
* Copyright (C) 2013 Kamal Dasu *
* kdasu.kdev@gmail.com *
@@ -34,9 +34,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
* *
* Cortex-A8(tm) TRM, ARM DDI 0344H *
* Cortex-A9(tm) TRM, ARM DDI 0407F *
@@ -55,6 +53,8 @@
#include "target_request.h"
#include "target_type.h"
#include "arm_opcodes.h"
+#include "arm_semihosting.h"
+#include "jtag/swd.h"
#include
static int cortex_a_poll(struct target *target);
@@ -75,8 +75,8 @@ static int cortex_a_dap_write_coreregister_u32(struct target *target,
static int cortex_a_mmu(struct target *target, int *enabled);
static int cortex_a_mmu_modify(struct target *target, int enable);
static int cortex_a_virt2phys(struct target *target,
- uint32_t virt, uint32_t *phys);
-static int cortex_a_read_apb_ab_memory(struct target *target,
+ target_addr_t virt, target_addr_t *phys);
+static int cortex_a_read_cpu_memory(struct target *target,
uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
@@ -196,32 +196,6 @@ static int cortex_a_mmu_modify(struct target *target, int enable)
return retval;
}
-/*
- * Cortex-A Basic debug access, very low level assumes state is saved
- */
-static int cortex_a8_init_debug_access(struct target *target)
-{
- struct armv7a_common *armv7a = target_to_armv7a(target);
- int retval;
-
- LOG_DEBUG(" ");
-
- /* Unlocking the debug registers for modification
- * The debugport might be uninitialised so try twice */
- retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
- if (retval != ERROR_OK) {
- /* try again */
- retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
- if (retval == ERROR_OK)
- LOG_USER(
- "Locking debug access failed on first, but succeeded on second try.");
- }
-
- return retval;
-}
-
/*
* Cortex-A Basic debug access, very low level assumes state is saved
*/
@@ -229,47 +203,11 @@ static int cortex_a_init_debug_access(struct target *target)
{
struct armv7a_common *armv7a = target_to_armv7a(target);
int retval;
- uint32_t dbg_osreg;
- uint32_t cortex_part_num;
- struct cortex_a_common *cortex_a = target_to_cortex_a(target);
-
- LOG_DEBUG(" ");
- cortex_part_num = (cortex_a->cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >>
- CORTEX_A_MIDR_PARTNUM_SHIFT;
-
- switch (cortex_part_num) {
- case CORTEX_A7_PARTNUM:
- case CORTEX_A15_PARTNUM:
- retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_OSLSR,
- &dbg_osreg);
- if (retval != ERROR_OK)
- return retval;
-
- LOG_DEBUG("DBGOSLSR 0x%" PRIx32, dbg_osreg);
-
- if (dbg_osreg & CPUDBG_OSLAR_LK_MASK)
- /* Unlocking the DEBUG OS registers for modification */
- retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_OSLAR,
- 0);
- break;
-
- case CORTEX_A5_PARTNUM:
- case CORTEX_A8_PARTNUM:
- case CORTEX_A9_PARTNUM:
- default:
- retval = cortex_a8_init_debug_access(target);
- }
-
- if (retval != ERROR_OK)
- return retval;
- /* Clear Sticky Power Down status Bit in PRSR to enable access to
- the registers in the Core Power Domain */
- retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg);
- LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR 0x%" PRIx32, target->coreid, dbg_osreg);
+ /* lock memory-mapped access to debug registers to prevent
+ * software interference */
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_LOCKACCESS, 0);
if (retval != ERROR_OK)
return retval;
@@ -299,7 +237,7 @@ static int cortex_a_wait_instrcmpl(struct target *target, uint32_t *dscr, bool f
* Writes final value of DSCR into *dscr. Pass force to force always
* reading DSCR at least once. */
struct armv7a_common *armv7a = target_to_armv7a(target);
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
while ((*dscr & DSCR_INSTR_COMP) == 0 || force) {
force = false;
int retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
@@ -342,7 +280,7 @@ static int cortex_a_exec_opcode(struct target *target,
if (retval != ERROR_OK)
return retval;
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
do {
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DSCR, &dscr);
@@ -431,7 +369,7 @@ static int cortex_a_dap_read_coreregister_u32(struct target *target,
}
/* Wait for DTRRXfull then read DTRRTX */
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
while ((dscr & DSCR_DTR_TX_FULL) == 0) {
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DSCR, &dscr);
@@ -574,7 +512,7 @@ static int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data,
dscr = *dscr_p;
/* Wait for DTRRXfull */
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
while ((dscr & DSCR_DTR_TX_FULL) == 0) {
retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
a->armv7a_common.debug_base + CPUDBG_DSCR,
@@ -606,7 +544,7 @@ static int cortex_a_dpm_prepare(struct arm_dpm *dpm)
int retval;
/* set up invariant: INSTR_COMP is set after ever DPM operation */
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
for (;; ) {
retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
a->armv7a_common.debug_base + CPUDBG_DSCR,
@@ -854,7 +792,8 @@ static int cortex_a_halt_smp(struct target *target)
head = target->head;
while (head != (struct target_list *)NULL) {
curr = head->target;
- if ((curr != target) && (curr->state != TARGET_HALTED))
+ if ((curr != target) && (curr->state != TARGET_HALTED)
+ && target_was_examined(curr))
retval += cortex_a_halt(curr);
head = head->next;
}
@@ -917,6 +856,10 @@ static int cortex_a_poll(struct target *target)
if (retval != ERROR_OK)
return retval;
}
+
+ if (arm_semihosting(target, &retval) != 0)
+ return retval;
+
target_call_event_callbacks(target,
TARGET_EVENT_HALTED);
}
@@ -936,12 +879,8 @@ static int cortex_a_poll(struct target *target)
TARGET_EVENT_DEBUG_HALTED);
}
}
- } else if (DSCR_RUN_MODE(dscr) == DSCR_CORE_RESTARTED)
+ } else
target->state = TARGET_RUNNING;
- else {
- LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32, dscr);
- target->state = TARGET_UNKNOWN;
- }
return retval;
}
@@ -974,7 +913,7 @@ static int cortex_a_halt(struct target *target)
if (retval != ERROR_OK)
return retval;
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
for (;; ) {
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DSCR, &dscr);
@@ -994,7 +933,7 @@ static int cortex_a_halt(struct target *target)
}
static int cortex_a_internal_restore(struct target *target, int current,
- uint32_t *address, int handle_breakpoints, int debug_execution)
+ target_addr_t *address, int handle_breakpoints, int debug_execution)
{
struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm *arm = &armv7a->arm;
@@ -1049,6 +988,9 @@ static int cortex_a_internal_restore(struct target *target, int current,
case ARM_STATE_JAZELLE:
LOG_ERROR("How do I resume into Jazelle state??");
return ERROR_FAIL;
+ case ARM_STATE_AARCH64:
+ LOG_ERROR("Shoudn't be in AARCH64 state");
+ return ERROR_FAIL;
}
LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
buf_set_u32(arm->pc->value, 0, 32, resume_pc);
@@ -1121,7 +1063,7 @@ static int cortex_a_internal_restart(struct target *target)
if (retval != ERROR_OK)
return retval;
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
for (;; ) {
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DSCR, &dscr);
@@ -1149,11 +1091,12 @@ static int cortex_a_restore_smp(struct target *target, int handle_breakpoints)
int retval = 0;
struct target_list *head;
struct target *curr;
- uint32_t address;
+ target_addr_t address;
head = target->head;
while (head != (struct target_list *)NULL) {
curr = head->target;
- if ((curr != target) && (curr->state != TARGET_RUNNING)) {
+ if ((curr != target) && (curr->state != TARGET_RUNNING)
+ && target_was_examined(curr)) {
/* resume current address , not in step mode */
retval += cortex_a_internal_restore(curr, 1, &address,
handle_breakpoints, 0);
@@ -1166,7 +1109,7 @@ static int cortex_a_restore_smp(struct target *target, int handle_breakpoints)
}
static int cortex_a_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints, int debug_execution)
{
int retval = 0;
/* dummy resume for smp toggle in order to reduce gdb impact */
@@ -1190,11 +1133,11 @@ static int cortex_a_resume(struct target *target, int current,
if (!debug_execution) {
target->state = TARGET_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
- LOG_DEBUG("target resumed at 0x%" PRIx32, address);
+ LOG_DEBUG("target resumed at " TARGET_ADDR_FMT, address);
} else {
target->state = TARGET_DEBUG_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
- LOG_DEBUG("target debug resumed at 0x%" PRIx32, address);
+ LOG_DEBUG("target debug resumed at " TARGET_ADDR_FMT, address);
}
return ERROR_OK;
@@ -1203,7 +1146,7 @@ static int cortex_a_resume(struct target *target, int current,
static int cortex_a_debug_entry(struct target *target)
{
int i;
- uint32_t regfile[16], cpsr, dscr;
+ uint32_t regfile[16], cpsr, spsr, dscr;
int retval = ERROR_OK;
struct working_area *regfile_working_area = NULL;
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
@@ -1252,6 +1195,7 @@ static int cortex_a_debug_entry(struct target *target)
if (cortex_a->fast_reg_read)
target_alloc_working_area(target, 64, ®file_working_area);
+
/* First load register acessible through core debug port*/
if (!regfile_working_area)
retval = arm_dpm_read_current_registers(&armv7a->dpm);
@@ -1296,6 +1240,19 @@ static int cortex_a_debug_entry(struct target *target)
reg->dirty = reg->valid;
}
+ if (arm->spsr) {
+ /* read Saved PSR */
+ retval = cortex_a_dap_read_coreregister_u32(target, &spsr, 17);
+ /* store current spsr */
+ if (retval != ERROR_OK)
+ return retval;
+
+ reg = arm->spsr;
+ buf_set_u32(reg->value, 0, 32, spsr);
+ reg->valid = 1;
+ reg->dirty = 0;
+ }
+
#if 0
/* TODO, Move this */
uint32_t cp15_control_register, cp15_cacr, cp15_nacr;
@@ -1386,7 +1343,7 @@ int cortex_a_set_dscr_bits(struct target *target, unsigned long bit_mask, unsign
return retval;
}
-static int cortex_a_step(struct target *target, int current, uint32_t address,
+static int cortex_a_step(struct target *target, int current, target_addr_t address,
int handle_breakpoints)
{
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
@@ -1443,7 +1400,7 @@ static int cortex_a_step(struct target *target, int current, uint32_t address,
if (retval != ERROR_OK)
return retval;
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
while (target->state != TARGET_HALTED) {
retval = cortex_a_poll(target);
if (retval != ERROR_OK)
@@ -1903,6 +1860,8 @@ static int cortex_a_assert_reset(struct target *target)
/* FIXME when halt is requested, make it work somehow... */
+ /* This function can be called in "target not examined" state */
+
/* Issue some kind of warm reset. */
if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
@@ -1910,14 +1869,23 @@ static int cortex_a_assert_reset(struct target *target)
/* REVISIT handle "pulls" cases, if there's
* hardware that needs them to work.
*/
- jtag_add_reset(0, 1);
+
+ /*
+ * FIXME: fix reset when transport is SWD. This is a temporary
+ * work-around for release v0.10 that is not intended to stay!
+ */
+ if (transport_is_swd() ||
+ (target->reset_halt && (jtag_get_reset_config() & RESET_SRST_NO_GATING)))
+ jtag_add_reset(0, 1);
+
} else {
LOG_ERROR("%s: how to reset?", target_name(target));
return ERROR_FAIL;
}
/* registers are now invalid */
- register_cache_invalidate(armv7a->arm.core_cache);
+ if (target_was_examined(target))
+ register_cache_invalidate(armv7a->arm.core_cache);
target->state = TARGET_RESET;
@@ -1933,17 +1901,22 @@ static int cortex_a_deassert_reset(struct target *target)
/* be certain SRST is off */
jtag_add_reset(0, 0);
- retval = cortex_a_poll(target);
- if (retval != ERROR_OK)
- return retval;
+ if (target_was_examined(target)) {
+ retval = cortex_a_poll(target);
+ if (retval != ERROR_OK)
+ return retval;
+ }
if (target->reset_halt) {
if (target->state != TARGET_HALTED) {
LOG_WARNING("%s: ran after reset and before halt ...",
target_name(target));
- retval = target_halt(target);
- if (retval != ERROR_OK)
- return retval;
+ if (target_was_examined(target)) {
+ retval = target_halt(target);
+ if (retval != ERROR_OK)
+ return retval;
+ } else
+ target->state = TARGET_UNKNOWN;
}
}
@@ -1977,7 +1950,7 @@ static int cortex_a_wait_dscr_bits(struct target *target, uint32_t mask,
{
/* Waits until the specified bit(s) of DSCR take on a specified value. */
struct armv7a_common *armv7a = target_to_armv7a(target);
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
int retval;
while ((*dscr & mask) != value) {
@@ -2123,13 +2096,13 @@ static int cortex_a_dfsr_to_error_code(uint32_t dfsr)
}
}
-static int cortex_a_write_apb_ab_memory_slow(struct target *target,
+static int cortex_a_write_cpu_memory_slow(struct target *target,
uint32_t size, uint32_t count, const uint8_t *buffer, uint32_t *dscr)
{
/* Writes count objects of size size from *buffer. Old value of DSCR must
* be in *dscr; updated to new value. This is slow because it works for
* non-word-sized objects and (maybe) unaligned accesses. If size == 4 and
- * the address is aligned, cortex_a_write_apb_ab_memory_fast should be
+ * the address is aligned, cortex_a_write_cpu_memory_fast should be
* preferred.
* Preconditions:
* - Address is in R0.
@@ -2198,7 +2171,7 @@ static int cortex_a_write_apb_ab_memory_slow(struct target *target,
return ERROR_OK;
}
-static int cortex_a_write_apb_ab_memory_fast(struct target *target,
+static int cortex_a_write_cpu_memory_fast(struct target *target,
uint32_t count, const uint8_t *buffer, uint32_t *dscr)
{
/* Writes count objects of size 4 from *buffer. Old value of DSCR must be
@@ -2227,17 +2200,17 @@ static int cortex_a_write_apb_ab_memory_fast(struct target *target,
4, count, armv7a->debug_base + CPUDBG_DTRRX);
}
-static int cortex_a_write_apb_ab_memory(struct target *target,
+static int cortex_a_write_cpu_memory(struct target *target,
uint32_t address, uint32_t size,
uint32_t count, const uint8_t *buffer)
{
- /* Write memory through APB-AP. */
+ /* Write memory through the CPU. */
int retval, final_retval;
struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm *arm = &armv7a->arm;
uint32_t dscr, orig_dfar, orig_dfsr, fault_dscr, fault_dfar, fault_dfsr;
- LOG_DEBUG("Writing APB-AP memory address 0x%" PRIx32 " size %" PRIu32 " count %" PRIu32,
+ LOG_DEBUG("Writing CPU memory address 0x%" PRIx32 " size %" PRIu32 " count %" PRIu32,
address, size, count);
if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted");
@@ -2283,10 +2256,10 @@ static int cortex_a_write_apb_ab_memory(struct target *target,
if (size == 4 && (address % 4) == 0) {
/* We are doing a word-aligned transfer, so use fast mode. */
- retval = cortex_a_write_apb_ab_memory_fast(target, count, buffer, &dscr);
+ retval = cortex_a_write_cpu_memory_fast(target, count, buffer, &dscr);
} else {
/* Use slow path. */
- retval = cortex_a_write_apb_ab_memory_slow(target, size, count, buffer, &dscr);
+ retval = cortex_a_write_cpu_memory_slow(target, size, count, buffer, &dscr);
}
out:
@@ -2305,7 +2278,7 @@ static int cortex_a_write_apb_ab_memory(struct target *target,
/* Wait until DTRRX is empty (according to ARMv7-A/-R architecture manual
* section C8.4.3, checking InstrCmpl_l is not sufficient; one must also
* check RXfull_l). Most of the time this will be free because RXfull_l
- * will be cleared immediately and cached in dscr. However, don’t do this
+ * will be cleared immediately and cached in dscr. However, don't do this
* if there is fault, because then the instruction might not have completed
* successfully. */
if (!(dscr & DSCR_STICKY_ABORT_PRECISE)) {
@@ -2366,13 +2339,13 @@ static int cortex_a_write_apb_ab_memory(struct target *target,
return final_retval;
}
-static int cortex_a_read_apb_ab_memory_slow(struct target *target,
+static int cortex_a_read_cpu_memory_slow(struct target *target,
uint32_t size, uint32_t count, uint8_t *buffer, uint32_t *dscr)
{
/* Reads count objects of size size into *buffer. Old value of DSCR must be
* in *dscr; updated to new value. This is slow because it works for
* non-word-sized objects and (maybe) unaligned accesses. If size == 4 and
- * the address is aligned, cortex_a_read_apb_ab_memory_fast should be
+ * the address is aligned, cortex_a_read_cpu_memory_fast should be
* preferred.
* Preconditions:
* - Address is in R0.
@@ -2442,7 +2415,7 @@ static int cortex_a_read_apb_ab_memory_slow(struct target *target,
return ERROR_OK;
}
-static int cortex_a_read_apb_ab_memory_fast(struct target *target,
+static int cortex_a_read_cpu_memory_fast(struct target *target,
uint32_t count, uint8_t *buffer, uint32_t *dscr)
{
/* Reads count objects of size 4 into *buffer. Old value of DSCR must be in
@@ -2529,17 +2502,17 @@ static int cortex_a_read_apb_ab_memory_fast(struct target *target,
return ERROR_OK;
}
-static int cortex_a_read_apb_ab_memory(struct target *target,
+static int cortex_a_read_cpu_memory(struct target *target,
uint32_t address, uint32_t size,
uint32_t count, uint8_t *buffer)
{
- /* Read memory through APB-AP. */
+ /* Read memory through the CPU. */
int retval, final_retval;
struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm *arm = &armv7a->arm;
uint32_t dscr, orig_dfar, orig_dfsr, fault_dscr, fault_dfar, fault_dfsr;
- LOG_DEBUG("Reading APB-AP memory address 0x%" PRIx32 " size %" PRIu32 " count %" PRIu32,
+ LOG_DEBUG("Reading CPU memory address 0x%" PRIx32 " size %" PRIu32 " count %" PRIu32,
address, size, count);
if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted");
@@ -2585,10 +2558,10 @@ static int cortex_a_read_apb_ab_memory(struct target *target,
if (size == 4 && (address % 4) == 0) {
/* We are doing a word-aligned transfer, so use fast mode. */
- retval = cortex_a_read_apb_ab_memory_fast(target, count, buffer, &dscr);
+ retval = cortex_a_read_cpu_memory_fast(target, count, buffer, &dscr);
} else {
/* Use slow path. */
- retval = cortex_a_read_apb_ab_memory_slow(target, size, count, buffer, &dscr);
+ retval = cortex_a_read_cpu_memory_slow(target, size, count, buffer, &dscr);
}
out:
@@ -2660,49 +2633,57 @@ static int cortex_a_read_apb_ab_memory(struct target *target,
/*
* Cortex-A Memory access
*
- * This is same Cortex M3 but we must also use the correct
+ * This is same Cortex-M3 but we must also use the correct
* ap number for every access.
*/
static int cortex_a_read_phys_memory(struct target *target,
- uint32_t address, uint32_t size,
+ target_addr_t address, uint32_t size,
uint32_t count, uint8_t *buffer)
{
- int retval = ERROR_COMMAND_SYNTAX_ERROR;
+ struct armv7a_common *armv7a = target_to_armv7a(target);
+ struct adiv5_dap *swjdp = armv7a->arm.dap;
+ uint8_t apsel = swjdp->apsel;
+ int retval;
- LOG_DEBUG("Reading memory at real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32,
+ if (!count || !buffer)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ LOG_DEBUG("Reading memory at real address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
address, size, count);
- if (count && buffer) {
- /* read memory through APB-AP */
- cortex_a_prep_memaccess(target, 1);
- retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
- cortex_a_post_memaccess(target, 1);
- }
+ if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num))
+ return mem_ap_read_buf(armv7a->memory_ap, buffer, size, count, address);
+
+ /* read memory through the CPU */
+ cortex_a_prep_memaccess(target, 1);
+ retval = cortex_a_read_cpu_memory(target, address, size, count, buffer);
+ cortex_a_post_memaccess(target, 1);
+
return retval;
}
-static int cortex_a_read_memory(struct target *target, uint32_t address,
+static int cortex_a_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
int retval;
/* cortex_a handles unaligned memory access */
- LOG_DEBUG("Reading memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
- size, count);
+ LOG_DEBUG("Reading memory at address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
+ address, size, count);
cortex_a_prep_memaccess(target, 0);
- retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
+ retval = cortex_a_read_cpu_memory(target, address, size, count, buffer);
cortex_a_post_memaccess(target, 0);
return retval;
}
-static int cortex_a_read_memory_ahb(struct target *target, uint32_t address,
+static int cortex_a_read_memory_ahb(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
int mmu_enabled = 0;
- uint32_t virt, phys;
+ target_addr_t virt, phys;
int retval;
struct armv7a_common *armv7a = target_to_armv7a(target);
struct adiv5_dap *swjdp = armv7a->arm.dap;
@@ -2712,8 +2693,8 @@ static int cortex_a_read_memory_ahb(struct target *target, uint32_t address,
return target_read_memory(target, address, size, count, buffer);
/* cortex_a handles unaligned memory access */
- LOG_DEBUG("Reading memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
- size, count);
+ LOG_DEBUG("Reading memory at address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
+ address, size, count);
/* determine if MMU was enabled on target stop */
if (!armv7a->is_armv7r) {
@@ -2728,7 +2709,8 @@ static int cortex_a_read_memory_ahb(struct target *target, uint32_t address,
if (retval != ERROR_OK)
return retval;
- LOG_DEBUG("Reading at virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
+ LOG_DEBUG("Reading at virtual address. "
+ "Translating v:" TARGET_ADDR_FMT " to r:" TARGET_ADDR_FMT,
virt, phys);
address = phys;
}
@@ -2742,47 +2724,54 @@ static int cortex_a_read_memory_ahb(struct target *target, uint32_t address,
}
static int cortex_a_write_phys_memory(struct target *target,
- uint32_t address, uint32_t size,
+ target_addr_t address, uint32_t size,
uint32_t count, const uint8_t *buffer)
{
- int retval = ERROR_COMMAND_SYNTAX_ERROR;
+ struct armv7a_common *armv7a = target_to_armv7a(target);
+ struct adiv5_dap *swjdp = armv7a->arm.dap;
+ uint8_t apsel = swjdp->apsel;
+ int retval;
+
+ if (!count || !buffer)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- LOG_DEBUG("Writing memory to real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
- size, count);
+ LOG_DEBUG("Writing memory to real address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
+ address, size, count);
- if (count && buffer) {
- /* write memory through APB-AP */
- cortex_a_prep_memaccess(target, 1);
- retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
- cortex_a_post_memaccess(target, 1);
- }
+ if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num))
+ return mem_ap_write_buf(armv7a->memory_ap, buffer, size, count, address);
+
+ /* write memory through the CPU */
+ cortex_a_prep_memaccess(target, 1);
+ retval = cortex_a_write_cpu_memory(target, address, size, count, buffer);
+ cortex_a_post_memaccess(target, 1);
return retval;
}
-static int cortex_a_write_memory(struct target *target, uint32_t address,
+static int cortex_a_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
int retval;
/* cortex_a handles unaligned memory access */
- LOG_DEBUG("Writing memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
- size, count);
+ LOG_DEBUG("Writing memory at address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
+ address, size, count);
/* memory writes bypass the caches, must flush before writing */
armv7a_cache_auto_flush_on_write(target, address, size * count);
cortex_a_prep_memaccess(target, 0);
- retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
+ retval = cortex_a_write_cpu_memory(target, address, size, count, buffer);
cortex_a_post_memaccess(target, 0);
return retval;
}
-static int cortex_a_write_memory_ahb(struct target *target, uint32_t address,
+static int cortex_a_write_memory_ahb(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
int mmu_enabled = 0;
- uint32_t virt, phys;
+ target_addr_t virt, phys;
int retval;
struct armv7a_common *armv7a = target_to_armv7a(target);
struct adiv5_dap *swjdp = armv7a->arm.dap;
@@ -2792,8 +2781,8 @@ static int cortex_a_write_memory_ahb(struct target *target, uint32_t address,
return target_write_memory(target, address, size, count, buffer);
/* cortex_a handles unaligned memory access */
- LOG_DEBUG("Writing memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
- size, count);
+ LOG_DEBUG("Writing memory at address " TARGET_ADDR_FMT "; size %" PRId32 "; count %" PRId32,
+ address, size, count);
/* determine if MMU was enabled on target stop */
if (!armv7a->is_armv7r) {
@@ -2808,7 +2797,8 @@ static int cortex_a_write_memory_ahb(struct target *target, uint32_t address,
if (retval != ERROR_OK)
return retval;
- LOG_DEBUG("Writing to virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
+ LOG_DEBUG("Writing to virtual address. "
+ "Translating v:" TARGET_ADDR_FMT " to r:" TARGET_ADDR_FMT,
virt,
phys);
address = phys;
@@ -2822,7 +2812,7 @@ static int cortex_a_write_memory_ahb(struct target *target, uint32_t address,
return retval;
}
-static int cortex_a_read_buffer(struct target *target, uint32_t address,
+static int cortex_a_read_buffer(struct target *target, target_addr_t address,
uint32_t count, uint8_t *buffer)
{
uint32_t size;
@@ -2856,7 +2846,7 @@ static int cortex_a_read_buffer(struct target *target, uint32_t address,
return ERROR_OK;
}
-static int cortex_a_write_buffer(struct target *target, uint32_t address,
+static int cortex_a_write_buffer(struct target *target, target_addr_t address,
uint32_t count, const uint8_t *buffer)
{
uint32_t size;
@@ -2908,6 +2898,7 @@ static int cortex_a_handle_target_request(void *priv)
armv7a->debug_base + CPUDBG_DSCR, &dscr);
/* check if we have data */
+ int64_t then = timeval_ms();
while ((dscr & DSCR_DTR_TX_FULL) && (retval == ERROR_OK)) {
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DTRTX, &request);
@@ -2916,6 +2907,10 @@ static int cortex_a_handle_target_request(void *priv)
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DSCR, &dscr);
}
+ if (timeval_ms() > then + 1000) {
+ LOG_ERROR("Timeout waiting for dtr tx full");
+ return ERROR_FAIL;
+ }
}
}
@@ -2931,9 +2926,10 @@ static int cortex_a_examine_first(struct target *target)
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
struct adiv5_dap *swjdp = armv7a->arm.dap;
+
int i;
int retval = ERROR_OK;
- uint32_t didr, ctypr, ttypr, cpuid, dbg_osreg;
+ uint32_t didr, cpuid, dbg_osreg;
retval = dap_dp_init(swjdp);
if (retval != ERROR_OK) {
@@ -2941,7 +2937,7 @@ static int cortex_a_examine_first(struct target *target)
return retval;
}
- /* Search for the APB-AB - it is needed for access to debug registers */
+ /* 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);
if (retval != ERROR_OK) {
LOG_ERROR("Could not find APB-AP for debug access");
@@ -2965,11 +2961,10 @@ static int cortex_a_examine_first(struct target *target)
retval = mem_ap_init(armv7a->memory_ap);
if (retval == ERROR_OK)
armv7a->memory_ap_available = true;
- else
- LOG_WARNING("Could not initialize AHB-AP for memory access - using APB-AP");
- } else {
- /* AHB-AP not found - use APB-AP */
- LOG_DEBUG("Could not find AHB-AP - using APB-AP for memory access");
+ }
+ if (retval != ERROR_OK) {
+ /* AHB-AP not found or unavailable - use the CPU */
+ LOG_DEBUG("No AHB-AP available for memory access");
}
if (!target->dbgbase_set) {
@@ -2996,79 +2991,69 @@ static int cortex_a_examine_first(struct target *target)
armv7a->debug_base = target->dbgbase;
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_CPUID, &cpuid);
- if (retval != ERROR_OK)
- return retval;
-
- retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_CPUID, &cpuid);
- if (retval != ERROR_OK) {
- LOG_DEBUG("Examine %s failed", "CPUID");
- return retval;
- }
-
- retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_CTYPR, &ctypr);
- if (retval != ERROR_OK) {
- LOG_DEBUG("Examine %s failed", "CTYPR");
- return retval;
- }
-
- retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_TTYPR, &ttypr);
+ armv7a->debug_base + CPUDBG_DIDR, &didr);
if (retval != ERROR_OK) {
- LOG_DEBUG("Examine %s failed", "TTYPR");
+ LOG_DEBUG("Examine %s failed", "DIDR");
return retval;
}
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_DIDR, &didr);
+ armv7a->debug_base + CPUDBG_CPUID, &cpuid);
if (retval != ERROR_OK) {
- LOG_DEBUG("Examine %s failed", "DIDR");
+ LOG_DEBUG("Examine %s failed", "CPUID");
return retval;
}
- LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
- LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
- LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
LOG_DEBUG("didr = 0x%08" PRIx32, didr);
+ LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
- cortex_a->cpuid = cpuid;
- cortex_a->ctypr = ctypr;
- cortex_a->ttypr = ttypr;
cortex_a->didr = didr;
+ cortex_a->cpuid = cpuid;
- /* Unlocking the debug registers */
- if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT ==
- CORTEX_A15_PARTNUM) {
-
- retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_OSLAR,
- 0);
-
- if (retval != ERROR_OK)
- return retval;
+ retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg);
+ if (retval != ERROR_OK)
+ return retval;
+ LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR 0x%" PRIx32, target->coreid, dbg_osreg);
+ if ((dbg_osreg & PRSR_POWERUP_STATUS) == 0) {
+ LOG_ERROR("target->coreid %" PRId32 " powered down!", target->coreid);
+ target->state = TARGET_UNKNOWN; /* TARGET_NO_POWER? */
+ return ERROR_TARGET_INIT_FAILED;
}
- /* Unlocking the debug registers */
- if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT ==
- CORTEX_A7_PARTNUM) {
-
- retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_OSLAR,
- 0);
- if (retval != ERROR_OK)
- return retval;
+ if (dbg_osreg & PRSR_STICKY_RESET_STATUS)
+ LOG_DEBUG("target->coreid %" PRId32 " was reset!", target->coreid);
- }
+ /* Read DBGOSLSR and check if OSLK is implemented */
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg);
-
+ armv7a->debug_base + CPUDBG_OSLSR, &dbg_osreg);
if (retval != ERROR_OK)
return retval;
+ LOG_DEBUG("target->coreid %" PRId32 " DBGOSLSR 0x%" PRIx32, target->coreid, dbg_osreg);
- LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR 0x%" PRIx32, target->coreid, dbg_osreg);
+ /* check if OS Lock is implemented */
+ if ((dbg_osreg & OSLSR_OSLM) == OSLSR_OSLM0 || (dbg_osreg & OSLSR_OSLM) == OSLSR_OSLM1) {
+ /* check if OS Lock is set */
+ if (dbg_osreg & OSLSR_OSLK) {
+ LOG_DEBUG("target->coreid %" PRId32 " OSLock set! Trying to unlock", target->coreid);
+
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_OSLAR,
+ 0);
+ if (retval == ERROR_OK)
+ retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_OSLSR, &dbg_osreg);
+
+ /* if we fail to access the register or cannot reset the OSLK bit, bail out */
+ if (retval != ERROR_OK || (dbg_osreg & OSLSR_OSLK) != 0) {
+ LOG_ERROR("target->coreid %" PRId32 " OSLock sticky, core not powered?",
+ target->coreid);
+ target->state = TARGET_UNKNOWN; /* TARGET_NO_POWER? */
+ return ERROR_TARGET_INIT_FAILED;
+ }
+ }
+ }
armv7a->arm.core_type = ARM_MODE_MON;
@@ -3128,6 +3113,7 @@ static int cortex_a_init_target(struct command_context *cmd_ctx,
struct target *target)
{
/* examine_first() does a bunch of this */
+ arm_semihosting_init(target);
return ERROR_OK;
}
@@ -3217,7 +3203,7 @@ static int cortex_a_mmu(struct target *target, int *enabled)
}
static int cortex_a_virt2phys(struct target *target,
- uint32_t virt, uint32_t *phys)
+ target_addr_t virt, target_addr_t *phys)
{
int retval = ERROR_FAIL;
struct armv7a_common *armv7a = target_to_armv7a(target);
@@ -3235,7 +3221,8 @@ static int cortex_a_virt2phys(struct target *target,
retval = cortex_a_mmu_modify(target, 1);
if (retval != ERROR_OK)
goto done;
- retval = armv7a_mmu_translate_va_pa(target, virt, phys, 1);
+ retval = armv7a_mmu_translate_va_pa(target, (uint32_t)virt,
+ (uint32_t *)phys, 1);
}
done:
return retval;
@@ -3331,17 +3318,14 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
};
const Jim_Nvp *n;
- if (target->state != TARGET_HALTED) {
- command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
- return ERROR_OK;
- }
-
if (CMD_ARGC > 0) {
n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
- if (n->name == NULL)
+ if (n->name == NULL) {
+ LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]);
return ERROR_COMMAND_SYNTAX_ERROR;
- cortex_a->isrmasking_mode = n->value;
+ }
+ cortex_a->isrmasking_mode = n->value;
}
n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode);
@@ -3413,7 +3397,7 @@ static const struct command_registration cortex_a_exec_command_handlers[] = {
{
.name = "maskisr",
.handler = handle_cortex_a_mask_interrupts_command,
- .mode = COMMAND_EXEC,
+ .mode = COMMAND_ANY,
.help = "mask cortex_a interrupts",
.usage = "['on'|'off']",
},
@@ -3550,8 +3534,8 @@ struct target_type cortexr4_target = {
/* REVISIT allow exporting VFP3 registers ... */
.get_gdb_reg_list = arm_get_gdb_reg_list,
- .read_memory = cortex_a_read_memory,
- .write_memory = cortex_a_write_memory,
+ .read_memory = cortex_a_read_phys_memory,
+ .write_memory = cortex_a_write_phys_memory,
.checksum_memory = arm_checksum_memory,
.blank_check_memory = arm_blank_check_memory,
diff --git a/src/target/cortex_a.h b/src/target/cortex_a.h
index 1c63588e2..ff0343208 100644
--- a/src/target/cortex_a.h
+++ b/src/target/cortex_a.h
@@ -22,13 +22,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef CORTEX_A_H
-#define CORTEX_A_H
+#ifndef OPENOCD_TARGET_CORTEX_A_H
+#define OPENOCD_TARGET_CORTEX_A_H
#include "armv7a.h"
@@ -99,8 +97,6 @@ struct cortex_a_common {
int fast_reg_read;
uint32_t cpuid;
- uint32_t ctypr;
- uint32_t ttypr;
uint32_t didr;
enum cortex_a_isrmasking_mode isrmasking_mode;
@@ -116,4 +112,4 @@ target_to_cortex_a(struct target *target)
return container_of(target->arch_info, struct cortex_a_common, armv7a_common.arm);
}
-#endif /* CORTEX_A_H */
+#endif /* OPENOCD_TARGET_CORTEX_A_H */
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 6786c46c9..e80cd2356 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
* *
* *
* Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
@@ -684,7 +682,7 @@ void cortex_m_enable_breakpoints(struct target *target)
}
static int cortex_m_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints, int debug_execution)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
struct breakpoint *breakpoint = NULL;
@@ -752,7 +750,7 @@ static int cortex_m_resume(struct target *target, int current,
/* Single step past breakpoint at current address */
breakpoint = breakpoint_find(target, resume_pc);
if (breakpoint) {
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %" PRIu32 ")",
+ LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
breakpoint->address,
breakpoint->unique_id);
cortex_m_unset_breakpoint(target, breakpoint);
@@ -784,7 +782,7 @@ static int cortex_m_resume(struct target *target, int current,
/* int irqstepcount = 0; */
static int cortex_m_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
struct cortex_m_common *cortex_m = target_to_cm(target);
struct armv7m_common *armv7m = &cortex_m->armv7m;
@@ -983,6 +981,18 @@ static int cortex_m_assert_reset(struct target *target)
bool srst_asserted = false;
+ if (!target_was_examined(target)) {
+ if (jtag_reset_config & RESET_HAS_SRST) {
+ adapter_assert_reset();
+ if (target->reset_halt)
+ LOG_ERROR("Target not examined, will not halt after reset!");
+ return ERROR_OK;
+ } else {
+ LOG_ERROR("Target not examined, reset NOT asserted!");
+ return ERROR_FAIL;
+ }
+ }
+
if ((jtag_reset_config & RESET_HAS_SRST) &&
(jtag_reset_config & RESET_SRST_NO_GATING)) {
adapter_assert_reset();
@@ -992,34 +1002,24 @@ static int cortex_m_assert_reset(struct target *target)
/* Enable debug requests */
int retval;
retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
- if (retval != ERROR_OK)
- return retval;
- if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {
+ /* Store important errors instead of failing and proceed to reset assert */
+
+ if (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN))
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_DEBUGEN);
- if (retval != ERROR_OK)
- return retval;
- }
/* If the processor is sleeping in a WFI or WFE instruction, the
* C_HALT bit must be asserted to regain control */
- if (cortex_m->dcb_dhcsr & S_SLEEP) {
+ if (retval == ERROR_OK && (cortex_m->dcb_dhcsr & S_SLEEP))
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
- if (retval != ERROR_OK)
- return retval;
- }
- retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
- if (retval != ERROR_OK)
- return retval;
+ mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
+ /* Ignore less important errors */
if (!target->reset_halt) {
/* Set/Clear C_MASKINTS in a separate operation */
- if (cortex_m->dcb_dhcsr & C_MASKINTS) {
- retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
+ if (cortex_m->dcb_dhcsr & C_MASKINTS)
+ mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
DBGKEY | C_DEBUGEN | C_HALT);
- if (retval != ERROR_OK)
- return retval;
- }
/* clear any debug flags before resuming */
cortex_m_clear_halt(target);
@@ -1033,16 +1033,20 @@ static int cortex_m_assert_reset(struct target *target)
* bad vector table entries. Should this include MMERR or
* other flags too?
*/
- retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
+ int retval2;
+ retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
- if (retval != ERROR_OK)
- return retval;
+ if (retval != ERROR_OK || retval2 != ERROR_OK)
+ LOG_INFO("AP write error, reset will not halt");
}
if (jtag_reset_config & RESET_HAS_SRST) {
/* default to asserting srst */
if (!srst_asserted)
adapter_assert_reset();
+
+ /* srst is asserted, ignore AP access errors */
+ retval = ERROR_OK;
} else {
/* Use a standard Cortex-M3 software reset mechanism.
* We default to using VECRESET as it is supported on all current cores.
@@ -1057,27 +1061,24 @@ static int cortex_m_assert_reset(struct target *target)
"handler to reset any peripherals or configure hardware srst support.");
}
- retval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,
+ int retval3;
+ retval3 = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,
AIRCR_VECTKEY | ((reset_config == CORTEX_M_RESET_SYSRESETREQ)
? AIRCR_SYSRESETREQ : AIRCR_VECTRESET));
- if (retval != ERROR_OK)
+ if (retval3 != ERROR_OK)
LOG_DEBUG("Ignoring AP write error right after reset");
- retval = dap_dp_init(armv7m->debug_ap->dap);
- if (retval != ERROR_OK) {
+ retval3 = dap_dp_init(armv7m->debug_ap->dap);
+ if (retval3 != ERROR_OK)
LOG_ERROR("DP initialisation failed");
- return retval;
- }
- {
+ else {
/* I do not know why this is necessary, but it
* fixes strange effects (step/resume cause NMI
* after reset) on LM3S6918 -- Michael Schwingen
*/
uint32_t tmp;
- retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, &tmp);
- if (retval != ERROR_OK)
- return retval;
+ mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, &tmp);
}
}
@@ -1086,6 +1087,10 @@ static int cortex_m_assert_reset(struct target *target)
register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
+ /* now return stored error code if any */
+ if (retval != ERROR_OK)
+ return retval;
+
if (target->reset_halt) {
retval = target_halt(target);
if (retval != ERROR_OK)
@@ -1108,7 +1113,8 @@ static int cortex_m_deassert_reset(struct target *target)
enum reset_types jtag_reset_config = jtag_get_reset_config();
if ((jtag_reset_config & RESET_HAS_SRST) &&
- !(jtag_reset_config & RESET_SRST_NO_GATING)) {
+ !(jtag_reset_config & RESET_SRST_NO_GATING) &&
+ target_was_examined(target)) {
int retval = dap_dp_init(armv7m->debug_ap->dap);
if (retval != ERROR_OK) {
LOG_ERROR("DP initialisation failed");
@@ -1192,7 +1198,7 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint
breakpoint->set = true;
}
- LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
+ LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
breakpoint->unique_id,
(int)(breakpoint->type),
breakpoint->address,
@@ -1213,7 +1219,7 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi
return ERROR_OK;
}
- LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
+ LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
breakpoint->unique_id,
(int)(breakpoint->type),
breakpoint->address,
@@ -1658,7 +1664,7 @@ static int cortex_m_store_core_reg_u32(struct target *target,
return ERROR_OK;
}
-static int cortex_m_read_memory(struct target *target, uint32_t address,
+static int cortex_m_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
@@ -1672,7 +1678,7 @@ static int cortex_m_read_memory(struct target *target, uint32_t address,
return mem_ap_read_buf(armv7m->debug_ap, buffer, size, count, address);
}
-static int cortex_m_write_memory(struct target *target, uint32_t address,
+static int cortex_m_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
@@ -1690,6 +1696,7 @@ static int cortex_m_init_target(struct command_context *cmd_ctx,
struct target *target)
{
armv7m_build_reg_cache(target);
+ arm_semihosting_init(target);
return ERROR_OK;
}
@@ -1702,6 +1709,7 @@ void cortex_m_deinit_target(struct target *target)
cortex_m_dwt_free(target);
armv7m_free_reg_cache(target);
+ free(target->private_config);
free(cortex_m);
}
@@ -1882,6 +1890,11 @@ static void cortex_m_dwt_free(struct target *target)
#define MVFR0_DEFAULT_M4 0x10110021
#define MVFR1_DEFAULT_M4 0x11000011
+#define MVFR0_DEFAULT_M7_SP 0x10110021
+#define MVFR0_DEFAULT_M7_DP 0x10110221
+#define MVFR1_DEFAULT_M7_SP 0x11000011
+#define MVFR1_DEFAULT_M7_DP 0x12000011
+
int cortex_m_examine(struct target *target)
{
int retval;
@@ -1900,11 +1913,15 @@ int cortex_m_examine(struct target *target)
return retval;
}
- /* Search for the MEM-AP */
- retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7m->debug_ap);
- if (retval != ERROR_OK) {
- LOG_ERROR("Could not find MEM-AP to control the core");
- return retval;
+ if (cortex_m->apsel < 0) {
+ /* Search for the MEM-AP */
+ retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7m->debug_ap);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Could not find MEM-AP to control the core");
+ return retval;
+ }
+ } else {
+ armv7m->debug_ap = dap_ap(swjdp, cortex_m->apsel);
}
/* Leave (only) generic DAP stuff for debugport_init(); */
@@ -1928,23 +1945,42 @@ int cortex_m_examine(struct target *target)
LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected",
i, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
+ if (i == 7) {
+ uint8_t rev, patch;
+ rev = (cpuid >> 20) & 0xf;
+ patch = (cpuid >> 0) & 0xf;
+ if ((rev == 0) && (patch < 2))
+ LOG_WARNING("Silicon bug: single stepping will enter pending exception handler!");
+ }
LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
- /* test for floating point feature on cortex-m4 */
if (i == 4) {
target_read_u32(target, MVFR0, &mvfr0);
target_read_u32(target, MVFR1, &mvfr1);
+ /* test for floating point feature on Cortex-M4 */
if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i);
armv7m->fp_feature = FPv4_SP;
}
+ } else if (i == 7) {
+ target_read_u32(target, MVFR0, &mvfr0);
+ target_read_u32(target, MVFR1, &mvfr1);
+
+ /* test for floating point features on Cortex-M7 */
+ if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
+ LOG_DEBUG("Cortex-M%d floating point feature FPv5_SP found", i);
+ armv7m->fp_feature = FPv5_SP;
+ } else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
+ LOG_DEBUG("Cortex-M%d floating point feature FPv5_DP found", i);
+ armv7m->fp_feature = FPv5_DP;
+ }
} else if (i == 0) {
/* Cortex-M0 does not support unaligned memory access */
armv7m->arm.is_armv6m = true;
}
- if (armv7m->fp_feature != FPv4_SP &&
+ if (armv7m->fp_feature == FP_NONE &&
armv7m->arm.core_cache->num_regs > ARMV7M_NUM_CORE_REGS_NOFP) {
/* free unavailable FPU registers */
size_t idx;
@@ -1959,9 +1995,14 @@ int cortex_m_examine(struct target *target)
armv7m->arm.core_cache->num_regs = ARMV7M_NUM_CORE_REGS_NOFP;
}
- if ((i == 4 || i == 3) && !armv7m->stlink) {
- /* Cortex-M3/M4 has 4096 bytes autoincrement range */
- armv7m->debug_ap->tar_autoincr_block = (1 << 12);
+ if (!armv7m->stlink) {
+ if (i == 3 || i == 4)
+ /* Cortex-M3/M4 have 4096 bytes autoincrement range,
+ * s. ARM IHI 0031C: MEM-AP 7.2.2 */
+ armv7m->debug_ap->tar_autoincr_block = (1 << 12);
+ else if (i == 7)
+ /* Cortex-M7 has only 1024 bytes autoincrement range */
+ armv7m->debug_ap->tar_autoincr_block = (1 << 10);
}
/* Configure trace modules */
@@ -2144,6 +2185,13 @@ static int cortex_m_target_create(struct target *target, Jim_Interp *interp)
cortex_m->common_magic = CORTEX_M_COMMON_MAGIC;
cortex_m_init_arch_info(target, cortex_m, target->tap);
+ if (target->private_config != NULL) {
+ struct adiv5_private_config *pc =
+ (struct adiv5_private_config *)target->private_config;
+ cortex_m->apsel = pc->ap_num;
+ } else
+ cortex_m->apsel = -1;
+
return ERROR_OK;
}
@@ -2405,6 +2453,7 @@ struct target_type cortexm_target = {
.commands = cortex_m_command_handlers,
.target_create = cortex_m_target_create,
+ .target_jim_configure = adiv5_jim_configure,
.init_target = cortex_m_init_target,
.examine = cortex_m_examine,
.deinit_target = cortex_m_deinit_target,
diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h
index b09cc49a6..3d9714b90 100644
--- a/src/target/cortex_m.h
+++ b/src/target/cortex_m.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef CORTEX_M_H
-#define CORTEX_M_H
+#ifndef OPENOCD_TARGET_CORTEX_M_H
+#define OPENOCD_TARGET_CORTEX_M_H
#include "armv7m.h"
@@ -190,6 +188,8 @@ struct cortex_m_common {
enum cortex_m_isrmasking_mode isrmasking_mode;
struct armv7m_common armv7m;
+
+ int apsel;
};
static inline struct cortex_m_common *
@@ -213,4 +213,4 @@ void cortex_m_enable_watchpoints(struct target *target);
void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target);
void cortex_m_deinit_target(struct target *target);
-#endif /* CORTEX_M_H */
+#endif /* OPENOCD_TARGET_CORTEX_M_H */
diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c
index 1cb18cf11..1d728dff8 100644
--- a/src/target/dsp563xx.c
+++ b/src/target/dsp563xx.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -1119,7 +1117,7 @@ static int dsp563xx_halt(struct target *target)
static int dsp563xx_resume(struct target *target,
int current,
- uint32_t address,
+ target_addr_t address,
int handle_breakpoints,
int debug_execution)
{
@@ -1292,7 +1290,7 @@ static int dsp563xx_step_ex(struct target *target,
static int dsp563xx_step(struct target *target,
int current,
- uint32_t address,
+ target_addr_t address,
int handle_breakpoints)
{
int err;
@@ -1376,7 +1374,7 @@ static int dsp563xx_deassert_reset(struct target *target)
static int dsp563xx_run_algorithm(struct target *target,
int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params,
- uint32_t entry_point, uint32_t exit_point,
+ target_addr_t entry_point, target_addr_t exit_point,
int timeout_ms, void *arch_info)
{
int i;
@@ -1594,7 +1592,7 @@ static int dsp563xx_read_memory_core(struct target *target,
static int dsp563xx_read_memory(struct target *target,
int mem_type,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint32_t count,
uint8_t *buffer)
@@ -1662,7 +1660,7 @@ static int dsp563xx_read_memory(struct target *target,
}
static int dsp563xx_read_memory_default(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint32_t count,
uint8_t *buffer)
@@ -1673,7 +1671,7 @@ static int dsp563xx_read_memory_default(struct target *target,
}
static int dsp563xx_read_buffer_default(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint8_t *buffer)
{
@@ -1684,7 +1682,7 @@ static int dsp563xx_read_buffer_default(struct target *target,
static int dsp563xx_write_memory_core(struct target *target,
int mem_type,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint32_t count,
const uint8_t *buffer)
@@ -1696,7 +1694,7 @@ static int dsp563xx_write_memory_core(struct target *target,
const uint8_t *b;
LOG_DEBUG(
- "memtype: %d address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
+ "memtype: %d address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
mem_type,
address,
size,
@@ -1768,7 +1766,7 @@ static int dsp563xx_write_memory_core(struct target *target,
static int dsp563xx_write_memory(struct target *target,
int mem_type,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint32_t count,
const uint8_t *buffer)
@@ -1836,7 +1834,7 @@ static int dsp563xx_write_memory(struct target *target,
}
static int dsp563xx_write_memory_default(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
uint32_t count,
const uint8_t *buffer)
@@ -1846,7 +1844,7 @@ static int dsp563xx_write_memory_default(struct target *target,
}
static int dsp563xx_write_buffer_default(struct target *target,
- uint32_t address,
+ target_addr_t address,
uint32_t size,
const uint8_t *buffer)
{
diff --git a/src/target/dsp563xx.h b/src/target/dsp563xx.h
index 446ad3f53..4bb5aceaf 100644
--- a/src/target/dsp563xx.h
+++ b/src/target/dsp563xx.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef DSP563XX_H
-#define DSP563XX_H
+#ifndef OPENOCD_TARGET_DSP563XX_H
+#define OPENOCD_TARGET_DSP563XX_H
#include
#include
@@ -72,4 +70,4 @@ static inline struct dsp563xx_common *target_to_dsp563xx(struct target *target)
return target->arch_info;
}
-#endif /* DSP563XX_H */
+#endif /* OPENOCD_TARGET_DSP563XX_H */
diff --git a/src/target/dsp563xx_once.c b/src/target/dsp563xx_once.c
index aa8c96910..fe4927ba3 100644
--- a/src/target/dsp563xx_once.c
+++ b/src/target/dsp563xx_once.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/dsp563xx_once.h b/src/target/dsp563xx_once.h
index 8835d553d..da7f5e9b8 100644
--- a/src/target/dsp563xx_once.h
+++ b/src/target/dsp563xx_once.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef DSP563XX_ONCE_H
-#define DSP563XX_ONCE_H
+#ifndef OPENOCD_TARGET_DSP563XX_ONCE_H
+#define OPENOCD_TARGET_DSP563XX_ONCE_H
#include
@@ -88,4 +86,4 @@ int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, int flush, uint32_t opcode
/** double word instruction */
int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, int flush, uint32_t opcode, uint32_t operand);
-#endif /* DSP563XX_ONCE_H */
+#endif /* OPENOCD_TARGET_DSP563XX_ONCE_H */
diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c
index 8a58cab47..a50f2cd47 100644
--- a/src/target/dsp5680xx.c
+++ b/src/target/dsp5680xx.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -1003,17 +1001,17 @@ static int dsp5680xx_poll(struct target *target)
__func__);
target->state = TARGET_UNKNOWN;
return ERROR_TARGET_FAILURE;
- };
+ }
if (target->state == TARGET_UNKNOWN) {
LOG_ERROR("%s: Target status invalid - communication failure",
__func__);
return ERROR_TARGET_FAILURE;
- };
+ }
return ERROR_OK;
}
static int dsp5680xx_resume(struct target *target, int current,
- uint32_t address, int hb, int d)
+ target_addr_t address, int hb, int d)
{
if (target->state == TARGET_RUNNING) {
LOG_USER("Target already running.");
@@ -1170,7 +1168,7 @@ static int dsp5680xx_read_32_single(struct target *t, uint32_t a,
return retval;
}
-static int dsp5680xx_read(struct target *t, uint32_t a, uint32_t size,
+static int dsp5680xx_read(struct target *t, target_addr_t a, uint32_t size,
uint32_t count, uint8_t *buf)
{
struct target *target = t;
@@ -1425,7 +1423,7 @@ static int dsp5680xx_write_32(struct target *t, uint32_t a, uint32_t c,
*
* @return
*/
-static int dsp5680xx_write(struct target *t, uint32_t a, uint32_t s, uint32_t c,
+static int dsp5680xx_write(struct target *t, target_addr_t a, uint32_t s, uint32_t c,
const uint8_t *b)
{
/* TODO Cannot write 32bit to odd address, will write 0x12345678 as 0x5678 0x0012 */
@@ -1470,7 +1468,7 @@ static int dsp5680xx_write(struct target *t, uint32_t a, uint32_t s, uint32_t c,
return retval;
}
-static int dsp5680xx_write_buffer(struct target *t, uint32_t a, uint32_t size,
+static int dsp5680xx_write_buffer(struct target *t, target_addr_t a, uint32_t size,
const uint8_t *b)
{
check_halt_and_debug(t);
@@ -1487,7 +1485,7 @@ static int dsp5680xx_write_buffer(struct target *t, uint32_t a, uint32_t size,
*
* @return
*/
-static int dsp5680xx_read_buffer(struct target *t, uint32_t a, uint32_t size,
+static int dsp5680xx_read_buffer(struct target *t, target_addr_t a, uint32_t size,
uint8_t *buf)
{
check_halt_and_debug(t);
@@ -1507,7 +1505,7 @@ static int dsp5680xx_read_buffer(struct target *t, uint32_t a, uint32_t size,
*
* @return
*/
-static int dsp5680xx_checksum_memory(struct target *t, uint32_t a, uint32_t s,
+static int dsp5680xx_checksum_memory(struct target *t, target_addr_t a, uint32_t s,
uint32_t *checksum)
{
return ERROR_FAIL;
@@ -2264,7 +2262,7 @@ int dsp5680xx_f_lock(struct target *target)
return retval;
}
-static int dsp5680xx_step(struct target *target, int current, uint32_t address,
+static int dsp5680xx_step(struct target *target, int current, target_addr_t address,
int handle_breakpoints)
{
err_check(ERROR_FAIL, DSP5680XX_ERROR_NOT_IMPLEMENTED_STEP,
diff --git a/src/target/dsp5680xx.h b/src/target/dsp5680xx.h
index cb3bf2a4f..842796bc7 100644
--- a/src/target/dsp5680xx.h
+++ b/src/target/dsp5680xx.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef DSP5680XX_H
-#define DSP5680XX_H
+#ifndef OPENOCD_TARGET_DSP5680XX_H
+#define OPENOCD_TARGET_DSP5680XX_H
#include
@@ -381,4 +379,4 @@ int dsp5680xx_f_lock(struct target *target);
*/
int dsp5680xx_f_unlock(struct target *target);
-#endif /* DSP5680XX_H */
+#endif /* OPENOCD_TARGET_DSP5680XX_H */
diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c
index 4b3a05a83..09d6fc8a1 100644
--- a/src/target/embeddedice.c
+++ b/src/target/embeddedice.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/embeddedice.h b/src/target/embeddedice.h
index f110e82e6..39902fb3e 100644
--- a/src/target/embeddedice.h
+++ b/src/target/embeddedice.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef EMBEDDED_ICE_H
-#define EMBEDDED_ICE_H
+#ifndef OPENOCD_TARGET_EMBEDDEDICE_H
+#define OPENOCD_TARGET_EMBEDDEDICE_H
#include "arm7_9_common.h"
@@ -127,4 +125,4 @@ static inline void embeddedice_write_reg_inner(struct jtag_tap *tap, int reg_add
void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *buffer,
int little, int count);
-#endif /* EMBEDDED_ICE_H */
+#endif /* OPENOCD_TARGET_EMBEDDEDICE_H */
diff --git a/src/target/etb.c b/src/target/etb.c
index 56f5795bd..dc25844b9 100644
--- a/src/target/etb.c
+++ b/src/target/etb.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/etb.h b/src/target/etb.h
index d5cbd85c1..680c8a1ab 100644
--- a/src/target/etb.h
+++ b/src/target/etb.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ETB_H
-#define ETB_H
+#ifndef OPENOCD_TARGET_ETB_H
+#define OPENOCD_TARGET_ETB_H
/* ETB registers */
enum {
@@ -57,4 +55,4 @@ extern struct etm_capture_driver etb_capture_driver;
struct reg_cache *etb_build_reg_cache(struct etb *etb);
-#endif /* ETB_H */
+#endif /* OPENOCD_TARGET_ETB_H */
diff --git a/src/target/etm.c b/src/target/etm.c
index 0246ae25e..6a00c23a8 100644
--- a/src/target/etm.c
+++ b/src/target/etm.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -1701,7 +1699,7 @@ COMMAND_HANDLER(handle_etm_image_command)
COMMAND_HANDLER(handle_etm_dump_command)
{
- struct fileio file;
+ struct fileio *file;
struct target *target;
struct arm *arm;
struct etm_context *etm_ctx;
@@ -1741,24 +1739,24 @@ COMMAND_HANDLER(handle_etm_dump_command)
if (fileio_open(&file, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
return ERROR_FAIL;
- fileio_write_u32(&file, etm_ctx->capture_status);
- fileio_write_u32(&file, etm_ctx->control);
- fileio_write_u32(&file, etm_ctx->trace_depth);
+ fileio_write_u32(file, etm_ctx->capture_status);
+ fileio_write_u32(file, etm_ctx->control);
+ fileio_write_u32(file, etm_ctx->trace_depth);
for (i = 0; i < etm_ctx->trace_depth; i++) {
- fileio_write_u32(&file, etm_ctx->trace_data[i].pipestat);
- fileio_write_u32(&file, etm_ctx->trace_data[i].packet);
- fileio_write_u32(&file, etm_ctx->trace_data[i].flags);
+ fileio_write_u32(file, etm_ctx->trace_data[i].pipestat);
+ fileio_write_u32(file, etm_ctx->trace_data[i].packet);
+ fileio_write_u32(file, etm_ctx->trace_data[i].flags);
}
- fileio_close(&file);
+ fileio_close(file);
return ERROR_OK;
}
COMMAND_HANDLER(handle_etm_load_command)
{
- struct fileio file;
+ struct fileio *file;
struct target *target;
struct arm *arm;
struct etm_context *etm_ctx;
@@ -1789,15 +1787,15 @@ COMMAND_HANDLER(handle_etm_load_command)
return ERROR_FAIL;
size_t filesize;
- int retval = fileio_size(&file, &filesize);
+ int retval = fileio_size(file, &filesize);
if (retval != ERROR_OK) {
- fileio_close(&file);
+ fileio_close(file);
return retval;
}
if (filesize % 4) {
command_print(CMD_CTX, "size isn't a multiple of 4, no valid trace data");
- fileio_close(&file);
+ fileio_close(file);
return ERROR_FAIL;
}
@@ -1808,28 +1806,28 @@ COMMAND_HANDLER(handle_etm_load_command)
{
uint32_t tmp;
- fileio_read_u32(&file, &tmp); etm_ctx->capture_status = tmp;
- fileio_read_u32(&file, &tmp); etm_ctx->control = tmp;
- fileio_read_u32(&file, &etm_ctx->trace_depth);
+ fileio_read_u32(file, &tmp); etm_ctx->capture_status = tmp;
+ fileio_read_u32(file, &tmp); etm_ctx->control = tmp;
+ fileio_read_u32(file, &etm_ctx->trace_depth);
}
etm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth);
if (etm_ctx->trace_data == NULL) {
command_print(CMD_CTX, "not enough memory to perform operation");
- fileio_close(&file);
+ fileio_close(file);
return ERROR_FAIL;
}
for (i = 0; i < etm_ctx->trace_depth; i++) {
uint32_t pipestat, packet, flags;
- fileio_read_u32(&file, &pipestat);
- fileio_read_u32(&file, &packet);
- fileio_read_u32(&file, &flags);
+ fileio_read_u32(file, &pipestat);
+ fileio_read_u32(file, &packet);
+ fileio_read_u32(file, &flags);
etm_ctx->trace_data[i].pipestat = pipestat & 0xff;
etm_ctx->trace_data[i].packet = packet & 0xffff;
etm_ctx->trace_data[i].flags = flags;
}
- fileio_close(&file);
+ fileio_close(file);
return ERROR_OK;
}
diff --git a/src/target/etm.h b/src/target/etm.h
index ff7925bf7..6a78b7564 100644
--- a/src/target/etm.h
+++ b/src/target/etm.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ETM_H
-#define ETM_H
+#ifndef OPENOCD_TARGET_ETM_H
+#define OPENOCD_TARGET_ETM_H
#include "trace.h"
#include "arm_jtag.h"
@@ -223,4 +221,4 @@ extern const struct command_registration etm_command_handlers[];
#define ERROR_ETM_CAPTURE_INIT_FAILED (-1302)
#define ERROR_ETM_ANALYSIS_FAILED (-1303)
-#endif /* ETM_H */
+#endif /* OPENOCD_TARGET_ETM_H */
diff --git a/src/target/etm_dummy.c b/src/target/etm_dummy.c
index 0533d1e0d..b18ce1744 100644
--- a/src/target/etm_dummy.c
+++ b/src/target/etm_dummy.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/etm_dummy.h b/src/target/etm_dummy.h
index 450b5c182..5a1955f37 100644
--- a/src/target/etm_dummy.h
+++ b/src/target/etm_dummy.h
@@ -13,16 +13,14 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef ETM_DUMMY_H
-#define ETM_DUMMY_H
+#ifndef OPENOCD_TARGET_ETM_DUMMY_H
+#define OPENOCD_TARGET_ETM_DUMMY_H
#include "etm.h"
extern struct etm_capture_driver etm_dummy_capture_driver;
-#endif /* ETB_H */
+#endif /* OPENOCD_TARGET_ETM_DUMMY_H */
diff --git a/src/target/fa526.c b/src/target/fa526.c
index dfb29b8ee..9f6b80551 100644
--- a/src/target/fa526.c
+++ b/src/target/fa526.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
diff --git a/src/target/feroceon.c b/src/target/feroceon.c
index 9c204f04f..6b14ab6a8 100644
--- a/src/target/feroceon.c
+++ b/src/target/feroceon.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
@@ -64,6 +62,13 @@ static int feroceon_assert_reset(struct target *target)
struct arm7_9_common *arm7_9 = arm->arch_info;
int ud = arm7_9->use_dbgrq;
+ /* TODO: apply hw reset signal in not examined state */
+ if (!(target_was_examined(target))) {
+ LOG_WARNING("Reset is not asserted because the target is not examined.");
+ LOG_WARNING("Use a reset button or power cycle the target.");
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
+
arm7_9->use_dbgrq = 0;
if (target->reset_halt)
arm7_9_halt(target);
@@ -455,7 +460,7 @@ static int feroceon_examine_debug_reason(struct target *target)
}
static int feroceon_bulk_write_memory(struct target *target,
- uint32_t address, uint32_t count, const uint8_t *buffer)
+ target_addr_t address, uint32_t count, const uint8_t *buffer)
{
int retval;
struct arm *arm = target->arch_info;
@@ -560,7 +565,7 @@ static int feroceon_bulk_write_memory(struct target *target,
buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32);
if (endaddress != address + count*4) {
LOG_ERROR("DCC write failed,"
- " expected end address 0x%08" PRIx32
+ " expected end address 0x%08" TARGET_PRIxADDR
" got 0x%0" PRIx32 "",
address + count*4, endaddress);
retval = ERROR_FAIL;
diff --git a/src/target/hla_target.c b/src/target/hla_target.c
index d0be966c3..78dc8c512 100644
--- a/src/target/hla_target.c
+++ b/src/target/hla_target.c
@@ -18,9 +18,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -343,7 +341,7 @@ static int adapter_init_target(struct command_context *cmd_ctx,
LOG_DEBUG("%s", __func__);
armv7m_build_reg_cache(target);
-
+ arm_semihosting_init(target);
return ERROR_OK;
}
@@ -586,7 +584,7 @@ static int adapter_halt(struct target *target)
}
static int adapter_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints,
+ target_addr_t address, int handle_breakpoints,
int debug_execution)
{
int res;
@@ -596,8 +594,8 @@ static int adapter_resume(struct target *target, int current,
struct breakpoint *breakpoint = NULL;
struct reg *pc;
- LOG_DEBUG("%s %d 0x%08" PRIx32 " %d %d", __func__, current, address,
- handle_breakpoints, debug_execution);
+ LOG_DEBUG("%s %d " TARGET_ADDR_FMT " %d %d", __func__, current,
+ address, handle_breakpoints, debug_execution);
if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted");
@@ -644,7 +642,7 @@ static int adapter_resume(struct target *target, int current,
/* Single step past breakpoint at current address */
breakpoint = breakpoint_find(target, resume_pc);
if (breakpoint) {
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %" PRIu32 ")",
+ LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
breakpoint->address,
breakpoint->unique_id);
cortex_m_unset_breakpoint(target, breakpoint);
@@ -677,7 +675,7 @@ static int adapter_resume(struct target *target, int current,
}
static int adapter_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
int res;
struct hl_interface_s *adapter = target_to_adapter(target);
@@ -740,7 +738,7 @@ static int adapter_step(struct target *target, int current,
return ERROR_OK;
}
-static int adapter_read_memory(struct target *target, uint32_t address,
+static int adapter_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count,
uint8_t *buffer)
{
@@ -749,12 +747,13 @@ static int adapter_read_memory(struct target *target, uint32_t address,
if (!count || !buffer)
return ERROR_COMMAND_SYNTAX_ERROR;
- LOG_DEBUG("%s 0x%08" PRIx32 " %" PRIu32 " %" PRIu32, __func__, address, size, count);
+ LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
+ __func__, address, size, count);
return adapter->layout->api->read_mem(adapter->handle, address, size, count, buffer);
}
-static int adapter_write_memory(struct target *target, uint32_t address,
+static int adapter_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count,
const uint8_t *buffer)
{
@@ -763,7 +762,8 @@ static int adapter_write_memory(struct target *target, uint32_t address,
if (!count || !buffer)
return ERROR_COMMAND_SYNTAX_ERROR;
- LOG_DEBUG("%s 0x%08" PRIx32 " %" PRIu32 " %" PRIu32, __func__, address, size, count);
+ LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
+ __func__, address, size, count);
return adapter->layout->api->write_mem(adapter->handle, address, size, count, buffer);
}
diff --git a/src/target/image.c b/src/target/image.c
index fa51ce33e..f97d90403 100644
--- a/src/target/image.c
+++ b/src/target/image.c
@@ -22,9 +22,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -47,7 +45,7 @@
static int autodetect_image_type(struct image *image, const char *url)
{
int retval;
- struct fileio fileio;
+ struct fileio *fileio;
size_t read_bytes;
uint8_t buffer[9];
@@ -55,13 +53,13 @@ static int autodetect_image_type(struct image *image, const char *url)
retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY);
if (retval != ERROR_OK)
return retval;
- retval = fileio_read(&fileio, 9, buffer, &read_bytes);
+ retval = fileio_read(fileio, 9, buffer, &read_bytes);
if (retval == ERROR_OK) {
if (read_bytes != 9)
retval = ERROR_FILEIO_OPERATION_FAILED;
}
- fileio_close(&fileio);
+ fileio_close(fileio);
if (retval != ERROR_OK)
return retval;
@@ -122,7 +120,7 @@ static int image_ihex_buffer_complete_inner(struct image *image,
struct imagesection *section)
{
struct image_ihex *ihex = image->type_private;
- struct fileio *fileio = &ihex->fileio;
+ struct fileio *fileio = ihex->fileio;
uint32_t full_address = 0x0;
uint32_t cooked_bytes;
int i;
@@ -352,7 +350,7 @@ static int image_elf_read_headers(struct image *image)
return ERROR_FILEIO_OPERATION_FAILED;
}
- retval = fileio_read(&elf->fileio, sizeof(Elf32_Ehdr), (uint8_t *)elf->header, &read_bytes);
+ retval = fileio_read(elf->fileio, sizeof(Elf32_Ehdr), (uint8_t *)elf->header, &read_bytes);
if (retval != ERROR_OK) {
LOG_ERROR("cannot read ELF file header, read failed");
return ERROR_FILEIO_OPERATION_FAILED;
@@ -384,7 +382,7 @@ static int image_elf_read_headers(struct image *image)
return ERROR_IMAGE_FORMAT_ERROR;
}
- retval = fileio_seek(&elf->fileio, field32(elf, elf->header->e_phoff));
+ retval = fileio_seek(elf->fileio, field32(elf, elf->header->e_phoff));
if (retval != ERROR_OK) {
LOG_ERROR("cannot seek to ELF program header table, read failed");
return retval;
@@ -396,7 +394,7 @@ static int image_elf_read_headers(struct image *image)
return ERROR_FILEIO_OPERATION_FAILED;
}
- retval = fileio_read(&elf->fileio, elf->segment_count*sizeof(Elf32_Phdr),
+ retval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf32_Phdr),
(uint8_t *)elf->segments, &read_bytes);
if (retval != ERROR_OK) {
LOG_ERROR("cannot read ELF segment headers, read failed");
@@ -486,12 +484,12 @@ static int image_elf_read_section(struct image *image,
LOG_DEBUG("read elf: size = 0x%zu at 0x%" PRIx32 "", read_size,
field32(elf, segment->p_offset) + offset);
/* read initialized area of the segment */
- retval = fileio_seek(&elf->fileio, field32(elf, segment->p_offset) + offset);
+ retval = fileio_seek(elf->fileio, field32(elf, segment->p_offset) + offset);
if (retval != ERROR_OK) {
LOG_ERROR("cannot find ELF segment content, seek failed");
return retval;
}
- retval = fileio_read(&elf->fileio, read_size, buffer, &really_read);
+ retval = fileio_read(elf->fileio, read_size, buffer, &really_read);
if (retval != ERROR_OK) {
LOG_ERROR("cannot read ELF segment content, read failed");
return retval;
@@ -511,7 +509,7 @@ static int image_mot_buffer_complete_inner(struct image *image,
struct imagesection *section)
{
struct image_mot *mot = image->type_private;
- struct fileio *fileio = &mot->fileio;
+ struct fileio *fileio = mot->fileio;
uint32_t full_address = 0x0;
uint32_t cooked_bytes;
int i;
@@ -708,9 +706,9 @@ int image_open(struct image *image, const char *url, const char *type_string)
if (retval != ERROR_OK)
return retval;
size_t filesize;
- retval = fileio_size(&image_binary->fileio, &filesize);
+ retval = fileio_size(image_binary->fileio, &filesize);
if (retval != ERROR_OK) {
- fileio_close(&image_binary->fileio);
+ fileio_close(image_binary->fileio);
return retval;
}
@@ -731,8 +729,8 @@ int image_open(struct image *image, const char *url, const char *type_string)
retval = image_ihex_buffer_complete(image);
if (retval != ERROR_OK) {
LOG_ERROR(
- "failed buffering IHEX image, check daemon output for additional information");
- fileio_close(&image_ihex->fileio);
+ "failed buffering IHEX image, check server output for additional information");
+ fileio_close(image_ihex->fileio);
return retval;
}
} else if (image->type == IMAGE_ELF) {
@@ -746,7 +744,7 @@ int image_open(struct image *image, const char *url, const char *type_string)
retval = image_elf_read_headers(image);
if (retval != ERROR_OK) {
- fileio_close(&image_elf->fileio);
+ fileio_close(image_elf->fileio);
return retval;
}
} else if (image->type == IMAGE_MEMORY) {
@@ -782,8 +780,8 @@ int image_open(struct image *image, const char *url, const char *type_string)
retval = image_mot_buffer_complete(image);
if (retval != ERROR_OK) {
LOG_ERROR(
- "failed buffering S19 image, check daemon output for additional information");
- fileio_close(&image_mot->fileio);
+ "failed buffering S19 image, check server output for additional information");
+ fileio_close(image_mot->fileio);
return retval;
}
} else if (image->type == IMAGE_BUILDER) {
@@ -835,12 +833,12 @@ int image_read_section(struct image *image,
return ERROR_COMMAND_SYNTAX_ERROR;
/* seek to offset */
- retval = fileio_seek(&image_binary->fileio, offset);
+ retval = fileio_seek(image_binary->fileio, offset);
if (retval != ERROR_OK)
return retval;
/* return requested bytes */
- retval = fileio_read(&image_binary->fileio, size, buffer, size_read);
+ retval = fileio_read(image_binary->fileio, size, buffer, size_read);
if (retval != ERROR_OK)
return retval;
} else if (image->type == IMAGE_IHEX) {
@@ -945,11 +943,11 @@ void image_close(struct image *image)
if (image->type == IMAGE_BINARY) {
struct image_binary *image_binary = image->type_private;
- fileio_close(&image_binary->fileio);
+ fileio_close(image_binary->fileio);
} else if (image->type == IMAGE_IHEX) {
struct image_ihex *image_ihex = image->type_private;
- fileio_close(&image_ihex->fileio);
+ fileio_close(image_ihex->fileio);
if (image_ihex->buffer) {
free(image_ihex->buffer);
@@ -958,7 +956,7 @@ void image_close(struct image *image)
} else if (image->type == IMAGE_ELF) {
struct image_elf *image_elf = image->type_private;
- fileio_close(&image_elf->fileio);
+ fileio_close(image_elf->fileio);
if (image_elf->header) {
free(image_elf->header);
@@ -979,7 +977,7 @@ void image_close(struct image *image)
} else if (image->type == IMAGE_SRECORD) {
struct image_mot *image_mot = image->type_private;
- fileio_close(&image_mot->fileio);
+ fileio_close(image_mot->fileio);
if (image_mot->buffer) {
free(image_mot->buffer);
diff --git a/src/target/image.h b/src/target/image.h
index 5aeba2f79..9907a5f3f 100644
--- a/src/target/image.h
+++ b/src/target/image.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef IMAGE_H
-#define IMAGE_H
+#ifndef OPENOCD_TARGET_IMAGE_H
+#define OPENOCD_TARGET_IMAGE_H
#include
@@ -48,7 +46,7 @@ enum image_type {
};
struct imagesection {
- uint32_t base_address;
+ target_addr_t base_address;
uint32_t size;
int flags;
void *private; /* private data */
@@ -66,11 +64,11 @@ struct image {
};
struct image_binary {
- struct fileio fileio;
+ struct fileio *fileio;
};
struct image_ihex {
- struct fileio fileio;
+ struct fileio *fileio;
uint8_t *buffer;
};
@@ -81,7 +79,7 @@ struct image_memory {
};
struct image_elf {
- struct fileio fileio;
+ struct fileio *fileio;
Elf32_Ehdr *header;
Elf32_Phdr *segments;
uint32_t segment_count;
@@ -89,7 +87,7 @@ struct image_elf {
};
struct image_mot {
- struct fileio fileio;
+ struct fileio *fileio;
uint8_t *buffer;
};
@@ -109,4 +107,4 @@ int image_calculate_checksum(uint8_t *buffer, uint32_t nbytes,
#define ERROR_IMAGE_TEMPORARILY_UNAVAILABLE (-1402)
#define ERROR_IMAGE_CHECKSUM (-1403)
-#endif /* IMAGE_H */
+#endif /* OPENOCD_TARGET_IMAGE_H */
diff --git a/src/target/lakemont.c b/src/target/lakemont.c
index 055d94340..2bd12fd41 100644
--- a/src/target/lakemont.c
+++ b/src/target/lakemont.c
@@ -1,11 +1,12 @@
/*
- * Copyright(c) 2013 Intel Corporation.
+ * Copyright(c) 2013-2016 Intel Corporation.
*
* Adrian Burns (adrian.burns@intel.com)
* Thomas Faust (thomas.faust@intel.com)
* Ivan De Cesaris (ivan.de.cesaris@intel.com)
* Julien Carreno (julien.carreno@intel.com)
* 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
@@ -18,8 +19,7 @@
* 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., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*
* Contact Information:
* Intel Corporation
@@ -498,6 +498,12 @@ static int halt_prep(struct target *t)
if (write_hw_reg(t, DSAR, PM_DSAR, 0) != ERROR_OK)
return ERROR_FAIL;
LOG_DEBUG("write DSAR 0x%08" PRIx32, PM_DSAR);
+ if (write_hw_reg(t, CSB, PM_DSB, 0) != ERROR_OK)
+ return ERROR_FAIL;
+ LOG_DEBUG("write %s 0x%08" PRIx32, regs[CSB].name, PM_DSB);
+ if (write_hw_reg(t, CSL, PM_DSL, 0) != ERROR_OK)
+ return ERROR_FAIL;
+ LOG_DEBUG("write %s 0x%08" PRIx32, regs[CSL].name, PM_DSL);
if (write_hw_reg(t, DR7, PM_DR7, 0) != ERROR_OK)
return ERROR_FAIL;
LOG_DEBUG("write DR7 0x%08" PRIx32, PM_DR7);
@@ -511,8 +517,7 @@ static int halt_prep(struct target *t)
LOG_DEBUG("EFLAGS = 0x%08" PRIx32 ", VM86 = %d, IF = %d", eflags,
eflags & EFLAGS_VM86 ? 1 : 0,
eflags & EFLAGS_IF ? 1 : 0);
- if (eflags & EFLAGS_VM86
- || eflags & EFLAGS_IF) {
+ if ((eflags & EFLAGS_VM86) || (eflags & EFLAGS_IF)) {
x86_32->pm_regs[I(EFLAGS)] = eflags & ~(EFLAGS_VM86 | EFLAGS_IF);
if (write_hw_reg(t, EFLAGS, x86_32->pm_regs[I(EFLAGS)], 0) != ERROR_OK)
return ERROR_FAIL;
@@ -530,14 +535,14 @@ static int halt_prep(struct target *t)
LOG_DEBUG("write CSAR_CPL to 0 0x%08" PRIx32, x86_32->pm_regs[I(CSAR)]);
}
if (ssar & SSAR_DPL) {
- x86_32->pm_regs[I(SSAR)] = ssar & ~CSAR_DPL;
+ x86_32->pm_regs[I(SSAR)] = ssar & ~SSAR_DPL;
if (write_hw_reg(t, SSAR, x86_32->pm_regs[I(SSAR)], 0) != ERROR_OK)
return ERROR_FAIL;
LOG_DEBUG("write SSAR_CPL to 0 0x%08" PRIx32, x86_32->pm_regs[I(SSAR)]);
}
- /* if cache's are enabled, disable and flush */
- if (!(cr0 & CR0_CD)) {
+ /* if cache's are enabled, disable and flush, depending on the core version */
+ if (!(x86_32->core_type == LMT3_5) && !(cr0 & CR0_CD)) {
LOG_DEBUG("caching enabled CR0 = 0x%08" PRIx32, cr0);
if (cr0 & CR0_PG) {
x86_32->pm_regs[I(CR0)] = cr0 & ~CR0_PG;
@@ -563,6 +568,13 @@ static int do_halt(struct target *t)
t->state = TARGET_DEBUG_RUNNING;
if (enter_probemode(t) != ERROR_OK)
return ERROR_FAIL;
+
+ return lakemont_update_after_probemode_entry(t);
+}
+
+/* we need to expose the update to be able to complete the reset at SoC level */
+int lakemont_update_after_probemode_entry(struct target *t)
+{
if (save_context(t) != ERROR_OK)
return ERROR_FAIL;
if (halt_prep(t) != ERROR_OK)
@@ -677,16 +689,16 @@ static int write_hw_reg(struct target *t, int reg, uint32_t regval, uint8_t cach
arch_info->op,
regval);
- scan.out[0] = RDWRPDR;
x86_32->flush = 0; /* dont flush scans till we have a batch */
- if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK)
- return ERROR_FAIL;
- if (drscan(t, reg_buf, scan.out, PDR_SIZE) != ERROR_OK)
- return ERROR_FAIL;
if (submit_reg_pir(t, reg) != ERROR_OK)
return ERROR_FAIL;
if (submit_instruction_pir(t, SRAMACCESS) != ERROR_OK)
return ERROR_FAIL;
+ scan.out[0] = RDWRPDR;
+ if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK)
+ return ERROR_FAIL;
+ if (drscan(t, reg_buf, scan.out, PDR_SIZE) != ERROR_OK)
+ return ERROR_FAIL;
x86_32->flush = 1;
if (submit_instruction_pir(t, PDR2SRAM) != ERROR_OK)
return ERROR_FAIL;
@@ -982,7 +994,7 @@ int lakemont_halt(struct target *t)
}
}
-int lakemont_resume(struct target *t, int current, uint32_t address,
+int lakemont_resume(struct target *t, int current, target_addr_t address,
int handle_breakpoints, int debug_execution)
{
struct breakpoint *bp = NULL;
@@ -1024,7 +1036,7 @@ int lakemont_resume(struct target *t, int current, uint32_t address,
}
int lakemont_step(struct target *t, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
struct x86_32_common *x86_32 = target_to_x86_32(t);
uint32_t eflags = buf_get_u32(x86_32->cache->reg_list[EFLAGS].value, 0, 32);
diff --git a/src/target/lakemont.h b/src/target/lakemont.h
index 30b34b3f2..98efd44a9 100644
--- a/src/target/lakemont.h
+++ b/src/target/lakemont.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2013 Intel Corporation.
+ * Copyright(c) 2013-2016 Intel Corporation.
*
* Adrian Burns (adrian.burns@intel.com)
* Thomas Faust (thomas.faust@intel.com)
@@ -18,8 +18,7 @@
* 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., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*
* Contact Information:
* Intel Corporation
@@ -30,8 +29,9 @@
* This is the interface to the probemode operations for Lakemont 1 (LMT1).
*/
-#ifndef LAKEMONT_H
-#define LAKEMONT_H
+#ifndef OPENOCD_TARGET_LAKEMONT_H
+#define OPENOCD_TARGET_LAKEMONT_H
+
#include
#include
@@ -95,11 +95,12 @@ int lakemont_init_arch_info(struct target *t, struct x86_32_common *x86_32);
int lakemont_poll(struct target *t);
int lakemont_arch_state(struct target *t);
int lakemont_halt(struct target *t);
-int lakemont_resume(struct target *t, int current, uint32_t address,
+int lakemont_resume(struct target *t, int current, target_addr_t address,
int handle_breakpoints, int debug_execution);
int lakemont_step(struct target *t, int current,
- uint32_t address, int handle_breakpoints);
+ target_addr_t address, int handle_breakpoints);
int lakemont_reset_assert(struct target *t);
int lakemont_reset_deassert(struct target *t);
+int lakemont_update_after_probemode_entry(struct target *t);
-#endif /* LAKEMONT_H */
+#endif /* OPENOCD_TARGET_LAKEMONT_H */
diff --git a/src/target/mips32.c b/src/target/mips32.c
index 5a0e2a3a1..93fb4e646 100644
--- a/src/target/mips32.c
+++ b/src/target/mips32.c
@@ -21,9 +21,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -36,7 +34,7 @@
#include "register.h"
static const char *mips_isa_strings[] = {
- "MIPS32", "MIPS16e"
+ "MIPS32", "MIPS16", "", "MICRO MIPS32",
};
#define MIPS32_GDB_DUMMY_FP_REG 1
@@ -377,6 +375,7 @@ int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, s
target->arch_info = mips32;
mips32->common_magic = MIPS32_COMMON_MAGIC;
mips32->fast_data_area = NULL;
+ mips32->isa_imp = MIPS32_ONLY; /* default */
/* has breakpoint/watchpoint unit been scanned */
mips32->bp_scanned = 0;
@@ -385,16 +384,18 @@ int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, s
mips32->ejtag_info.tap = tap;
mips32->read_core_reg = mips32_read_core_reg;
mips32->write_core_reg = mips32_write_core_reg;
-
- mips32->ejtag_info.scan_delay = 2000000; /* Initial default value */
+ /* if unknown endianness defaults to little endian, 1 */
+ mips32->ejtag_info.endianness = target->endianness == TARGET_BIG_ENDIAN ? 0 : 1;
+ mips32->ejtag_info.scan_delay = MIPS32_SCAN_DELAY_LEGACY_MODE;
mips32->ejtag_info.mode = 0; /* Initial default value */
-
+ mips32->ejtag_info.isa = 0; /* isa on debug mips32, updated by poll function */
+ mips32->ejtag_info.config_regs = 0; /* no config register read */
return ERROR_OK;
}
/* run to exit point. return error if exit point was not reached. */
-static int mips32_run_and_wait(struct target *target, uint32_t entry_point,
- int timeout_ms, uint32_t exit_point, struct mips32_common *mips32)
+static int mips32_run_and_wait(struct target *target, target_addr_t entry_point,
+ int timeout_ms, target_addr_t exit_point, struct mips32_common *mips32)
{
uint32_t pc;
int retval;
@@ -427,8 +428,8 @@ static int mips32_run_and_wait(struct target *target, uint32_t entry_point,
int mips32_run_algorithm(struct target *target, int num_mem_params,
struct mem_param *mem_params, int num_reg_params,
- struct reg_param *reg_params, uint32_t entry_point,
- uint32_t exit_point, int timeout_ms, void *arch_info)
+ struct reg_param *reg_params, target_addr_t entry_point,
+ target_addr_t exit_point, int timeout_ms, void *arch_info)
{
struct mips32_common *mips32 = target_to_mips32(target);
struct mips32_algorithm *mips32_algorithm_info = arch_info;
@@ -698,57 +699,109 @@ int mips32_enable_interrupts(struct target *target, int enable)
return ERROR_OK;
}
-int mips32_checksum_memory(struct target *target, uint32_t address,
+/* read config to config3 cp0 registers and log isa implementation */
+int mips32_read_config_regs(struct target *target)
+{
+ struct mips32_common *mips32 = target_to_mips32(target);
+ struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+
+ if (ejtag_info->config_regs == 0)
+ for (int i = 0; i != 4; i++) {
+ int retval = mips32_cp0_read(ejtag_info, &ejtag_info->config[i], 16, i);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32, i);
+ ejtag_info->config_regs = 0;
+ return retval;
+ }
+ ejtag_info->config_regs = i + 1;
+ if ((ejtag_info->config[i] & (1 << 31)) == 0)
+ break; /* no more config registers implemented */
+ }
+ else
+ return ERROR_OK; /* already succesfully read */
+
+ LOG_DEBUG("read %"PRId32" config registers", ejtag_info->config_regs);
+
+ if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
+ mips32->isa_imp = MIPS32_MIPS16;
+ LOG_USER("MIPS32 with MIPS16 support implemented");
+
+ } else if (ejtag_info->config_regs >= 4) { /* config3 implemented */
+ unsigned isa_imp = (ejtag_info->config[3] & MIPS32_CONFIG3_ISA_MASK) >> MIPS32_CONFIG3_ISA_SHIFT;
+ if (isa_imp == 1) {
+ mips32->isa_imp = MMIPS32_ONLY;
+ LOG_USER("MICRO MIPS32 only implemented");
+
+ } else if (isa_imp != 0) {
+ mips32->isa_imp = MIPS32_MMIPS32;
+ LOG_USER("MIPS32 and MICRO MIPS32 implemented");
+ }
+ }
+
+ if (mips32->isa_imp == MIPS32_ONLY) /* initial default value */
+ LOG_USER("MIPS32 only implemented");
+
+ return ERROR_OK;
+}
+int mips32_checksum_memory(struct target *target, target_addr_t address,
uint32_t count, uint32_t *checksum)
{
struct working_area *crc_algorithm;
struct reg_param reg_params[2];
struct mips32_algorithm mips32_info;
- /* see contrib/loaders/checksum/mips32.s for src */
+ struct mips32_common *mips32 = target_to_mips32(target);
+ struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
- static const uint32_t mips_crc_code[] = {
- 0x248C0000, /* addiu $t4, $a0, 0 */
- 0x24AA0000, /* addiu $t2, $a1, 0 */
- 0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */
- 0x10000010, /* beq $zero, $zero, ncomp */
- 0x240B0000, /* addiu $t3, $zero, 0 */
+ /* see contrib/loaders/checksum/mips32.s for src */
+ uint32_t isa = ejtag_info->isa ? 1 : 0;
+
+ uint32_t mips_crc_code[] = {
+ MIPS32_ADDIU(isa, 12, 4, 0), /* addiu $t4, $a0, 0 */
+ MIPS32_ADDIU(isa, 10, 5, 0), /* addiu $t2, $a1, 0 */
+ MIPS32_ADDIU(isa, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
+ MIPS32_BEQ(isa, 0, 0, 0x10 << isa), /* beq $zero, $zero, ncomp */
+ MIPS32_ADDIU(isa, 11, 0, 0), /* addiu $t3, $zero, 0 */
/* nbyte: */
- 0x81850000, /* lb $a1, ($t4) */
- 0x218C0001, /* addi $t4, $t4, 1 */
- 0x00052E00, /* sll $a1, $a1, 24 */
- 0x3C0204C1, /* lui $v0, 0x04c1 */
- 0x00852026, /* xor $a0, $a0, $a1 */
- 0x34471DB7, /* ori $a3, $v0, 0x1db7 */
- 0x00003021, /* addu $a2, $zero, $zero */
- /* loop: */
- 0x00044040, /* sll $t0, $a0, 1 */
- 0x24C60001, /* addiu $a2, $a2, 1 */
- 0x28840000, /* slti $a0, $a0, 0 */
- 0x01074826, /* xor $t1, $t0, $a3 */
- 0x0124400B, /* movn $t0, $t1, $a0 */
- 0x28C30008, /* slti $v1, $a2, 8 */
- 0x1460FFF9, /* bne $v1, $zero, loop */
- 0x01002021, /* addu $a0, $t0, $zero */
- /* ncomp: */
- 0x154BFFF0, /* bne $t2, $t3, nbyte */
- 0x256B0001, /* addiu $t3, $t3, 1 */
- 0x7000003F, /* sdbbp */
+ MIPS32_LB(isa, 5, 0, 12), /* lb $a1, ($t4) */
+ MIPS32_ADDI(isa, 12, 12, 1), /* addi $t4, $t4, 1 */
+ MIPS32_SLL(isa, 5, 5, 24), /* sll $a1, $a1, 24 */
+ MIPS32_LUI(isa, 2, 0x04c1), /* lui $v0, 0x04c1 */
+ MIPS32_XOR(isa, 4, 4, 5), /* xor $a0, $a0, $a1 */
+ MIPS32_ORI(isa, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
+ MIPS32_ADDU(isa, 6, 0, 0), /* addu $a2, $zero, $zero */
+ /* loop */
+ MIPS32_SLL(isa, 8, 4, 1), /* sll $t0, $a0, 1 */
+ MIPS32_ADDIU(isa, 6, 6, 1), /* addiu $a2, $a2, 1 */
+ MIPS32_SLTI(isa, 4, 4, 0), /* slti $a0, $a0, 0 */
+ MIPS32_XOR(isa, 9, 8, 7), /* xor $t1, $t0, $a3 */
+ MIPS32_MOVN(isa, 8, 9, 4), /* movn $t0, $t1, $a0 */
+ MIPS32_SLTI(isa, 3, 6, 8), /* slti $v1, $a2, 8 */
+ MIPS32_BNE(isa, 3, 0, NEG16(7 << isa)), /* bne $v1, $zero, loop */
+ MIPS32_ADDU(isa, 4, 8, 0), /* addu $a0, $t0, $zero */
+ /* ncomp */
+ MIPS32_BNE(isa, 10, 11, NEG16(16 << isa)), /* bne $t2, $t3, nbyte */
+ MIPS32_ADDIU(isa, 11, 11, 1), /* addiu $t3, $t3, 1 */
+ MIPS32_SDBBP(isa),
};
/* make sure we have a working area */
if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ pracc_swap16_array(ejtag_info, mips_crc_code, ARRAY_SIZE(mips_crc_code));
+
/* convert mips crc code into a buffer in target endianness */
uint8_t mips_crc_code_8[sizeof(mips_crc_code)];
target_buffer_set_u32_array(target, mips_crc_code_8,
ARRAY_SIZE(mips_crc_code), mips_crc_code);
- target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);
+ int retval = target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);
+ if (retval != ERROR_OK)
+ return retval;
mips32_info.common_magic = MIPS32_COMMON_MAGIC;
- mips32_info.isa_mode = MIPS32_ISA_MIPS32;
+ mips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32; /* run isa as in debug mode */
init_reg_param(®_params[0], "r4", 32, PARAM_IN_OUT);
buf_set_u32(reg_params[0].value, 0, 32, address);
@@ -758,9 +811,8 @@ int mips32_checksum_memory(struct target *target, uint32_t address,
int timeout = 20000 * (1 + (count / (1024 * 1024)));
- int retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
- crc_algorithm->address, crc_algorithm->address + (sizeof(mips_crc_code) - 4), timeout,
- &mips32_info);
+ retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,
+ crc_algorithm->address + (sizeof(mips_crc_code) - 4), timeout, &mips32_info);
if (retval == ERROR_OK)
*checksum = buf_get_u32(reg_params[0].value, 0, 32);
@@ -773,37 +825,51 @@ int mips32_checksum_memory(struct target *target, uint32_t address,
return retval;
}
-/** Checks whether a memory region is zeroed. */
+/** Checks whether a memory region is erased. */
int mips32_blank_check_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *blank)
+ target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
{
struct working_area *erase_check_algorithm;
struct reg_param reg_params[3];
struct mips32_algorithm mips32_info;
- static const uint32_t erase_check_code[] = {
+ struct mips32_common *mips32 = target_to_mips32(target);
+ struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+
+ if (erased_value != 0xff) {
+ LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for MIPS32",
+ erased_value);
+ return ERROR_FAIL;
+ }
+ uint32_t isa = ejtag_info->isa ? 1 : 0;
+ uint32_t erase_check_code[] = {
/* nbyte: */
- 0x80880000, /* lb $t0, ($a0) */
- 0x00C83024, /* and $a2, $a2, $t0 */
- 0x24A5FFFF, /* addiu $a1, $a1, -1 */
- 0x14A0FFFC, /* bne $a1, $zero, nbyte */
- 0x24840001, /* addiu $a0, $a0, 1 */
- 0x7000003F /* sdbbp */
+ MIPS32_LB(isa, 8, 0, 4), /* lb $t0, ($a0) */
+ MIPS32_AND(isa, 6, 6, 8), /* and $a2, $a2, $t0 */
+ MIPS32_ADDIU(isa, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
+ MIPS32_BNE(isa, 5, 0, NEG16(4 << isa)), /* bne $a1, $zero, nbyte */
+ MIPS32_ADDIU(isa, 4, 4, 1), /* addiu $a0, $a0, 1 */
+ MIPS32_SDBBP(isa) /* sdbbp */
};
/* make sure we have a working area */
if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ pracc_swap16_array(ejtag_info, erase_check_code, ARRAY_SIZE(erase_check_code));
+
/* convert erase check code into a buffer in target endianness */
uint8_t erase_check_code_8[sizeof(erase_check_code)];
target_buffer_set_u32_array(target, erase_check_code_8,
ARRAY_SIZE(erase_check_code), erase_check_code);
- target_write_buffer(target, erase_check_algorithm->address, sizeof(erase_check_code), erase_check_code_8);
+ int retval = target_write_buffer(target, erase_check_algorithm->address,
+ sizeof(erase_check_code), erase_check_code_8);
+ if (retval != ERROR_OK)
+ return retval;
mips32_info.common_magic = MIPS32_COMMON_MAGIC;
- mips32_info.isa_mode = MIPS32_ISA_MIPS32;
+ mips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32;
init_reg_param(®_params[0], "r4", 32, PARAM_OUT);
buf_set_u32(reg_params[0].value, 0, 32, address);
@@ -812,12 +878,10 @@ int mips32_blank_check_memory(struct target *target,
buf_set_u32(reg_params[1].value, 0, 32, count);
init_reg_param(®_params[2], "r6", 32, PARAM_IN_OUT);
- buf_set_u32(reg_params[2].value, 0, 32, 0xff);
+ buf_set_u32(reg_params[2].value, 0, 32, erased_value);
- int retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
- erase_check_algorithm->address,
- erase_check_algorithm->address + (sizeof(erase_check_code) - 4),
- 10000, &mips32_info);
+ retval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address,
+ erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &mips32_info);
if (retval == ERROR_OK)
*blank = buf_get_u32(reg_params[2].value, 0, 32);
@@ -913,7 +977,7 @@ COMMAND_HANDLER(mips32_handle_scan_delay_command)
return ERROR_COMMAND_SYNTAX_ERROR;
command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay);
- if (ejtag_info->scan_delay >= 2000000) {
+ if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {
ejtag_info->mode = 0;
command_print(CMD_CTX, "running in legacy mode");
} else {
diff --git a/src/target/mips32.h b/src/target/mips32.h
index 56f4fb4e1..928598f4c 100644
--- a/src/target/mips32.h
+++ b/src/target/mips32.h
@@ -18,13 +18,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef MIPS32_H
-#define MIPS32_H
+#ifndef OPENOCD_TARGET_MIPS32_H
+#define OPENOCD_TARGET_MIPS32_H
#include "target.h"
#include "mips32_pracc.h"
@@ -60,9 +58,14 @@
#define MIPS32_CONFIG1_DL_SHIFT 10
#define MIPS32_CONFIG1_DL_MASK (0x7 << MIPS32_CONFIG1_DL_SHIFT)
+#define MIPS32_CONFIG3_ISA_SHIFT 14
+#define MIPS32_CONFIG3_ISA_MASK (3 << MIPS32_CONFIG3_ISA_SHIFT)
+
#define MIPS32_ARCH_REL1 0x0
#define MIPS32_ARCH_REL2 0x1
+#define MIPS32_SCAN_DELAY_LEGACY_MODE 2000000
+
/* offsets into mips32 core register cache */
enum {
MIPS32_PC = 37,
@@ -73,6 +76,14 @@ enum {
enum mips32_isa_mode {
MIPS32_ISA_MIPS32 = 0,
MIPS32_ISA_MIPS16E = 1,
+ MIPS32_ISA_MMIPS32 = 3,
+};
+
+enum mips32_isa_imp {
+ MIPS32_ONLY = 0,
+ MMIPS32_ONLY = 1,
+ MIPS32_MIPS16 = 2,
+ MIPS32_MMIPS32 = 3,
};
struct mips32_comparator {
@@ -88,6 +99,7 @@ struct mips32_common {
struct mips_ejtag ejtag_info;
uint32_t core_regs[MIPS32NUMCOREREGS];
enum mips32_isa_mode isa_mode;
+ enum mips32_isa_imp isa_imp;
/* working area for fastdata access */
struct working_area *fast_data_area;
@@ -122,44 +134,49 @@ struct mips32_algorithm {
enum mips32_isa_mode isa_mode;
};
-#define MIPS32_OP_ADDIU 0x21
-#define MIPS32_OP_ANDI 0x0C
-#define MIPS32_OP_BEQ 0x04
-#define MIPS32_OP_BGTZ 0x07
-#define MIPS32_OP_BNE 0x05
-#define MIPS32_OP_ADDI 0x08
-#define MIPS32_OP_AND 0x24
-#define MIPS32_OP_CACHE 0x2F
-#define MIPS32_OP_COP0 0x10
-#define MIPS32_OP_J 0x02
-#define MIPS32_OP_JR 0x08
-#define MIPS32_OP_LUI 0x0F
-#define MIPS32_OP_LW 0x23
-#define MIPS32_OP_LBU 0x24
-#define MIPS32_OP_LHU 0x25
-#define MIPS32_OP_MFHI 0x10
-#define MIPS32_OP_MTHI 0x11
-#define MIPS32_OP_MFLO 0x12
-#define MIPS32_OP_MTLO 0x13
-#define MIPS32_OP_RDHWR 0x3B
-#define MIPS32_OP_SB 0x28
-#define MIPS32_OP_SH 0x29
-#define MIPS32_OP_SW 0x2B
-#define MIPS32_OP_ORI 0x0D
-#define MIPS32_OP_XORI 0x0E
-#define MIPS32_OP_XOR 0x26
-#define MIPS32_OP_SLTU 0x2B
-#define MIPS32_OP_SRL 0x03
-#define MIPS32_OP_SYNCI 0x1F
-
-#define MIPS32_OP_REGIMM 0x01
-#define MIPS32_OP_SDBBP 0x3F
-#define MIPS32_OP_SPECIAL 0x00
-#define MIPS32_OP_SPECIAL2 0x07
-#define MIPS32_OP_SPECIAL3 0x1F
-
-#define MIPS32_COP0_MF 0x00
-#define MIPS32_COP0_MT 0x04
+#define MIPS32_OP_ADDU 0x21u
+#define MIPS32_OP_ADDIU 0x09u
+#define MIPS32_OP_ANDI 0x0Cu
+#define MIPS32_OP_BEQ 0x04u
+#define MIPS32_OP_BGTZ 0x07u
+#define MIPS32_OP_BNE 0x05u
+#define MIPS32_OP_ADDI 0x08u
+#define MIPS32_OP_AND 0x24u
+#define MIPS32_OP_CACHE 0x2Fu
+#define MIPS32_OP_COP0 0x10u
+#define MIPS32_OP_J 0x02u
+#define MIPS32_OP_JR 0x08u
+#define MIPS32_OP_LUI 0x0Fu
+#define MIPS32_OP_LW 0x23u
+#define MIPS32_OP_LB 0x20u
+#define MIPS32_OP_LBU 0x24u
+#define MIPS32_OP_LHU 0x25u
+#define MIPS32_OP_MFHI 0x10u
+#define MIPS32_OP_MTHI 0x11u
+#define MIPS32_OP_MFLO 0x12u
+#define MIPS32_OP_MTLO 0x13u
+#define MIPS32_OP_RDHWR 0x3Bu
+#define MIPS32_OP_SB 0x28u
+#define MIPS32_OP_SH 0x29u
+#define MIPS32_OP_SW 0x2Bu
+#define MIPS32_OP_ORI 0x0Du
+#define MIPS32_OP_XORI 0x0Eu
+#define MIPS32_OP_XOR 0x26u
+#define MIPS32_OP_SLTU 0x2Bu
+#define MIPS32_OP_SRL 0x03u
+#define MIPS32_OP_SYNCI 0x1Fu
+#define MIPS32_OP_SLL 0x00u
+#define MIPS32_OP_SLTI 0x0Au
+#define MIPS32_OP_MOVN 0x0Bu
+
+#define MIPS32_OP_REGIMM 0x01u
+#define MIPS32_OP_SDBBP 0x3Fu
+#define MIPS32_OP_SPECIAL 0x00u
+#define MIPS32_OP_SPECIAL2 0x07u
+#define MIPS32_OP_SPECIAL3 0x1Fu
+
+#define MIPS32_COP0_MF 0x00u
+#define MIPS32_COP0_MT 0x04u
#define MIPS32_R_INST(opcode, rs, rt, rd, shamt, funct) \
(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((shamt) << 6) | (funct))
@@ -167,41 +184,52 @@ struct mips32_algorithm {
(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | (immd))
#define MIPS32_J_INST(opcode, addr) (((opcode) << 26) | (addr))
-#define MIPS32_NOP 0
-#define MIPS32_ADDI(tar, src, val) MIPS32_I_INST(MIPS32_OP_ADDI, src, tar, val)
-#define MIPS32_ADDU(dst, src, tar) MIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_ADDIU)
-#define MIPS32_AND(reg, off, val) MIPS32_R_INST(0, off, val, reg, 0, MIPS32_OP_AND)
-#define MIPS32_ANDI(tar, src, val) MIPS32_I_INST(MIPS32_OP_ANDI, src, tar, val)
-#define MIPS32_B(off) MIPS32_BEQ(0, 0, off)
-#define MIPS32_BEQ(src, tar, off) MIPS32_I_INST(MIPS32_OP_BEQ, src, tar, off)
-#define MIPS32_BGTZ(reg, off) MIPS32_I_INST(MIPS32_OP_BGTZ, reg, 0, off)
-#define MIPS32_BNE(src, tar, off) MIPS32_I_INST(MIPS32_OP_BNE, src, tar, off)
-#define MIPS32_CACHE(op, off, base) MIPS32_I_INST(MIPS32_OP_CACHE, base, op, off)
-#define MIPS32_J(tar) MIPS32_J_INST(MIPS32_OP_J, tar)
-#define MIPS32_JR(reg) MIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_JR)
-#define MIPS32_MFC0(gpr, cpr, sel) MIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MF, gpr, cpr, 0, sel)
-#define MIPS32_MTC0(gpr, cpr, sel) MIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MT, gpr, cpr, 0, sel)
-#define MIPS32_LBU(reg, off, base) MIPS32_I_INST(MIPS32_OP_LBU, base, reg, off)
-#define MIPS32_LHU(reg, off, base) MIPS32_I_INST(MIPS32_OP_LHU, base, reg, off)
-#define MIPS32_LUI(reg, val) MIPS32_I_INST(MIPS32_OP_LUI, 0, reg, val)
-#define MIPS32_LW(reg, off, base) MIPS32_I_INST(MIPS32_OP_LW, base, reg, off)
-#define MIPS32_MFLO(reg) MIPS32_R_INST(0, 0, 0, reg, 0, MIPS32_OP_MFLO)
-#define MIPS32_MFHI(reg) MIPS32_R_INST(0, 0, 0, reg, 0, MIPS32_OP_MFHI)
-#define MIPS32_MTLO(reg) MIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_MTLO)
-#define MIPS32_MTHI(reg) MIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_MTHI)
-#define MIPS32_ORI(tar, src, val) MIPS32_I_INST(MIPS32_OP_ORI, src, tar, val)
-#define MIPS32_XORI(tar, src, val) MIPS32_I_INST(MIPS32_OP_XORI, src, tar, val)
-#define MIPS32_RDHWR(tar, dst) MIPS32_R_INST(MIPS32_OP_SPECIAL3, 0, tar, dst, 0, MIPS32_OP_RDHWR)
-#define MIPS32_SB(reg, off, base) MIPS32_I_INST(MIPS32_OP_SB, base, reg, off)
-#define MIPS32_SH(reg, off, base) MIPS32_I_INST(MIPS32_OP_SH, base, reg, off)
-#define MIPS32_SW(reg, off, base) MIPS32_I_INST(MIPS32_OP_SW, base, reg, off)
-#define MIPS32_XOR(reg, val1, val2) MIPS32_R_INST(0, val1, val2, reg, 0, MIPS32_OP_XOR)
-#define MIPS32_SRL(reg, src, off) MIPS32_R_INST(0, 0, src, reg, off, MIPS32_OP_SRL)
-#define MIPS32_SLTU(dst, src, tar) MIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_SLTU)
-#define MIPS32_SYNCI(off, base) MIPS32_I_INST(MIPS32_OP_REGIMM, base, MIPS32_OP_SYNCI, off)
-
-#define MIPS32_SYNC 0xF
-#define MIPS32_SYNCI_STEP 0x1 /* reg num od address step size to be used with synci instruction */
+#define MIPS32_ISA_NOP 0
+#define MIPS32_ISA_ADDI(tar, src, val) MIPS32_I_INST(MIPS32_OP_ADDI, src, tar, val)
+#define MIPS32_ISA_ADDIU(tar, src, val) MIPS32_I_INST(MIPS32_OP_ADDIU, src, tar, val)
+#define MIPS32_ISA_ADDU(dst, src, tar) MIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_ADDU)
+#define MIPS32_ISA_AND(dst, src, tar) MIPS32_R_INST(0, src, tar, dst, 0, MIPS32_OP_AND)
+#define MIPS32_ISA_ANDI(tar, src, val) MIPS32_I_INST(MIPS32_OP_ANDI, src, tar, val)
+
+#define MIPS32_ISA_B(off) MIPS32_ISA_BEQ(0, 0, off)
+#define MIPS32_ISA_BEQ(src, tar, off) MIPS32_I_INST(MIPS32_OP_BEQ, src, tar, off)
+#define MIPS32_ISA_BGTZ(reg, off) MIPS32_I_INST(MIPS32_OP_BGTZ, reg, 0, off)
+#define MIPS32_ISA_BNE(src, tar, off) MIPS32_I_INST(MIPS32_OP_BNE, src, tar, off)
+#define MIPS32_ISA_CACHE(op, off, base) MIPS32_I_INST(MIPS32_OP_CACHE, base, op, off)
+#define MIPS32_ISA_J(tar) MIPS32_J_INST(MIPS32_OP_J, (0x0FFFFFFFu & (tar)) >> 2)
+#define MIPS32_ISA_JR(reg) MIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_JR)
+
+#define MIPS32_ISA_LB(reg, off, base) MIPS32_I_INST(MIPS32_OP_LB, base, reg, off)
+#define MIPS32_ISA_LBU(reg, off, base) MIPS32_I_INST(MIPS32_OP_LBU, base, reg, off)
+#define MIPS32_ISA_LHU(reg, off, base) MIPS32_I_INST(MIPS32_OP_LHU, base, reg, off)
+#define MIPS32_ISA_LUI(reg, val) MIPS32_I_INST(MIPS32_OP_LUI, 0, reg, val)
+#define MIPS32_ISA_LW(reg, off, base) MIPS32_I_INST(MIPS32_OP_LW, base, reg, off)
+
+#define MIPS32_ISA_MFC0(gpr, cpr, sel) MIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MF, gpr, cpr, 0, sel)
+#define MIPS32_ISA_MTC0(gpr, cpr, sel) MIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MT, gpr, cpr, 0, sel)
+#define MIPS32_ISA_MFLO(reg) MIPS32_R_INST(0, 0, 0, reg, 0, MIPS32_OP_MFLO)
+#define MIPS32_ISA_MFHI(reg) MIPS32_R_INST(0, 0, 0, reg, 0, MIPS32_OP_MFHI)
+#define MIPS32_ISA_MTLO(reg) MIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_MTLO)
+#define MIPS32_ISA_MTHI(reg) MIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_MTHI)
+
+#define MIPS32_ISA_MOVN(dst, src, tar) MIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_MOVN)
+#define MIPS32_ISA_ORI(tar, src, val) MIPS32_I_INST(MIPS32_OP_ORI, src, tar, val)
+#define MIPS32_ISA_RDHWR(tar, dst) MIPS32_R_INST(MIPS32_OP_SPECIAL3, 0, tar, dst, 0, MIPS32_OP_RDHWR)
+#define MIPS32_ISA_SB(reg, off, base) MIPS32_I_INST(MIPS32_OP_SB, base, reg, off)
+#define MIPS32_ISA_SH(reg, off, base) MIPS32_I_INST(MIPS32_OP_SH, base, reg, off)
+#define MIPS32_ISA_SW(reg, off, base) MIPS32_I_INST(MIPS32_OP_SW, base, reg, off)
+
+#define MIPS32_ISA_SLL(dst, src, sa) MIPS32_R_INST(MIPS32_OP_SPECIAL, 0, src, dst, sa, MIPS32_OP_SLL)
+#define MIPS32_ISA_SLTI(tar, src, val) MIPS32_I_INST(MIPS32_OP_SLTI, src, tar, val)
+#define MIPS32_ISA_SLTU(dst, src, tar) MIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_SLTU)
+#define MIPS32_ISA_SRL(reg, src, off) MIPS32_R_INST(0, 0, src, reg, off, MIPS32_OP_SRL)
+#define MIPS32_ISA_SYNC 0xFu
+#define MIPS32_ISA_SYNCI(off, base) MIPS32_I_INST(MIPS32_OP_REGIMM, base, MIPS32_OP_SYNCI, off)
+
+#define MIPS32_ISA_XOR(reg, val1, val2) MIPS32_R_INST(0, val1, val2, reg, 0, MIPS32_OP_XOR)
+#define MIPS32_ISA_XORI(tar, src, val) MIPS32_I_INST(MIPS32_OP_XORI, src, tar, val)
+
+#define MIPS32_ISA_SYNCI_STEP 0x1 /* reg num od address step size to be used with synci instruction */
/**
* Cache operations definitions
@@ -213,9 +241,158 @@ struct mips32_algorithm {
#define MIPS32_CACHE_I_HIT_INVALIDATE ((0x0 << 0) | (0x4 << 2))
/* ejtag specific instructions */
-#define MIPS32_DRET 0x4200001F
-#define MIPS32_SDBBP 0x7000003F /* MIPS32_J_INST(MIPS32_OP_SPECIAL2, MIPS32_OP_SDBBP) */
-#define MIPS16_SDBBP 0xE801
+#define MIPS32_ISA_DRET 0x4200001Fu
+/* MIPS32_ISA_J_INST(MIPS32_ISA_OP_SPECIAL2, MIPS32_ISA_OP_SDBBP) */
+#define MIPS32_ISA_SDBBP 0x7000003Fu
+#define MIPS16_ISA_SDBBP 0xE801u
+
+/*MICRO MIPS INSTRUCTIONS, see doc MD00582 */
+#define POOL32A 0X00u
+#define POOL32AXf 0x3Cu
+#define POOL32B 0x08u
+#define POOL32I 0x10u
+#define MMIPS32_OP_ADDI 0x04u
+#define MMIPS32_OP_ADDIU 0x0Cu
+#define MMIPS32_OP_ADDU 0x150u
+#define MMIPS32_OP_AND 0x250u
+#define MMIPS32_OP_ANDI 0x34u
+#define MMIPS32_OP_BEQ 0x25u
+#define MMIPS32_OP_BGTZ 0x06u
+#define MMIPS32_OP_BNE 0x2Du
+#define MMIPS32_OP_CACHE 0x06u
+#define MMIPS32_OP_J 0x35u
+#define MMIPS32_OP_JALR 0x03Cu
+#define MMIPS32_OP_LB 0x07u
+#define MMIPS32_OP_LBU 0x05u
+#define MMIPS32_OP_LHU 0x0Du
+#define MMIPS32_OP_LUI 0x0Du
+#define MMIPS32_OP_LW 0x3Fu
+#define MMIPS32_OP_MFC0 0x03u
+#define MMIPS32_OP_MTC0 0x0Bu
+#define MMIPS32_OP_MFLO 0x075u
+#define MMIPS32_OP_MFHI 0x035u
+#define MMIPS32_OP_MTLO 0x0F5u
+#define MMIPS32_OP_MTHI 0x0B5u
+#define MMIPS32_OP_MOVN 0x018u
+#define MMIPS32_OP_ORI 0x14u
+#define MMIPS32_OP_RDHWR 0x1ACu
+#define MMIPS32_OP_SB 0x06u
+#define MMIPS32_OP_SH 0x0Eu
+#define MMIPS32_OP_SW 0x3Eu
+#define MMIPS32_OP_SLTU 0x390u
+#define MMIPS32_OP_SLL 0x000u
+#define MMIPS32_OP_SLTI 0x24u
+#define MMIPS32_OP_SRL 0x040u
+#define MMIPS32_OP_SYNCI 0x10u
+#define MMIPS32_OP_XOR 0x310u
+#define MMIPS32_OP_XORI 0x1Cu
+
+#define MMIPS32_ADDI(tar, src, val) MIPS32_I_INST(MMIPS32_OP_ADDI, tar, src, val)
+#define MMIPS32_ADDIU(tar, src, val) MIPS32_I_INST(MMIPS32_OP_ADDIU, tar, src, val)
+#define MMIPS32_ADDU(dst, src, tar) MIPS32_R_INST(POOL32A, tar, src, dst, 0, MMIPS32_OP_ADDU)
+#define MMIPS32_AND(dst, src, tar) MIPS32_R_INST(POOL32A, tar, src, dst, 0, MMIPS32_OP_AND)
+#define MMIPS32_ANDI(tar, src, val) MIPS32_I_INST(MMIPS32_OP_ANDI, tar, src, val)
+
+#define MMIPS32_B(off) MMIPS32_BEQ(0, 0, off)
+#define MMIPS32_BEQ(src, tar, off) MIPS32_I_INST(MMIPS32_OP_BEQ, tar, src, off)
+#define MMIPS32_BGTZ(reg, off) MIPS32_I_INST(POOL32I, MMIPS32_OP_BGTZ, reg, off)
+#define MMIPS32_BNE(src, tar, off) MIPS32_I_INST(MMIPS32_OP_BNE, tar, src, off)
+#define MMIPS32_CACHE(op, off, base) MIPS32_R_INST(POOL32B, op, base, MMIPS32_OP_CACHE << 1, 0, off)
+
+#define MMIPS32_J(tar) MIPS32_J_INST(MMIPS32_OP_J, ((0x07FFFFFFu & ((tar) >> 1))))
+#define MMIPS32_JR(reg) MIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_JALR, POOL32AXf)
+#define MMIPS32_LB(reg, off, base) MIPS32_I_INST(MMIPS32_OP_LB, reg, base, off)
+#define MMIPS32_LBU(reg, off, base) MIPS32_I_INST(MMIPS32_OP_LBU, reg, base, off)
+#define MMIPS32_LHU(reg, off, base) MIPS32_I_INST(MMIPS32_OP_LHU, reg, base, off)
+#define MMIPS32_LUI(reg, val) MIPS32_I_INST(POOL32I, MMIPS32_OP_LUI, reg, val)
+#define MMIPS32_LW(reg, off, base) MIPS32_I_INST(MMIPS32_OP_LW, reg, base, off)
+
+#define MMIPS32_MFC0(gpr, cpr, sel) MIPS32_R_INST(POOL32A, gpr, cpr, sel, MMIPS32_OP_MFC0, POOL32AXf)
+#define MMIPS32_MFLO(reg) MIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_MFLO, POOL32AXf)
+#define MMIPS32_MFHI(reg) MIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_MFHI, POOL32AXf)
+#define MMIPS32_MTC0(gpr, cpr, sel) MIPS32_R_INST(POOL32A, gpr, cpr, sel, MMIPS32_OP_MTC0, POOL32AXf)
+#define MMIPS32_MTLO(reg) MIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_MTLO, POOL32AXf)
+#define MMIPS32_MTHI(reg) MIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_MTHI, POOL32AXf)
+
+#define MMIPS32_MOVN(dst, src, tar) MIPS32_R_INST(POOL32A, tar, src, dst, 0, MMIPS32_OP_MOVN)
+#define MMIPS32_NOP 0
+#define MMIPS32_ORI(tar, src, val) MIPS32_I_INST(MMIPS32_OP_ORI, tar, src, val)
+#define MMIPS32_RDHWR(tar, dst) MIPS32_R_INST(POOL32A, dst, tar, 0, MMIPS32_OP_RDHWR, POOL32AXf)
+#define MMIPS32_SB(reg, off, base) MIPS32_I_INST(MMIPS32_OP_SB, reg, base, off)
+#define MMIPS32_SH(reg, off, base) MIPS32_I_INST(MMIPS32_OP_SH, reg, base, off)
+#define MMIPS32_SW(reg, off, base) MIPS32_I_INST(MMIPS32_OP_SW, reg, base, off)
+
+#define MMIPS32_SRL(reg, src, off) MIPS32_R_INST(POOL32A, reg, src, off, 0, MMIPS32_OP_SRL)
+#define MMIPS32_SLTU(dst, src, tar) MIPS32_R_INST(POOL32A, tar, src, dst, 0, MMIPS32_OP_SLTU)
+#define MMIPS32_SYNCI(off, base) MIPS32_I_INST(POOL32I, MMIPS32_OP_SYNCI, base, off)
+#define MMIPS32_SLL(dst, src, sa) MIPS32_R_INST(POOL32A, dst, src, sa, 0, MMIPS32_OP_SLL)
+#define MMIPS32_SLTI(tar, src, val) MIPS32_I_INST(MMIPS32_OP_SLTI, tar, src, val)
+#define MMIPS32_SYNC 0x00001A7Cu /* MIPS32_R_INST(POOL32A, 0, 0, 0, 0x1ADu, POOL32AXf) */
+
+#define MMIPS32_XOR(reg, val1, val2) MIPS32_R_INST(POOL32A, val1, val2, reg, 0, MMIPS32_OP_XOR)
+#define MMIPS32_XORI(tar, src, val) MIPS32_I_INST(MMIPS32_OP_XORI, tar, src, val)
+
+#define MMIPS32_SYNCI_STEP 0x1u /* reg num od address step size to be used with synci instruction */
+
+
+/* ejtag specific instructions */
+#define MMIPS32_DRET 0x0000E37Cu /* MIPS32_R_INST(POOL32A, 0, 0, 0, 0x38D, POOL32AXf) */
+#define MMIPS32_SDBBP 0x0000DB7Cu /* MIPS32_R_INST(POOL32A, 0, 0, 0, 0x1BD, POOL32AXf) */
+#define MMIPS16_SDBBP 0x46C0u /* POOL16C instr */
+
+/* instruction code with isa selection */
+#define MIPS32_NOP 0 /* same for both isa's */
+#define MIPS32_ADDI(isa, tar, src, val) (isa ? MMIPS32_ADDI(tar, src, val) : MIPS32_ISA_ADDI(tar, src, val))
+#define MIPS32_ADDIU(isa, tar, src, val) (isa ? MMIPS32_ADDIU(tar, src, val) : MIPS32_ISA_ADDIU(tar, src, val))
+#define MIPS32_ADDU(isa, dst, src, tar) (isa ? MMIPS32_ADDU(dst, src, tar) : MIPS32_ISA_ADDU(dst, src, tar))
+#define MIPS32_AND(isa, dst, src, tar) (isa ? MMIPS32_AND(dst, src, tar) : MIPS32_ISA_AND(dst, src, tar))
+#define MIPS32_ANDI(isa, tar, src, val) (isa ? MMIPS32_ANDI(tar, src, val) : MIPS32_ISA_ANDI(tar, src, val))
+
+#define MIPS32_B(isa, off) (isa ? MMIPS32_B(off) : MIPS32_ISA_B(off))
+#define MIPS32_BEQ(isa, src, tar, off) (isa ? MMIPS32_BEQ(src, tar, off) : MIPS32_ISA_BEQ(src, tar, off))
+#define MIPS32_BGTZ(isa, reg, off) (isa ? MMIPS32_BGTZ(reg, off) : MIPS32_ISA_BGTZ(reg, off))
+#define MIPS32_BNE(isa, src, tar, off) (isa ? MMIPS32_BNE(src, tar, off) : MIPS32_ISA_BNE(src, tar, off))
+#define MIPS32_CACHE(isa, op, off, base) (isa ? MMIPS32_CACHE(op, off, base) : MIPS32_ISA_CACHE(op, off, base))
+
+#define MIPS32_J(isa, tar) (isa ? MMIPS32_J(tar) : MIPS32_ISA_J(tar))
+#define MIPS32_JR(isa, reg) (isa ? MMIPS32_JR(reg) : MIPS32_ISA_JR(reg))
+#define MIPS32_LB(isa, reg, off, base) (isa ? MMIPS32_LB(reg, off, base) : MIPS32_ISA_LB(reg, off, base))
+#define MIPS32_LBU(isa, reg, off, base) (isa ? MMIPS32_LBU(reg, off, base) : MIPS32_ISA_LBU(reg, off, base))
+#define MIPS32_LHU(isa, reg, off, base) (isa ? MMIPS32_LHU(reg, off, base) : MIPS32_ISA_LHU(reg, off, base))
+#define MIPS32_LW(isa, reg, off, base) (isa ? MMIPS32_LW(reg, off, base) : MIPS32_ISA_LW(reg, off, base))
+#define MIPS32_LUI(isa, reg, val) (isa ? MMIPS32_LUI(reg, val) : MIPS32_ISA_LUI(reg, val))
+
+#define MIPS32_MFC0(isa, gpr, cpr, sel) (isa ? MMIPS32_MFC0(gpr, cpr, sel) : MIPS32_ISA_MFC0(gpr, cpr, sel))
+#define MIPS32_MTC0(isa, gpr, cpr, sel) (isa ? MMIPS32_MTC0(gpr, cpr, sel) : MIPS32_ISA_MTC0(gpr, cpr, sel))
+#define MIPS32_MFLO(isa, reg) (isa ? MMIPS32_MFLO(reg) : MIPS32_ISA_MFLO(reg))
+#define MIPS32_MFHI(isa, reg) (isa ? MMIPS32_MFHI(reg) : MIPS32_ISA_MFHI(reg))
+#define MIPS32_MTLO(isa, reg) (isa ? MMIPS32_MTLO(reg) : MIPS32_ISA_MTLO(reg))
+#define MIPS32_MTHI(isa, reg) (isa ? MMIPS32_MTHI(reg) : MIPS32_ISA_MTHI(reg))
+
+#define MIPS32_MOVN(isa, dst, src, tar) (isa ? MMIPS32_MOVN(dst, src, tar) : MIPS32_ISA_MOVN(dst, src, tar))
+#define MIPS32_ORI(isa, tar, src, val) (isa ? MMIPS32_ORI(tar, src, val) : MIPS32_ISA_ORI(tar, src, val))
+#define MIPS32_RDHWR(isa, tar, dst) (isa ? MMIPS32_RDHWR(tar, dst) : MIPS32_ISA_RDHWR(tar, dst))
+#define MIPS32_SB(isa, reg, off, base) (isa ? MMIPS32_SB(reg, off, base) : MIPS32_ISA_SB(reg, off, base))
+#define MIPS32_SH(isa, reg, off, base) (isa ? MMIPS32_SH(reg, off, base) : MIPS32_ISA_SH(reg, off, base))
+#define MIPS32_SW(isa, reg, off, base) (isa ? MMIPS32_SW(reg, off, base) : MIPS32_ISA_SW(reg, off, base))
+
+#define MIPS32_SLL(isa, dst, src, sa) (isa ? MMIPS32_SLL(dst, src, sa) : MIPS32_ISA_SLL(dst, src, sa))
+#define MIPS32_SLTI(isa, tar, src, val) (isa ? MMIPS32_SLTI(tar, src, val) : MIPS32_ISA_SLTI(tar, src, val))
+#define MIPS32_SLTU(isa, dst, src, tar) (isa ? MMIPS32_SLTU(dst, src, tar) : MIPS32_ISA_SLTU(dst, src, tar))
+#define MIPS32_SRL(isa, reg, src, off) (isa ? MMIPS32_SRL(reg, src, off) : MIPS32_ISA_SRL(reg, src, off))
+
+#define MIPS32_SYNCI(isa, off, base) (isa ? MMIPS32_SYNCI(off, base) : MIPS32_ISA_SYNCI(off, base))
+#define MIPS32_SYNC(isa) (isa ? MMIPS32_SYNC : MIPS32_ISA_SYNC)
+#define MIPS32_XOR(isa, reg, val1, val2) (isa ? MMIPS32_XOR(reg, val1, val2) : MIPS32_ISA_XOR(reg, val1, val2))
+#define MIPS32_XORI(isa, tar, src, val) (isa ? MMIPS32_XORI(tar, src, val) : MIPS32_ISA_XORI(tar, src, val))
+
+#define MIPS32_SYNCI_STEP 0x1
+
+/* ejtag specific instructions */
+#define MIPS32_DRET(isa) (isa ? MMIPS32_DRET : MIPS32_ISA_DRET)
+#define MIPS32_SDBBP(isa) (isa ? MMIPS32_SDBBP : MIPS32_ISA_SDBBP)
+
+#define MIPS16_SDBBP(isa) (isa ? MMIPS16_SDBBP : MIPS16_ISA_SDBBP)
extern const struct command_registration mips32_command_handlers[];
@@ -232,7 +409,7 @@ struct reg_cache *mips32_build_reg_cache(struct target *target);
int mips32_run_algorithm(struct target *target,
int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params,
- uint32_t entry_point, uint32_t exit_point,
+ target_addr_t entry_point, target_addr_t exit_point,
int timeout_ms, void *arch_info);
int mips32_configure_break_unit(struct target *target);
@@ -241,14 +418,16 @@ int mips32_enable_interrupts(struct target *target, int enable);
int mips32_examine(struct target *target);
+int mips32_read_config_regs(struct target *target);
+
int mips32_register_commands(struct command_context *cmd_ctx);
int mips32_get_gdb_reg_list(struct target *target,
struct reg **reg_list[], int *reg_list_size,
enum target_register_class reg_class);
-int mips32_checksum_memory(struct target *target, uint32_t address,
+int mips32_checksum_memory(struct target *target, target_addr_t address,
uint32_t count, uint32_t *checksum);
int mips32_blank_check_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *blank);
+ target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value);
-#endif /*MIPS32_H*/
+#endif /* OPENOCD_TARGET_MIPS32_H */
diff --git a/src/target/mips32_dmaacc.c b/src/target/mips32_dmaacc.c
index c2fea21dd..220ea94f9 100644
--- a/src/target/mips32_dmaacc.c
+++ b/src/target/mips32_dmaacc.c
@@ -18,9 +18,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/mips32_dmaacc.h b/src/target/mips32_dmaacc.h
index 45d5b3614..70fe2a77e 100644
--- a/src/target/mips32_dmaacc.h
+++ b/src/target/mips32_dmaacc.h
@@ -18,13 +18,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef MIPS32_DMAACC_H
-#define MIPS32_DMAACC_H
+#ifndef OPENOCD_TARGET_MIPS32_DMAACC_H
+#define OPENOCD_TARGET_MIPS32_DMAACC_H
#include "mips_ejtag.h"
@@ -40,4 +38,4 @@ int mips32_dmaacc_read_mem(struct mips_ejtag *ejtag_info,
int mips32_dmaacc_write_mem(struct mips_ejtag *ejtag_info,
uint32_t addr, int size, int count, const void *buf);
-#endif
+#endif /* OPENOCD_TARGET_MIPS32_DMAACC_H */
diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index e97626cb2..790c8dc93 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -20,9 +20,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/*
@@ -75,77 +73,61 @@
#include "mips32.h"
#include "mips32_pracc.h"
-struct mips32_pracc_context {
- uint32_t *local_oparam;
- int num_oparam;
- const uint32_t *code;
- int code_len;
- uint32_t stack[32];
- int stack_offset;
- struct mips_ejtag *ejtag_info;
-};
-
-static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl)
+static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info)
{
- uint32_t ejtag_ctrl;
- long long then = timeval_ms();
+ int64_t then = timeval_ms();
/* wait for the PrAcc to become "1" */
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
while (1) {
- ejtag_ctrl = ejtag_info->ejtag_ctrl;
- int retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+ ejtag_info->pa_ctrl = ejtag_info->ejtag_ctrl;
+ int retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_info->pa_ctrl);
if (retval != ERROR_OK)
return retval;
- if (ejtag_ctrl & EJTAG_CTRL_PRACC)
+ if (ejtag_info->pa_ctrl & EJTAG_CTRL_PRACC)
break;
- int timeout = timeval_ms() - then;
+ int64_t timeout = timeval_ms() - then;
if (timeout > 1000) {
LOG_DEBUG("DEBUGMODULE: No memory access in progress!");
return ERROR_JTAG_DEVICE_ERROR;
}
}
- *ctrl = ejtag_ctrl;
return ERROR_OK;
}
/* Shift in control and address for a new processor access, save them in ejtag_info */
static int mips32_pracc_read_ctrl_addr(struct mips_ejtag *ejtag_info)
{
- int retval = wait_for_pracc_rw(ejtag_info, &ejtag_info->pa_ctrl);
+ int retval = wait_for_pracc_rw(ejtag_info);
if (retval != ERROR_OK)
return retval;
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
- ejtag_info->pa_addr = 0;
- retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_info->pa_addr);
- return retval;
+ ejtag_info->pa_addr = 0;
+ return mips_ejtag_drscan_32(ejtag_info, &ejtag_info->pa_addr);
}
/* Finish processor access */
-static int mips32_pracc_finish(struct mips_ejtag *ejtag_info)
+static void mips32_pracc_finish(struct mips_ejtag *ejtag_info)
{
uint32_t ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
mips_ejtag_drscan_32_out(ejtag_info, ctrl);
-
- return jtag_execute_queue();
}
int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info)
{
- uint32_t jt_code = MIPS32_J((0x0FFFFFFF & MIPS32_PRACC_TEXT) >> 2);
- int retval;
-
+ uint32_t jt_code = MIPS32_J(ejtag_info->isa, MIPS32_PRACC_TEXT);
+ pracc_swap16_array(ejtag_info, &jt_code, 1);
/* do 3 0/nops to clean pipeline before a jump to pracc text, NOP in delay slot */
for (int i = 0; i != 5; i++) {
/* Wait for pracc */
- retval = wait_for_pracc_rw(ejtag_info, &ejtag_info->pa_ctrl);
+ int retval = wait_for_pracc_rw(ejtag_info);
if (retval != ERROR_OK)
return retval;
@@ -155,33 +137,33 @@ int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info)
mips_ejtag_drscan_32_out(ejtag_info, data);
/* finish pa */
- retval = mips32_pracc_finish(ejtag_info);
- if (retval != ERROR_OK)
- return retval;
+ mips32_pracc_finish(ejtag_info);
}
- if (ejtag_info->mode != 0) /* done, queued mode won't work with lexra cores */
+ if (ejtag_info->mode != 0) /* async mode support only for MIPS ... */
return ERROR_OK;
- retval = mips32_pracc_read_ctrl_addr(ejtag_info);
- if (retval != ERROR_OK)
- return retval;
-
- if (ejtag_info->pa_addr != MIPS32_PRACC_TEXT) { /* LEXRA/BMIPS ?, shift out another NOP */
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
- mips_ejtag_drscan_32_out(ejtag_info, MIPS32_NOP);
- retval = mips32_pracc_finish(ejtag_info);
+ for (int i = 0; i != 2; i++) {
+ int retval = mips32_pracc_read_ctrl_addr(ejtag_info);
if (retval != ERROR_OK)
return retval;
+
+ if (ejtag_info->pa_addr != MIPS32_PRACC_TEXT) { /* LEXRA/BMIPS ?, shift out another NOP, max 2 */
+ mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
+ mips_ejtag_drscan_32_out(ejtag_info, MIPS32_NOP);
+ mips32_pracc_finish(ejtag_info);
+ } else
+ break;
}
return ERROR_OK;
}
-int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *param_out)
+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;
- int store_pending = 0; /* increases with every store instruction at dmseg, decreases with every store pa */
+ int store_pending = 0; /* increases with every store instr at dmseg, decreases with every store pa */
uint32_t max_store_addr = 0; /* for store pa address testing */
bool restart = 0; /* restarting control */
int restart_count = 0;
@@ -204,12 +186,12 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ct
LOG_DEBUG("restarting code");
}
- retval = mips32_pracc_read_ctrl_addr(ejtag_info); /* update current pa info: control and address */
+ retval = mips32_pracc_read_ctrl_addr(ejtag_info); /* update current pa info: control and address */
if (retval != ERROR_OK)
return retval;
/* Check for read or write access */
- if (ejtag_info->pa_ctrl & EJTAG_CTRL_PRNW) { /* write/store access */
+ if (ejtag_info->pa_ctrl & EJTAG_CTRL_PRNW) { /* write/store access */
/* Check for pending store from a previous store instruction at dmseg */
if (store_pending == 0) {
LOG_DEBUG("unexpected write at address %" PRIx32, ejtag_info->pa_addr);
@@ -220,8 +202,8 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ct
return ERROR_JTAG_DEVICE_ERROR;
} else {
/* check address */
- if (ejtag_info->pa_addr < MIPS32_PRACC_PARAM_OUT || ejtag_info->pa_addr > max_store_addr) {
-
+ if (ejtag_info->pa_addr < MIPS32_PRACC_PARAM_OUT ||
+ ejtag_info->pa_addr > max_store_addr) {
LOG_DEBUG("writing at unexpected address %" PRIx32, ejtag_info->pa_addr);
return ERROR_JTAG_DEVICE_ERROR;
}
@@ -245,7 +227,8 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ct
ejtag_info->pa_addr, MIPS32_PRACC_TEXT + code_count * 4);
/* restart code execution only in some cases */
- if (code_count == 1 && ejtag_info->pa_addr == MIPS32_PRACC_TEXT && restart_count == 0) {
+ if (code_count == 1 && ejtag_info->pa_addr == MIPS32_PRACC_TEXT &&
+ restart_count == 0) {
LOG_DEBUG("restarting, without clean jump");
restart_count++;
code_count = 0;
@@ -254,18 +237,17 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ct
restart = 1;
continue;
}
-
return ERROR_JTAG_DEVICE_ERROR;
}
/* check for store instruction at dmseg */
- uint32_t store_addr = ctx->pracc_list[ctx->max_code + code_count];
+ uint32_t store_addr = ctx->pracc_list[code_count].addr;
if (store_addr != 0) {
if (store_addr > max_store_addr)
max_store_addr = store_addr;
store_pending++;
}
- instr = ctx->pracc_list[code_count++];
+ instr = ctx->pracc_list[code_count++].instr;
if (code_count == ctx->code_count) /* last instruction, start final check */
final_check = 1;
@@ -283,13 +265,14 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ct
}
} else {
if (ejtag_info->pa_addr != (MIPS32_PRACC_TEXT + code_count * 4)) {
- LOG_DEBUG("unexpected read address in final check: %" PRIx32 ", expected: %x",
- ejtag_info->pa_addr, MIPS32_PRACC_TEXT + code_count * 4);
+ LOG_DEBUG("unexpected read address in final check: %"
+ PRIx32 ", expected: %x", ejtag_info->pa_addr,
+ MIPS32_PRACC_TEXT + code_count * 4);
return ERROR_JTAG_DEVICE_ERROR;
}
}
if (!pass) {
- if ((code_count - ctx->code_count) > 1) { /* allow max 2 instruction delay slot */
+ if ((code_count - ctx->code_count) > 1) { /* allow max 2 instr delay slot */
LOG_DEBUG("failed to jump back to pracc text");
return ERROR_JTAG_DEVICE_ERROR;
}
@@ -307,12 +290,10 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ct
mips_ejtag_drscan_32_out(ejtag_info, instr);
}
/* finish processor access, let the processor eat! */
- retval = mips32_pracc_finish(ejtag_info);
- if (retval != ERROR_OK)
- return retval;
+ mips32_pracc_finish(ejtag_info);
- if (instr == MIPS32_DRET) /* after leaving debug mode nothing to do */
- return ERROR_OK;
+ if (final_check && !check_last) /* last instr, don't check, execute and exit */
+ return jtag_execute_queue();
if (store_pending == 0 && pass) { /* store access done, but after passing pracc text */
LOG_DEBUG("warning: store access pass pracc text");
@@ -326,34 +307,63 @@ inline void pracc_queue_init(struct pracc_queue_info *ctx)
ctx->retval = ERROR_OK;
ctx->code_count = 0;
ctx->store_count = 0;
-
- ctx->pracc_list = malloc(2 * ctx->max_code * sizeof(uint32_t));
- if (ctx->pracc_list == NULL) {
- LOG_ERROR("Out of memory");
- ctx->retval = ERROR_FAIL;
- }
+ ctx->max_code = 0;
+ ctx->pracc_list = NULL;
+ ctx->isa = ctx->ejtag_info->isa ? 1 : 0;
}
-inline void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)
+void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)
{
- ctx->pracc_list[ctx->max_code + ctx->code_count] = addr;
- ctx->pracc_list[ctx->code_count++] = instr;
+ if (ctx->retval != ERROR_OK) /* On previous out of memory, return */
+ return;
+ if (ctx->code_count == ctx->max_code) {
+ void *p = realloc(ctx->pracc_list, sizeof(pa_list) * (ctx->max_code + PRACC_BLOCK));
+ if (p) {
+ ctx->max_code += PRACC_BLOCK;
+ ctx->pracc_list = p;
+ } else {
+ ctx->retval = ERROR_FAIL; /* Out of memory */
+ return;
+ }
+ }
+ ctx->pracc_list[ctx->code_count].instr = instr;
+ ctx->pracc_list[ctx->code_count++].addr = addr;
if (addr)
ctx->store_count++;
}
+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 */
+ else if (UPPER16(data) == 0 && optimize)
+ pracc_add(ctx, 0, MIPS32_ORI(ctx->isa, reg_num, 0, LOWER16(data))); /* load only lower */
+ else {
+ pracc_add(ctx, 0, MIPS32_LUI(ctx->isa, reg_num, UPPER16(data))); /* load upper and lower */
+ pracc_add(ctx, 0, MIPS32_ORI(ctx->isa, reg_num, reg_num, LOWER16(data)));
+ }
+}
+
inline void pracc_queue_free(struct pracc_queue_info *ctx)
{
- if (ctx->code_count > ctx->max_code) /* Only for internal check, will be erased */
- LOG_ERROR("Internal error, code count: %d > max code: %d", ctx->code_count, ctx->max_code);
if (ctx->pracc_list != NULL)
free(ctx->pracc_list);
}
-int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *buf)
+int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
+ uint32_t *buf, bool check_last)
{
+ if (ctx->retval != ERROR_OK) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+
+ if (ejtag_info->isa && ejtag_info->endianness)
+ for (int i = 0; i != ctx->code_count; i++)
+ ctx->pracc_list[i].instr = SWAP16(ctx->pracc_list[i].instr);
+
if (ejtag_info->mode == 0)
- return mips32_pracc_exec(ejtag_info, ctx, buf);
+ return mips32_pracc_exec(ejtag_info, ctx, buf, check_last);
union scan_in {
uint8_t scan_96[12];
@@ -376,16 +386,16 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);
int scan_count = 0;
- for (int i = 0; i != 2 * ctx->code_count; i++) {
- uint32_t data = 0;
- if (i & 1u) { /* Check store address from previous instruction, if not the first */
- if (i < 2 || 0 == ctx->pracc_list[ctx->max_code + (i / 2) - 1])
- continue;
- } else
- data = ctx->pracc_list[i / 2];
-
+ for (int i = 0; i != ctx->code_count; i++) {
jtag_add_clocks(num_clocks);
- mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, data, scan_in[scan_count++].scan_96);
+ mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, ctx->pracc_list[i].instr,
+ scan_in[scan_count++].scan_96);
+
+ /* Check store address from previous instruction, if not the first */
+ if (i > 0 && ctx->pracc_list[i - 1].addr) {
+ jtag_add_clocks(num_clocks);
+ mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, 0, scan_in[scan_count++].scan_96);
+ }
}
int retval = jtag_execute_queue(); /* execute queued scans */
@@ -394,24 +404,35 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
uint32_t fetch_addr = MIPS32_PRACC_TEXT; /* start address */
scan_count = 0;
- for (int i = 0; i != 2 * ctx->code_count; i++) { /* verify every pracc access */
- uint32_t store_addr = 0;
- if (i & 1u) { /* Read store addres from previous instruction, if not the first */
- store_addr = ctx->pracc_list[ctx->max_code + (i / 2) - 1];
- if (i < 2 || 0 == store_addr)
- continue;
- }
-
+ for (int i = 0; i != ctx->code_count; i++) { /* verify every pracc access */
+ /* check pracc bit */
ejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32);
+ uint32_t addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);
if (!(ejtag_ctrl & EJTAG_CTRL_PRACC)) {
LOG_ERROR("Error: access not pending count: %d", scan_count);
retval = ERROR_FAIL;
goto exit;
}
+ if (ejtag_ctrl & EJTAG_CTRL_PRNW) {
+ LOG_ERROR("Not a fetch/read access, count: %d", scan_count);
+ retval = ERROR_FAIL;
+ goto exit;
+ }
+ if (addr != fetch_addr) {
+ LOG_ERROR("Fetch addr mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
+ addr, fetch_addr, scan_count);
+ retval = ERROR_FAIL;
+ goto exit;
+ }
+ fetch_addr += 4;
+ scan_count++;
- uint32_t addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);
+ /* check if previous intrucction is a store instruction at dmesg */
+ if (i > 0 && ctx->pracc_list[i - 1].addr) {
+ uint32_t store_addr = ctx->pracc_list[i - 1].addr;
+ ejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32);
+ addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);
- if (store_addr != 0) {
if (!(ejtag_ctrl & EJTAG_CTRL_PRNW)) {
LOG_ERROR("Not a store/write access, count: %d", scan_count);
retval = ERROR_FAIL;
@@ -419,28 +440,14 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
}
if (addr != store_addr) {
LOG_ERROR("Store address mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
- addr, store_addr, scan_count);
+ addr, store_addr, scan_count);
retval = ERROR_FAIL;
goto exit;
}
int buf_index = (addr - MIPS32_PRACC_PARAM_OUT) / 4;
buf[buf_index] = buf_get_u32(scan_in[scan_count].scan_32.data, 0, 32);
-
- } else {
- if (ejtag_ctrl & EJTAG_CTRL_PRNW) {
- LOG_ERROR("Not a fetch/read access, count: %d", scan_count);
- retval = ERROR_FAIL;
- goto exit;
- }
- if (addr != fetch_addr) {
- LOG_ERROR("Fetch addr mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
- addr, fetch_addr, scan_count);
- retval = ERROR_FAIL;
- goto exit;
- }
- fetch_addr += 4;
+ scan_count++;
}
- scan_count++;
}
exit:
free(scan_in);
@@ -449,23 +456,19 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
{
- struct pracc_queue_info ctx = {.max_code = 8};
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
- pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
- pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16((addr + 0x8000)))); /* load $8 with modified upper address */
- pracc_add(&ctx, 0, MIPS32_LW(8, LOWER16(addr), 8)); /* lw $8, LOWER16(addr)($8) */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 8, UPPER16((addr + 0x8000)))); /* load $8 with modified upper addr */
+ pracc_add(&ctx, 0, MIPS32_LW(ctx.isa, 8, LOWER16(addr), 8)); /* lw $8, LOWER16(addr)($8) */
pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,
- MIPS32_SW(8, PRACC_OUT_OFFSET, 15)); /* sw $8,PRACC_OUT_OFFSET($15) */
- pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(ejtag_info->reg8))); /* restore upper 16 of $8 */
- pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 of $8 */
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0)); /* move COP0 DeSave to $15 */
+ MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET, 15)); /* sw $8,PRACC_OUT_OFFSET($15) */
+ pracc_add_li32(&ctx, 8, ejtag_info->reg8, 0); /* restore $8 */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0)); /* move COP0 DeSave to $15 */
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf);
-exit:
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf, 1);
pracc_queue_free(&ctx);
return ctx.retval;
}
@@ -475,12 +478,10 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size
if (count == 1 && size == 4)
return mips32_pracc_read_u32(ejtag_info, addr, (uint32_t *)buf);
- uint32_t *data = NULL;
- struct pracc_queue_info ctx = {.max_code = 256 * 3 + 8 + 1}; /* alloc memory for the worst case */
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
+ uint32_t *data = NULL;
if (size != 4) {
data = malloc(256 * sizeof(uint32_t));
if (data == NULL) {
@@ -496,45 +497,44 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size
while (count) {
ctx.code_count = 0;
ctx.store_count = 0;
+
int this_round_count = (count > 256) ? 256 : count;
uint32_t last_upper_base_addr = UPPER16((addr + 0x8000));
- pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
- pracc_add(&ctx, 0, MIPS32_LUI(9, last_upper_base_addr)); /* load the upper memory address in $9 */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 9, last_upper_base_addr)); /* upper memory addr to $9 */
for (int i = 0; i != this_round_count; i++) { /* Main code loop */
uint32_t upper_base_addr = UPPER16((addr + 0x8000));
- if (last_upper_base_addr != upper_base_addr) { /* if needed, change upper address in $9 */
- pracc_add(&ctx, 0, MIPS32_LUI(9, upper_base_addr));
+ if (last_upper_base_addr != upper_base_addr) { /* if needed, change upper addr in $9 */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 9, upper_base_addr));
last_upper_base_addr = upper_base_addr;
}
- if (size == 4)
- pracc_add(&ctx, 0, MIPS32_LW(8, LOWER16(addr), 9)); /* load from memory to $8 */
+ if (size == 4) /* load from memory to $8 */
+ pracc_add(&ctx, 0, MIPS32_LW(ctx.isa, 8, LOWER16(addr), 9));
else if (size == 2)
- pracc_add(&ctx, 0, MIPS32_LHU(8, LOWER16(addr), 9));
+ pracc_add(&ctx, 0, MIPS32_LHU(ctx.isa, 8, LOWER16(addr), 9));
else
- pracc_add(&ctx, 0, MIPS32_LBU(8, LOWER16(addr), 9));
+ pracc_add(&ctx, 0, MIPS32_LBU(ctx.isa, 8, LOWER16(addr), 9));
- pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + i * 4,
- MIPS32_SW(8, PRACC_OUT_OFFSET + i * 4, 15)); /* store $8 at param out */
+ pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + i * 4, /* store $8 at param out */
+ MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + i * 4, 15));
addr += size;
}
- pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(ejtag_info->reg8))); /* restore upper 16 bits of reg 8 */
- pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of reg 8 */
- pracc_add(&ctx, 0, MIPS32_LUI(9, UPPER16(ejtag_info->reg9))); /* restore upper 16 bits of reg 9 */
- pracc_add(&ctx, 0, MIPS32_ORI(9, 9, LOWER16(ejtag_info->reg9))); /* restore lower 16 bits of reg 9 */
+ pracc_add_li32(&ctx, 8, ejtag_info->reg8, 0); /* restore $8 */
+ pracc_add_li32(&ctx, 9, ejtag_info->reg9, 0); /* restore $9 */
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0)); /* restore $15 from DeSave */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0)); /* restore $15 from DeSave */
if (size == 4) {
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf32);
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf32, 1);
if (ctx.retval != ERROR_OK)
goto exit;
buf32 += this_round_count;
} else {
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, data);
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, data, 1);
if (ctx.retval != ERROR_OK)
goto exit;
@@ -557,68 +557,37 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size
int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_reg, uint32_t cp0_sel)
{
- struct pracc_queue_info ctx = {.max_code = 7};
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
- pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
- pracc_add(&ctx, 0, MIPS32_MFC0(8, 0, 0) | (cp0_reg << 11) | cp0_sel); /* move COP0 [cp0_reg select] to $8 */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, cp0_reg, cp0_sel)); /* move cp0 reg / sel to $8 */
pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,
- MIPS32_SW(8, PRACC_OUT_OFFSET, 15)); /* store $8 to pracc_out */
- pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0)); /* move COP0 DeSave to $15 */
- pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(ejtag_info->reg8))); /* restore upper 16 bits of $8 */
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */
+ MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET, 15)); /* store $8 to pracc_out */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0)); /* restore $15 from DeSave */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 8, UPPER16(ejtag_info->reg8))); /* restore upper 16 bits of $8 */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val);
-exit:
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val, 1);
pracc_queue_free(&ctx);
return ctx.retval;
-
- /**
- * Note that our input parametes cp0_reg and cp0_sel
- * are numbers (not gprs) which make part of mfc0 instruction opcode.
- *
- * These are not fix, but can be different for each mips32_cp0_read() function call,
- * and that is why we must insert them directly into opcode,
- * i.e. we can not pass it on EJTAG microprogram stack (via param_in),
- * and put them into the gprs later from MIPS32_PRACC_STACK
- * because mfc0 do not use gpr as a parameter for the cp0_reg and select part,
- * but plain (immediate) number.
- *
- * MIPS32_MTC0 is implemented via MIPS32_R_INST macro.
- * In order to insert our parameters, we must change rd and funct fields.
- *
- * code[2] |= (cp0_reg << 11) | cp0_sel; change rd and funct of MIPS32_R_INST macro
- **/
}
int mips32_cp0_write(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel)
{
- struct pracc_queue_info ctx = {.max_code = 6};
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
- pracc_add(&ctx, 0, MIPS32_LUI(15, UPPER16(val))); /* Load val to $15 */
- pracc_add(&ctx, 0, MIPS32_ORI(15, 15, LOWER16(val)));
+ pracc_add_li32(&ctx, 15, val, 0); /* Load val to $15 */
- pracc_add(&ctx, 0, MIPS32_MTC0(15, 0, 0) | (cp0_reg << 11) | cp0_sel); /* write cp0 reg / sel */
+ pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, cp0_reg, cp0_sel)); /* write $15 to cp0 reg / sel */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0)); /* restore $15 from DeSave */
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0)); /* move COP0 DeSave to $15 */
-
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
-exit:
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
pracc_queue_free(&ctx);
return ctx.retval;
-
- /**
- * Note that MIPS32_MTC0 macro is implemented via MIPS32_R_INST macro.
- * In order to insert our parameters, we must change rd and funct fields.
- * code[3] |= (cp0_reg << 11) | cp0_sel; change rd and funct fields of MIPS32_R_INST macro
- **/
}
/**
@@ -651,26 +620,25 @@ int mips32_cp0_write(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t cp0_r
static int mips32_pracc_synchronize_cache(struct mips_ejtag *ejtag_info,
uint32_t start_addr, uint32_t end_addr, int cached, int rel)
{
- struct pracc_queue_info ctx = {.max_code = 256 * 2 + 5};
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
+
/** Find cache line size in bytes */
uint32_t clsiz;
if (rel) { /* Release 2 (rel = 1) */
- pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
- pracc_add(&ctx, 0, MIPS32_RDHWR(8, MIPS32_SYNCI_STEP)); /* load synci_step value to $8 */
+ pracc_add(&ctx, 0, MIPS32_RDHWR(ctx.isa, 8, MIPS32_SYNCI_STEP)); /* load synci_step value to $8 */
pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,
- MIPS32_SW(8, PRACC_OUT_OFFSET, 15)); /* store $8 to pracc_out */
+ MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET, 15)); /* store $8 to pracc_out */
- pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(ejtag_info->reg8))); /* restore upper 16 bits of $8 */
- pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0)); /* move COP0 DeSave to $15 */
+ pracc_add_li32(&ctx, 8, ejtag_info->reg8, 0); /* restore $8 */
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, &clsiz);
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0)); /* restore $15 from DeSave */
+
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, &clsiz, 1);
if (ctx.retval != ERROR_OK)
goto exit;
@@ -703,47 +671,50 @@ static int mips32_pracc_synchronize_cache(struct mips_ejtag *ejtag_info,
end_addr |= clsiz - 1;
ctx.code_count = 0;
+ ctx.store_count = 0;
+
int count = 0;
uint32_t last_upper_base_addr = UPPER16((start_addr + 0x8000));
- pracc_add(&ctx, 0, MIPS32_LUI(15, last_upper_base_addr)); /* load upper memory base address to $15 */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, last_upper_base_addr)); /* load upper memory base addr to $15 */
while (start_addr <= end_addr) { /* main loop */
uint32_t upper_base_addr = UPPER16((start_addr + 0x8000));
- if (last_upper_base_addr != upper_base_addr) { /* if needed, change upper address in $15 */
- pracc_add(&ctx, 0, MIPS32_LUI(15, upper_base_addr));
+ if (last_upper_base_addr != upper_base_addr) { /* if needed, change upper addr in $15 */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, upper_base_addr));
last_upper_base_addr = upper_base_addr;
}
- if (rel)
- pracc_add(&ctx, 0, MIPS32_SYNCI(LOWER16(start_addr), 15)); /* synci instruction, offset($15) */
+ if (rel) /* synci instruction, offset($15) */
+ pracc_add(&ctx, 0, MIPS32_SYNCI(ctx.isa, LOWER16(start_addr), 15));
else {
- if (cached == 3)
- pracc_add(&ctx, 0, MIPS32_CACHE(MIPS32_CACHE_D_HIT_WRITEBACK,
- LOWER16(start_addr), 15)); /* cache Hit_Writeback_D, offset($15) */
-
- pracc_add(&ctx, 0, MIPS32_CACHE(MIPS32_CACHE_I_HIT_INVALIDATE,
- LOWER16(start_addr), 15)); /* cache Hit_Invalidate_I, offset($15) */
+ if (cached == 3) /* cache Hit_Writeback_D, offset($15) */
+ pracc_add(&ctx, 0, MIPS32_CACHE(ctx.isa, MIPS32_CACHE_D_HIT_WRITEBACK,
+ LOWER16(start_addr), 15));
+ /* cache Hit_Invalidate_I, offset($15) */
+ pracc_add(&ctx, 0, MIPS32_CACHE(ctx.isa, MIPS32_CACHE_I_HIT_INVALIDATE,
+ LOWER16(start_addr), 15));
}
start_addr += clsiz;
count++;
- if (count == 256 && start_addr <= end_addr) { /* more ?, then execute code list */
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_NOP); /* nop in delay slot */
+ if (count == 256 && start_addr <= end_addr) { /* more ?, then execute code list */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* to start */
+ pracc_add(&ctx, 0, MIPS32_NOP); /* nop in delay slot */
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
if (ctx.retval != ERROR_OK)
goto exit;
- ctx.code_count = 0;
+ ctx.code_count = 0; /* reset counters for another loop */
+ ctx.store_count = 0;
count = 0;
}
}
- pracc_add(&ctx, 0, MIPS32_SYNC);
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0)); /* restore $15 from DeSave*/
+ pracc_add(&ctx, 0, MIPS32_SYNC(ctx.isa));
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0)); /* restore $15 from DeSave*/
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
exit:
pracc_queue_free(&ctx);
return ctx.retval;
@@ -752,10 +723,8 @@ static int mips32_pracc_synchronize_cache(struct mips_ejtag *ejtag_info,
static int mips32_pracc_write_mem_generic(struct mips_ejtag *ejtag_info,
uint32_t addr, int size, int count, const void *buf)
{
- struct pracc_queue_info ctx = {.max_code = 128 * 3 + 5 + 1}; /* alloc memory for the worst case */
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
const uint32_t *buf32 = buf;
const uint16_t *buf16 = buf;
@@ -764,50 +733,43 @@ static int mips32_pracc_write_mem_generic(struct mips_ejtag *ejtag_info,
while (count) {
ctx.code_count = 0;
ctx.store_count = 0;
+
int this_round_count = (count > 128) ? 128 : count;
uint32_t last_upper_base_addr = UPPER16((addr + 0x8000));
-
- pracc_add(&ctx, 0, MIPS32_LUI(15, last_upper_base_addr)); /* load $15 with memory base address */
+ /* load $15 with memory base address */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, last_upper_base_addr));
for (int i = 0; i != this_round_count; i++) {
uint32_t upper_base_addr = UPPER16((addr + 0x8000));
- if (last_upper_base_addr != upper_base_addr) {
- pracc_add(&ctx, 0, MIPS32_LUI(15, upper_base_addr)); /* if needed, change upper address in $15*/
+ if (last_upper_base_addr != upper_base_addr) { /* if needed, change upper address in $15*/
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, upper_base_addr));
last_upper_base_addr = upper_base_addr;
}
- if (size == 4) { /* for word writes check if one half word is 0 and load it accordingly */
- if (LOWER16(*buf32) == 0)
- pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(*buf32))); /* load only upper value */
- else if (UPPER16(*buf32) == 0)
- pracc_add(&ctx, 0, MIPS32_ORI(8, 0, LOWER16(*buf32))); /* load only lower */
- else {
- pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(*buf32))); /* load upper and lower */
- pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(*buf32)));
- }
- pracc_add(&ctx, 0, MIPS32_SW(8, LOWER16(addr), 15)); /* store word to memory */
+ if (size == 4) {
+ pracc_add_li32(&ctx, 8, *buf32, 1); /* load with li32, optimize */
+ pracc_add(&ctx, 0, MIPS32_SW(ctx.isa, 8, LOWER16(addr), 15)); /* store word to mem */
buf32++;
} else if (size == 2) {
- pracc_add(&ctx, 0, MIPS32_ORI(8, 0, *buf16)); /* load lower value */
- pracc_add(&ctx, 0, MIPS32_SH(8, LOWER16(addr), 15)); /* store half word to memory */
+ pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 0, *buf16)); /* load lower value */
+ pracc_add(&ctx, 0, MIPS32_SH(ctx.isa, 8, LOWER16(addr), 15)); /* store half word */
buf16++;
} else {
- pracc_add(&ctx, 0, MIPS32_ORI(8, 0, *buf8)); /* load lower value */
- pracc_add(&ctx, 0, MIPS32_SB(8, LOWER16(addr), 15)); /* store byte to memory */
+ pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 0, *buf8)); /* load lower value */
+ pracc_add(&ctx, 0, MIPS32_SB(ctx.isa, 8, LOWER16(addr), 15)); /* store byte */
buf8++;
}
addr += size;
}
- pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(ejtag_info->reg8))); /* restore upper 16 bits of reg 8 */
- pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of reg 8 */
+ pracc_add_li32(&ctx, 8, ejtag_info->reg8, 0); /* restore $8 */
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0)); /* restore $15 from DeSave */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0)); /* restore $15 from DeSave */
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
if (ctx.retval != ERROR_OK)
goto exit;
count -= this_round_count;
@@ -874,95 +836,77 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int siz
int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
{
- static const uint32_t cp0_write_code[] = {
- MIPS32_MTC0(1, 12, 0), /* move $1 to status */
- MIPS32_MTLO(1), /* move $1 to lo */
- MIPS32_MTHI(1), /* move $1 to hi */
- MIPS32_MTC0(1, 8, 0), /* move $1 to badvaddr */
- MIPS32_MTC0(1, 13, 0), /* move $1 to cause*/
- MIPS32_MTC0(1, 24, 0), /* move $1 to depc (pc) */
- };
-
- struct pracc_queue_info ctx = {.max_code = 37 * 2 + 7 + 1};
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
- /* load registers 2 to 31 with lui and ori instructions, check if some instructions can be saved */
- for (int i = 2; i < 32; i++) {
- if (LOWER16((regs[i])) == 0) /* if lower half word is 0, lui instruction only */
- pracc_add(&ctx, 0, MIPS32_LUI(i, UPPER16((regs[i]))));
- else if (UPPER16((regs[i])) == 0) /* if upper half word is 0, ori with $0 only*/
- pracc_add(&ctx, 0, MIPS32_ORI(i, 0, LOWER16((regs[i]))));
- else { /* default, load with lui and ori instructions */
- pracc_add(&ctx, 0, MIPS32_LUI(i, UPPER16((regs[i]))));
- pracc_add(&ctx, 0, MIPS32_ORI(i, i, LOWER16((regs[i]))));
- }
- }
+ uint32_t cp0_write_code[] = {
+ MIPS32_MTC0(ctx.isa, 1, 12, 0), /* move $1 to status */
+ MIPS32_MTLO(ctx.isa, 1), /* move $1 to lo */
+ MIPS32_MTHI(ctx.isa, 1), /* move $1 to hi */
+ MIPS32_MTC0(ctx.isa, 1, 8, 0), /* move $1 to badvaddr */
+ MIPS32_MTC0(ctx.isa, 1, 13, 0), /* move $1 to cause*/
+ MIPS32_MTC0(ctx.isa, 1, 24, 0), /* move $1 to depc (pc) */
+ };
+
+ /* load registers 2 to 31 with li32, optimize */
+ for (int i = 2; i < 32; i++)
+ pracc_add_li32(&ctx, i, regs[i], 1);
for (int i = 0; i != 6; i++) {
- pracc_add(&ctx, 0, MIPS32_LUI(1, UPPER16((regs[i + 32])))); /* load CPO value in $1, with lui and ori */
- pracc_add(&ctx, 0, MIPS32_ORI(1, 1, LOWER16((regs[i + 32]))));
- pracc_add(&ctx, 0, cp0_write_code[i]); /* write value from $1 to CPO register */
+ pracc_add_li32(&ctx, 1, regs[i + 32], 0); /* load CPO value in $1 */
+ pracc_add(&ctx, 0, cp0_write_code[i]); /* write value from $1 to CPO register */
}
- pracc_add(&ctx, 0, MIPS32_MTC0(15, 31, 0)); /* load $15 in DeSave */
- pracc_add(&ctx, 0, MIPS32_LUI(1, UPPER16((regs[1])))); /* load upper half word in $1 */
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_ORI(1, 1, LOWER16((regs[1])))); /* load lower half word in $1 */
+ pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0)); /* load $15 in DeSave */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 1, UPPER16((regs[1])))); /* load upper half word in $1 */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 1, 1, LOWER16((regs[1])))); /* load lower half word in $1 */
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
ejtag_info->reg8 = regs[8];
ejtag_info->reg9 = regs[9];
-exit:
pracc_queue_free(&ctx);
return ctx.retval;
}
int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
{
- static int cp0_read_code[] = {
- MIPS32_MFC0(8, 12, 0), /* move status to $8 */
- MIPS32_MFLO(8), /* move lo to $8 */
- MIPS32_MFHI(8), /* move hi to $8 */
- MIPS32_MFC0(8, 8, 0), /* move badvaddr to $8 */
- MIPS32_MFC0(8, 13, 0), /* move cause to $8 */
- MIPS32_MFC0(8, 24, 0), /* move depc (pc) to $8 */
- };
-
- struct pracc_queue_info ctx = {.max_code = 49};
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
- pracc_add(&ctx, 0, MIPS32_MTC0(1, 31, 0)); /* move $1 to COP0 DeSave */
- pracc_add(&ctx, 0, MIPS32_LUI(1, PRACC_UPPER_BASE_ADDR)); /* $1 = MIP32_PRACC_BASE_ADDR */
+ uint32_t cp0_read_code[] = {
+ MIPS32_MFC0(ctx.isa, 8, 12, 0), /* move status to $8 */
+ MIPS32_MFLO(ctx.isa, 8), /* move lo to $8 */
+ MIPS32_MFHI(ctx.isa, 8), /* move hi to $8 */
+ MIPS32_MFC0(ctx.isa, 8, 8, 0), /* move badvaddr to $8 */
+ MIPS32_MFC0(ctx.isa, 8, 13, 0), /* move cause to $8 */
+ MIPS32_MFC0(ctx.isa, 8, 24, 0), /* move depc (pc) to $8 */
+ };
+
+ pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 1, 31, 0)); /* move $1 to COP0 DeSave */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 1, PRACC_UPPER_BASE_ADDR)); /* $1 = MIP32_PRACC_BASE_ADDR */
for (int i = 2; i != 32; i++) /* store GPR's 2 to 31 */
pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + (i * 4),
- MIPS32_SW(i, PRACC_OUT_OFFSET + (i * 4), 1));
+ MIPS32_SW(ctx.isa, i, PRACC_OUT_OFFSET + (i * 4), 1));
for (int i = 0; i != 6; i++) {
pracc_add(&ctx, 0, cp0_read_code[i]); /* load COP0 needed registers to $8 */
pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + (i + 32) * 4, /* store $8 at PARAM OUT */
- MIPS32_SW(8, PRACC_OUT_OFFSET + (i + 32) * 4, 1));
+ MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + (i + 32) * 4, 1));
}
- pracc_add(&ctx, 0, MIPS32_MFC0(8, 31, 0)); /* move DeSave to $8, reg1 value */
- pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + 4, /* store reg1 value from $8 to param out */
- MIPS32_SW(8, PRACC_OUT_OFFSET + 4, 1));
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 31, 0)); /* move DeSave to $8, reg1 value */
+ pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + 4, /* store reg1 value from $8 to param out */
+ MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + 4, 1));
- pracc_add(&ctx, 0, MIPS32_MFC0(1, 31, 0)); /* move COP0 DeSave to $1, restore reg1 */
- pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_MTC0(15, 31, 0)); /* load $15 in DeSave */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 1, 31, 0)); /* move COP0 DeSave to $1, restore reg1 */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0)); /* load $15 in DeSave */
- if (ejtag_info->mode == 0)
- ctx.store_count++; /* Needed by legacy code, due to offset from reg0 */
-
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, regs);
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, regs, 1);
ejtag_info->reg8 = regs[8]; /* reg8 is saved but not restored, next called function should restore it */
ejtag_info->reg9 = regs[9];
-exit:
pracc_queue_free(&ctx);
return ctx.retval;
}
@@ -977,70 +921,61 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_area *source,
int write_t, uint32_t addr, int count, uint32_t *buf)
{
+ uint32_t isa = ejtag_info->isa ? 1 : 0;
uint32_t handler_code[] = {
- /* caution when editing, table is modified below */
/* r15 points to the start of this code */
- MIPS32_SW(8, MIPS32_FASTDATA_HANDLER_SIZE - 4, 15),
- MIPS32_SW(9, MIPS32_FASTDATA_HANDLER_SIZE - 8, 15),
- MIPS32_SW(10, MIPS32_FASTDATA_HANDLER_SIZE - 12, 15),
- MIPS32_SW(11, MIPS32_FASTDATA_HANDLER_SIZE - 16, 15),
+ MIPS32_SW(isa, 8, MIPS32_FASTDATA_HANDLER_SIZE - 4, 15),
+ MIPS32_SW(isa, 9, MIPS32_FASTDATA_HANDLER_SIZE - 8, 15),
+ MIPS32_SW(isa, 10, MIPS32_FASTDATA_HANDLER_SIZE - 12, 15),
+ MIPS32_SW(isa, 11, MIPS32_FASTDATA_HANDLER_SIZE - 16, 15),
/* start of fastdata area in t0 */
- MIPS32_LUI(8, UPPER16(MIPS32_PRACC_FASTDATA_AREA)),
- MIPS32_ORI(8, 8, LOWER16(MIPS32_PRACC_FASTDATA_AREA)),
- MIPS32_LW(9, 0, 8), /* start addr in t1 */
- MIPS32_LW(10, 0, 8), /* end addr to t2 */
- /* loop: */
- /* 8 */ MIPS32_LW(11, 0, 0), /* lw t3,[t8 | r9] */
- /* 9 */ MIPS32_SW(11, 0, 0), /* sw t3,[r9 | r8] */
- MIPS32_BNE(10, 9, NEG16(3)), /* bne $t2,t1,loop */
- MIPS32_ADDI(9, 9, 4), /* addi t1,t1,4 */
-
- MIPS32_LW(8, MIPS32_FASTDATA_HANDLER_SIZE - 4, 15),
- MIPS32_LW(9, MIPS32_FASTDATA_HANDLER_SIZE - 8, 15),
- MIPS32_LW(10, MIPS32_FASTDATA_HANDLER_SIZE - 12, 15),
- MIPS32_LW(11, MIPS32_FASTDATA_HANDLER_SIZE - 16, 15),
-
- MIPS32_LUI(15, UPPER16(MIPS32_PRACC_TEXT)),
- MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_TEXT)),
- MIPS32_JR(15), /* jr start */
- MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
+ MIPS32_LUI(isa, 8, UPPER16(MIPS32_PRACC_FASTDATA_AREA)),
+ MIPS32_ORI(isa, 8, 8, LOWER16(MIPS32_PRACC_FASTDATA_AREA)),
+ MIPS32_LW(isa, 9, 0, 8), /* start addr in t1 */
+ MIPS32_LW(isa, 10, 0, 8), /* end addr to t2 */
+ /* loop: */
+ write_t ? MIPS32_LW(isa, 11, 0, 8) : MIPS32_LW(isa, 11, 0, 9), /* from xfer area : from memory */
+ write_t ? MIPS32_SW(isa, 11, 0, 9) : MIPS32_SW(isa, 11, 0, 8), /* to memory : to xfer area */
+
+ MIPS32_BNE(isa, 10, 9, NEG16(3 << isa)), /* bne $t2,t1,loop */
+ MIPS32_ADDI(isa, 9, 9, 4), /* addi t1,t1,4 */
+
+ MIPS32_LW(isa, 8, MIPS32_FASTDATA_HANDLER_SIZE - 4, 15),
+ MIPS32_LW(isa, 9, MIPS32_FASTDATA_HANDLER_SIZE - 8, 15),
+ MIPS32_LW(isa, 10, MIPS32_FASTDATA_HANDLER_SIZE - 12, 15),
+ MIPS32_LW(isa, 11, MIPS32_FASTDATA_HANDLER_SIZE - 16, 15),
+
+ MIPS32_LUI(isa, 15, UPPER16(MIPS32_PRACC_TEXT)),
+ MIPS32_ORI(isa, 15, 15, LOWER16(MIPS32_PRACC_TEXT) | isa), /* isa bit for JR instr */
+ MIPS32_JR(isa, 15), /* jr start */
+ MIPS32_MFC0(isa, 15, 31, 0), /* move COP0 DeSave to $15 */
};
- uint32_t jmp_code[] = {
- /* 0 */ MIPS32_LUI(15, 0), /* addr of working area added below */
- /* 1 */ MIPS32_ORI(15, 15, 0), /* addr of working area added below */
- MIPS32_JR(15), /* jump to ram program */
- MIPS32_NOP,
- };
-
- int retval, i;
- uint32_t val, ejtag_ctrl, address;
-
if (source->size < MIPS32_FASTDATA_HANDLER_SIZE)
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- if (write_t) {
- handler_code[8] = MIPS32_LW(11, 0, 8); /* load data from probe at fastdata area */
- handler_code[9] = MIPS32_SW(11, 0, 9); /* store data to RAM @ r9 */
- } else {
- handler_code[8] = MIPS32_LW(11, 0, 9); /* load data from RAM @ r9 */
- handler_code[9] = MIPS32_SW(11, 0, 8); /* store data to probe at fastdata area */
- }
-
- /* write program into RAM */
+ pracc_swap16_array(ejtag_info, handler_code, ARRAY_SIZE(handler_code));
+ /* write program into RAM */
if (write_t != ejtag_info->fast_access_save) {
mips32_pracc_write_mem(ejtag_info, source->address, 4, ARRAY_SIZE(handler_code), handler_code);
/* save previous operation to speed to any consecutive read/writes */
ejtag_info->fast_access_save = write_t;
}
- LOG_DEBUG("%s using 0x%.8" PRIx32 " for write handler", __func__, source->address);
+ LOG_DEBUG("%s using 0x%.8" TARGET_PRIxADDR " for write handler", __func__, source->address);
+
+ uint32_t jmp_code[] = {
+ MIPS32_LUI(isa, 15, UPPER16(source->address)), /* load addr of jump in $15 */
+ MIPS32_ORI(isa, 15, 15, LOWER16(source->address) | isa), /* isa bit for JR instr */
+ MIPS32_JR(isa, 15), /* jump to ram program */
+ isa ? MIPS32_XORI(isa, 15, 15, 1) : MIPS32_NOP, /* drop isa bit, needed for LW/SW instructions */
+ };
- jmp_code[0] |= UPPER16(source->address);
- jmp_code[1] |= LOWER16(source->address);
+ pracc_swap16_array(ejtag_info, jmp_code, ARRAY_SIZE(jmp_code));
- for (i = 0; i < (int) ARRAY_SIZE(jmp_code); i++) {
- retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
+ /* execute jump code, with no address check */
+ for (unsigned i = 0; i < ARRAY_SIZE(jmp_code); i++) {
+ int retval = wait_for_pracc_rw(ejtag_info);
if (retval != ERROR_OK)
return retval;
@@ -1048,32 +983,24 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
mips_ejtag_drscan_32_out(ejtag_info, jmp_code[i]);
/* Clear the access pending bit (let the processor eat!) */
- ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
- mips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl);
+ mips32_pracc_finish(ejtag_info);
}
- /* wait PrAcc pending bit for FASTDATA write */
- retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
+ /* wait PrAcc pending bit for FASTDATA write, read address */
+ int retval = mips32_pracc_read_ctrl_addr(ejtag_info);
if (retval != ERROR_OK)
return retval;
/* next fetch to dmseg should be in FASTDATA_AREA, check */
- address = 0;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
- retval = mips_ejtag_drscan_32(ejtag_info, &address);
- if (retval != ERROR_OK)
- return retval;
-
- if (address != MIPS32_PRACC_FASTDATA_AREA)
+ if (ejtag_info->pa_addr != MIPS32_PRACC_FASTDATA_AREA)
return ERROR_FAIL;
/* Send the load start address */
- val = addr;
+ uint32_t val = addr;
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
- retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
+ retval = wait_for_pracc_rw(ejtag_info);
if (retval != ERROR_OK)
return retval;
@@ -1086,11 +1013,9 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
if (ejtag_info->mode != 0)
num_clocks = ((uint64_t)(ejtag_info->scan_delay) * jtag_get_speed_khz() + 500000) / 1000000;
- for (i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++) {
jtag_add_clocks(num_clocks);
- retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++);
- if (retval != ERROR_OK)
- return retval;
+ mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++);
}
retval = jtag_execute_queue();
@@ -1099,17 +1024,11 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
return retval;
}
- retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
- if (retval != ERROR_OK)
- return retval;
-
- address = 0;
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
- retval = mips_ejtag_drscan_32(ejtag_info, &address);
+ retval = mips32_pracc_read_ctrl_addr(ejtag_info);
if (retval != ERROR_OK)
return retval;
- if (address != MIPS32_PRACC_TEXT)
+ if (ejtag_info->pa_addr != MIPS32_PRACC_TEXT)
LOG_ERROR("mini program did not return to start");
return retval;
diff --git a/src/target/mips32_pracc.h b/src/target/mips32_pracc.h
index eab5f73ec..888c847c0 100644
--- a/src/target/mips32_pracc.h
+++ b/src/target/mips32_pracc.h
@@ -18,13 +18,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef MIPS32_PRACC_H
-#define MIPS32_PRACC_H
+#ifndef OPENOCD_TARGET_MIPS32_PRACC_H
+#define OPENOCD_TARGET_MIPS32_PRACC_H
#include
#include
@@ -36,26 +34,40 @@
#define MIPS32_PRACC_PARAM_OUT 0xFF202000
#define PRACC_UPPER_BASE_ADDR (MIPS32_PRACC_BASE_ADDR >> 16)
+#define PRACC_MAX_CODE (MIPS32_PRACC_PARAM_OUT - MIPS32_PRACC_TEXT)
+#define PRACC_MAX_INSTRUCTIONS (PRACC_MAX_CODE / 4)
#define PRACC_OUT_OFFSET (MIPS32_PRACC_PARAM_OUT - MIPS32_PRACC_BASE_ADDR)
#define MIPS32_FASTDATA_HANDLER_SIZE 0x80
#define UPPER16(uint32_t) (uint32_t >> 16)
#define LOWER16(uint32_t) (uint32_t & 0xFFFF)
#define NEG16(v) (((~(v)) + 1) & 0xFFFF)
+#define SWAP16(v) ((LOWER16(v) << 16) | (UPPER16(v)))
/*#define NEG18(v) (((~(v)) + 1) & 0x3FFFF)*/
+#define PRACC_BLOCK 128 /* 1 Kbyte */
+
+typedef struct {
+ uint32_t instr;
+ uint32_t addr;
+} pa_list;
+
struct pracc_queue_info {
+ struct mips_ejtag *ejtag_info;
+ unsigned isa;
int retval;
- const int max_code;
int code_count;
int store_count;
- uint32_t *pracc_list; /* Code and store addresses */
+ int max_code; /* max intstructions with currently allocated memory */
+ pa_list *pracc_list; /* Code and store addresses at dmseg */
};
+
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);
+ struct pracc_queue_info *ctx, uint32_t *buf, bool check_last);
int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info,
uint32_t addr, int size, int count, void *buf);
@@ -67,7 +79,8 @@ 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);
+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
@@ -101,4 +114,11 @@ int mips32_cp0_read(struct mips_ejtag *ejtag_info,
int mips32_cp0_write(struct mips_ejtag *ejtag_info,
uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel);
-#endif
+static inline void pracc_swap16_array(struct mips_ejtag *ejtag_info, uint32_t *buf, int count)
+{
+ if (ejtag_info->isa && ejtag_info->endianness)
+ for (int i = 0; i != count; i++)
+ buf[i] = SWAP16(buf[i]);
+}
+
+#endif /* OPENOCD_TARGET_MIPS32_PRACC_H */
diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c
index 2a16193f8..03a09529c 100644
--- a/src/target/mips_ejtag.c
+++ b/src/target/mips_ejtag.c
@@ -17,9 +17,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -30,74 +28,40 @@
#include "mips_ejtag.h"
#include "mips32_dmaacc.h"
-void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, int new_instr)
+void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr)
{
- struct jtag_tap *tap;
+ assert(ejtag_info->tap != NULL);
+ struct jtag_tap *tap = ejtag_info->tap;
- tap = ejtag_info->tap;
- assert(tap != NULL);
+ if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
- if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) {
struct scan_field field;
- uint8_t t[4];
-
field.num_bits = tap->ir_length;
+
+ uint8_t t[4];
field.out_value = t;
buf_set_u32(t, 0, field.num_bits, new_instr);
+
field.in_value = NULL;
jtag_add_ir_scan(tap, &field, TAP_IDLE);
}
}
-int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info, uint32_t *idcode)
+int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info)
{
- struct scan_field field;
- uint8_t r[4];
-
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IDCODE);
- field.num_bits = 32;
- field.out_value = NULL;
- field.in_value = r;
-
- jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
-
- int retval;
- retval = jtag_execute_queue();
- if (retval != ERROR_OK) {
- LOG_ERROR("register read failed");
- return retval;
- }
-
- *idcode = buf_get_u32(field.in_value, 0, 32);
-
- return ERROR_OK;
+ ejtag_info->idcode = 0;
+ return mips_ejtag_drscan_32(ejtag_info, &ejtag_info->idcode);
}
-static int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info, uint32_t *impcode)
+int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info)
{
- struct scan_field field;
- uint8_t r[4];
-
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IMPCODE);
- field.num_bits = 32;
- field.out_value = NULL;
- field.in_value = r;
-
- jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
-
- int retval;
- retval = jtag_execute_queue();
- if (retval != ERROR_OK) {
- LOG_ERROR("register read failed");
- return retval;
- }
-
- *impcode = buf_get_u32(field.in_value, 0, 32);
-
- return ERROR_OK;
+ ejtag_info->impcode = 0;
+ return mips_ejtag_drscan_32(ejtag_info, &ejtag_info->impcode);
}
void mips_ejtag_add_scan_96(struct mips_ejtag *ejtag_info, uint32_t ctrl, uint32_t data, uint8_t *in_scan_buf)
@@ -123,91 +87,73 @@ void mips_ejtag_add_scan_96(struct mips_ejtag *ejtag_info, uint32_t ctrl, uint32
keep_alive();
}
-int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)
+void mips_ejtag_drscan_32_queued(struct mips_ejtag *ejtag_info, uint32_t data_out, uint8_t *data_in)
{
- struct jtag_tap *tap;
- tap = ejtag_info->tap;
- assert(tap != NULL);
+ assert(ejtag_info->tap != NULL);
+ struct jtag_tap *tap = ejtag_info->tap;
struct scan_field field;
- uint8_t t[4], r[4];
- int retval;
-
field.num_bits = 32;
- field.out_value = t;
- buf_set_u32(t, 0, field.num_bits, *data);
- field.in_value = r;
+ uint8_t scan_out[4];
+ field.out_value = scan_out;
+ buf_set_u32(scan_out, 0, field.num_bits, data_out);
+
+ field.in_value = data_in;
jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
- retval = jtag_execute_queue();
+ keep_alive();
+}
+
+int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)
+{
+ uint8_t scan_in[4];
+ mips_ejtag_drscan_32_queued(ejtag_info, *data, scan_in);
+
+ int retval = jtag_execute_queue();
if (retval != ERROR_OK) {
LOG_ERROR("register read failed");
return retval;
}
- *data = buf_get_u32(field.in_value, 0, 32);
-
- keep_alive();
-
+ *data = buf_get_u32(scan_in, 0, 32);
return ERROR_OK;
}
void mips_ejtag_drscan_32_out(struct mips_ejtag *ejtag_info, uint32_t data)
{
- uint8_t t[4];
- struct jtag_tap *tap;
- tap = ejtag_info->tap;
- assert(tap != NULL);
-
- struct scan_field field;
-
- field.num_bits = 32;
- field.out_value = t;
- buf_set_u32(t, 0, field.num_bits, data);
-
- field.in_value = NULL;
-
- jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
+ mips_ejtag_drscan_32_queued(ejtag_info, data, NULL);
}
-int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data)
+int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint8_t *data)
{
- struct jtag_tap *tap;
- tap = ejtag_info->tap;
- assert(tap != NULL);
+ assert(ejtag_info->tap != NULL);
+ struct jtag_tap *tap = ejtag_info->tap;
struct scan_field field;
- uint8_t t[4] = {0, 0, 0, 0}, r[4];
- int retval;
-
field.num_bits = 8;
- field.out_value = t;
- buf_set_u32(t, 0, field.num_bits, *data);
- field.in_value = r;
+
+ field.out_value = data;
+ field.in_value = data;
jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
- retval = jtag_execute_queue();
+ int retval = jtag_execute_queue();
if (retval != ERROR_OK) {
LOG_ERROR("register read failed");
return retval;
}
-
- *data = buf_get_u32(field.in_value, 0, 32);
-
return ERROR_OK;
}
void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)
{
- struct jtag_tap *tap;
- tap = ejtag_info->tap;
- assert(tap != NULL);
+ assert(ejtag_info->tap != NULL);
+ struct jtag_tap *tap = ejtag_info->tap;
struct scan_field field;
-
field.num_bits = 8;
+
field.out_value = &data;
field.in_value = NULL;
@@ -217,23 +163,20 @@ void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)
/* Set (to enable) or clear (to disable stepping) the SSt bit (bit 8) in Cp0 Debug reg (reg 23, sel 0) */
int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
{
- struct pracc_queue_info ctx = {.max_code = 7};
+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
- pracc_add(&ctx, 0, MIPS32_MFC0(8, 23, 0)); /* move COP0 Debug to $8 */
- pracc_add(&ctx, 0, MIPS32_ORI(8, 8, 0x0100)); /* set SSt bit in debug reg */
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 23, 0)); /* move COP0 Debug to $8 */
+ pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, 0x0100)); /* set SSt bit in debug reg */
if (!enable_step)
- pracc_add(&ctx, 0, MIPS32_XORI(8, 8, 0x0100)); /* clear SSt bit in debug reg */
+ pracc_add(&ctx, 0, MIPS32_XORI(ctx.isa, 8, 8, 0x0100)); /* clear SSt bit in debug reg */
- pracc_add(&ctx, 0, MIPS32_MTC0(8, 23, 0)); /* move $8 to COP0 Debug */
- pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(ejtag_info->reg8))); /* restore upper 16 bits of $8 */
- pracc_add(&ctx, 0, MIPS32_B(NEG16((ctx.code_count + 1)))); /* jump to start */
- pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */
+ pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 8, 23, 0)); /* move $8 to COP0 Debug */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 8, UPPER16(ejtag_info->reg8))); /* restore upper 16 bits of $8 */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
-exit:
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
pracc_queue_free(&ctx);
return ctx.retval;
}
@@ -292,11 +235,11 @@ int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info)
int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
{
- uint32_t pracc_list[] = {MIPS32_DRET, 0};
- struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = pracc_list, .code_count = 1, .store_count = 0};
+ pa_list pracc_list = {.instr = MIPS32_DRET(ejtag_info->isa), .addr = 0};
+ struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = &pracc_list, .code_count = 1, .store_count = 0};
/* execute our dret instruction */
- ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 0); /* shift out instr, omit last check */
/* pic32mx workaround, false pending at low core clock */
jtag_add_sleep(1000);
@@ -391,12 +334,11 @@ static void ejtag_main_print_imp(struct mips_ejtag *ejtag_info)
int mips_ejtag_init(struct mips_ejtag *ejtag_info)
{
- int retval;
-
- retval = mips_ejtag_get_impcode(ejtag_info, &ejtag_info->impcode);
- if (retval != ERROR_OK)
+ int retval = mips_ejtag_get_impcode(ejtag_info);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("impcode read failed");
return retval;
- LOG_DEBUG("impcode: 0x%8.8" PRIx32 "", ejtag_info->impcode);
+ }
/* get ejtag version */
ejtag_info->ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
@@ -446,22 +388,22 @@ int mips_ejtag_init(struct mips_ejtag *ejtag_info)
int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data)
{
- struct jtag_tap *tap;
-
- tap = ejtag_info->tap;
- assert(tap != NULL);
+ assert(ejtag_info->tap != NULL);
+ struct jtag_tap *tap = ejtag_info->tap;
struct scan_field fields[2];
- uint8_t spracc = 0;
- uint8_t t[4] = {0, 0, 0, 0};
/* fastdata 1-bit register */
fields[0].num_bits = 1;
+
+ uint8_t spracc = 0;
fields[0].out_value = &spracc;
fields[0].in_value = NULL;
/* processor access data register 32 bit */
fields[1].num_bits = 32;
+
+ uint8_t t[4] = {0, 0, 0, 0};
fields[1].out_value = t;
if (write_t) {
diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h
index 3e0d83101..71f5c1b4b 100644
--- a/src/target/mips_ejtag.h
+++ b/src/target/mips_ejtag.h
@@ -15,13 +15,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef MIPS_EJTAG
-#define MIPS_EJTAG
+#ifndef OPENOCD_TARGET_MIPS_EJTAG_H
+#define OPENOCD_TARGET_MIPS_EJTAG_H
#include
@@ -60,6 +58,7 @@
#define EJTAG_CTRL_DERR (1 << 10)
#define EJTAG_CTRL_DSTRT (1 << 11)
#define EJTAG_CTRL_JTAGBRK (1 << 12)
+#define EJTAG_CTRL_DBGISA (1 << 13)
#define EJTAG_CTRL_SETDEV (1 << 14)
#define EJTAG_CTRL_PROBEN (1 << 15)
#define EJTAG_CTRL_PRRST (1 << 16)
@@ -144,7 +143,7 @@
#define EJTAG_V20_IBC_OFFS 0x4 /* IBC Offset */
#define EJTAG_V20_IBM_OFFS 0x8
#define EJTAG_V20_IBAn_STEP 0x10 /* Offset for next channel */
-#define EJTAG_V20_DBS 0xFF30008
+#define EJTAG_V20_DBS 0xFF300008
#define EJTAG_V20_DBA0 0xFF300200
#define EJTAG_V20_DBC_OFFS 0x4
#define EJTAG_V20_DBM_OFFS 0x8
@@ -184,6 +183,9 @@ struct mips_ejtag {
uint32_t idcode;
uint32_t ejtag_ctrl;
int fast_access_save;
+ uint32_t config_regs; /* number of config registers read */
+ uint32_t config[4]; /* cp0 config to config3 */
+
uint32_t reg8;
uint32_t reg9;
unsigned scan_delay;
@@ -191,6 +193,8 @@ struct mips_ejtag {
uint32_t pa_ctrl;
uint32_t pa_addr;
unsigned int ejtag_version;
+ uint32_t isa;
+ uint32_t endianness;
/* Memory-Mapped Registers. This addresses are not same on different
* EJTAG versions. */
@@ -212,17 +216,16 @@ struct mips_ejtag {
uint32_t ejtag_dba_step_size; /* size of step till next *DBAn register. */
};
-void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info,
- int new_instr);
+void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr);
int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info);
int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info);
-int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info, uint32_t *idcode);
+int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info);
void mips_ejtag_add_scan_96(struct mips_ejtag *ejtag_info,
uint32_t ctrl, uint32_t data, uint8_t *in_scan_buf);
void mips_ejtag_drscan_32_out(struct mips_ejtag *ejtag_info, uint32_t data);
int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data);
void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data);
-int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data);
+int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint8_t *data);
int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data);
int mips_ejtag_init(struct mips_ejtag *ejtag_info);
@@ -234,4 +237,4 @@ static inline void mips_le_to_h_u32(jtag_callback_data_t arg)
*((uint32_t *)arg) = le_to_h_u32(in);
}
-#endif /* MIPS_EJTAG */
+#endif /* OPENOCD_TARGET_MIPS_EJTAG_H */
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 5b740cc45..7d1c06cf0 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -20,9 +20,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -43,10 +41,10 @@ static int mips_m4k_set_breakpoint(struct target *target,
static int mips_m4k_unset_breakpoint(struct target *target,
struct breakpoint *breakpoint);
static int mips_m4k_internal_restore(struct target *target, int current,
- uint32_t address, int handle_breakpoints,
+ target_addr_t address, int handle_breakpoints,
int debug_execution);
static int mips_m4k_halt(struct target *target);
-static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
+static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address,
uint32_t count, const uint8_t *buffer);
static int mips_m4k_examine_debug_reason(struct target *target)
@@ -110,11 +108,14 @@ static int mips_m4k_debug_entry(struct target *target)
/* attempt to find halt reason */
mips_m4k_examine_debug_reason(target);
+ mips32_read_config_regs(target);
+
/* default to mips32 isa, it will be changed below if required */
mips32->isa_mode = MIPS32_ISA_MIPS32;
- if (ejtag_info->impcode & EJTAG_IMP_MIPS16)
- mips32->isa_mode = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1);
+ /* other than mips32 only and isa bit set ? */
+ if (mips32->isa_imp && buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1))
+ mips32->isa_mode = mips32->isa_imp == 2 ? MIPS32_ISA_MIPS16E : MIPS32_ISA_MMIPS32;
LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32),
@@ -197,6 +198,8 @@ static int mips_m4k_poll(struct target *target)
if (retval != ERROR_OK)
return retval;
+ ejtag_info->isa = (ejtag_ctrl & EJTAG_CTRL_DBGISA) ? 1 : 0;
+
/* clear this bit before handling polling
* as after reset registers will read zero */
if (ejtag_ctrl & EJTAG_CTRL_ROCC) {
@@ -302,6 +305,13 @@ static int mips_m4k_assert_reset(struct target *target)
struct mips_m4k_common *mips_m4k = target_to_m4k(target);
struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
+ /* TODO: apply hw reset signal in not examined state */
+ if (!(target_was_examined(target))) {
+ LOG_WARNING("Reset is not asserted because the target is not examined.");
+ LOG_WARNING("Use a reset button or power cycle the target.");
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
+
LOG_DEBUG("target->state: %s",
target_state_name(target));
@@ -424,7 +434,7 @@ static int mips_m4k_restore_smp(struct target *target, uint32_t address, int han
}
static int mips_m4k_internal_restore(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints, int debug_execution)
{
struct mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
@@ -444,12 +454,13 @@ static int mips_m4k_internal_restore(struct target *target, int current,
/* current = 1: continue on current pc, otherwise continue at */
if (!current) {
+ mips_m4k_isa_filter(mips32->isa_imp, &address);
buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
}
- if (ejtag_info->impcode & EJTAG_IMP_MIPS16)
+ if ((mips32->isa_imp > 1) && debug_execution) /* if more than one isa supported */
buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode);
if (!current)
@@ -464,7 +475,8 @@ static int mips_m4k_internal_restore(struct target *target, int current,
/* Single step past breakpoint at current address */
breakpoint = breakpoint_find(target, resume_pc);
if (breakpoint) {
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+ LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT "",
+ breakpoint->address);
mips_m4k_unset_breakpoint(target, breakpoint);
mips_m4k_single_step_core(target);
mips_m4k_set_breakpoint(target, breakpoint);
@@ -495,7 +507,7 @@ static int mips_m4k_internal_restore(struct target *target, int current,
}
static int mips_m4k_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints, int debug_execution)
{
int retval = ERROR_OK;
@@ -522,7 +534,7 @@ static int mips_m4k_resume(struct target *target, int current,
}
static int mips_m4k_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
/* get pointers to arch-specific information */
struct mips32_common *mips32 = target_to_mips32(target);
@@ -536,6 +548,7 @@ static int mips_m4k_step(struct target *target, int current,
/* current = 1: continue on current pc, otherwise continue at */
if (!current) {
+ mips_m4k_isa_filter(mips32->isa_imp, &address);
buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
@@ -618,6 +631,11 @@ static int mips_m4k_set_breakpoint(struct target *target,
comparator_list[bp_num].used = 1;
comparator_list[bp_num].bp_value = breakpoint->address;
+ if (breakpoint->length != 4) /* make sure isa bit set */
+ comparator_list[bp_num].bp_value |= 1;
+ else /* make sure isa bit cleared */
+ comparator_list[bp_num].bp_value &= ~1;
+
/* EJTAG 2.0 uses 30bit IBA. First 2 bits are reserved.
* Warning: there is no IB ASID registers in 2.0.
* Do not set it! :) */
@@ -635,41 +653,77 @@ static int mips_m4k_set_breakpoint(struct target *target,
bp_num, comparator_list[bp_num].bp_value);
} else if (breakpoint->type == BKPT_SOFT) {
LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
- if (breakpoint->length == 4) {
+
+ uint32_t isa_req = breakpoint->length & 1; /* micro mips request bit */
+ uint32_t bplength = breakpoint->length & ~1; /* drop micro mips request bit for length */
+ uint32_t bpaddr = breakpoint->address & ~1; /* drop isa bit from address, if set */
+
+ if (bplength == 4) {
uint32_t verify = 0xffffffff;
+ uint32_t sdbbp32_instr = MIPS32_SDBBP(isa_req);
+ if (ejtag_info->endianness && isa_req)
+ sdbbp32_instr = SWAP16(sdbbp32_instr);
- retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
- breakpoint->orig_instr);
- if (retval != ERROR_OK)
- return retval;
- retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP);
- if (retval != ERROR_OK)
- return retval;
+ if ((breakpoint->address & 3) == 0) { /* word alligned */
- retval = target_read_u32(target, breakpoint->address, &verify);
- if (retval != ERROR_OK)
- return retval;
- if (verify != MIPS32_SDBBP) {
- LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32
- " - check that memory is read/writable", breakpoint->address);
+ retval = target_read_memory(target, bpaddr, bplength, 1, breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(target, bpaddr, sdbbp32_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_u32(target, bpaddr, &verify);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (verify != sdbbp32_instr)
+ verify = 0;
+
+ } else { /* 16 bit aligned */
+ retval = target_read_memory(target, bpaddr, 2, 2, breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ uint8_t sdbbp_buf[4];
+ target_buffer_set_u32(target, sdbbp_buf, sdbbp32_instr);
+
+ retval = target_write_memory(target, bpaddr, 2, 2, sdbbp_buf);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_memory(target, bpaddr, 2, 2, sdbbp_buf);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (target_buffer_get_u32(target, sdbbp_buf) != sdbbp32_instr)
+ verify = 0;
+ }
+
+ if (verify == 0) {
+ LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx64
+ " - check that memory is read/writable", breakpoint->address);
return ERROR_OK;
}
+
} else {
uint16_t verify = 0xffff;
- retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
- breakpoint->orig_instr);
+ retval = target_read_memory(target, bpaddr, bplength, 1, breakpoint->orig_instr);
if (retval != ERROR_OK)
return retval;
- retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP);
+
+ retval = target_write_u16(target, bpaddr, MIPS16_SDBBP(isa_req));
if (retval != ERROR_OK)
return retval;
- retval = target_read_u16(target, breakpoint->address, &verify);
+ retval = target_read_u16(target, bpaddr, &verify);
if (retval != ERROR_OK)
return retval;
- if (verify != MIPS16_SDBBP) {
- LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32
+
+ if (verify != MIPS16_SDBBP(isa_req)) {
+ LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx64
" - check that memory is read/writable", breakpoint->address);
return ERROR_OK;
}
@@ -712,46 +766,58 @@ static int mips_m4k_unset_breakpoint(struct target *target,
} else {
/* restore original instruction (kept in target endianness) */
+ uint32_t isa_req = breakpoint->length & 1;
+ uint32_t bplength = breakpoint->length & ~1;
+ uint8_t current_instr[4];
LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
- if (breakpoint->length == 4) {
- uint32_t current_instr;
-
- /* check that user program has not modified breakpoint instruction */
- retval = target_read_memory(target, breakpoint->address, 4, 1,
- (uint8_t *)¤t_instr);
- if (retval != ERROR_OK)
- return retval;
-
- /**
- * target_read_memory() gets us data in _target_ endianess.
- * If we want to use this data on the host for comparisons with some macros
- * we must first transform it to _host_ endianess using target_buffer_get_u32().
- */
- current_instr = target_buffer_get_u32(target, (uint8_t *)¤t_instr);
-
- if (current_instr == MIPS32_SDBBP) {
- retval = target_write_memory(target, breakpoint->address, 4, 1,
- breakpoint->orig_instr);
+ if (bplength == 4) {
+ uint32_t sdbbp32_instr = MIPS32_SDBBP(isa_req);
+ if (ejtag_info->endianness && isa_req)
+ sdbbp32_instr = SWAP16(sdbbp32_instr);
+
+ if ((breakpoint->address & 3) == 0) { /* 32bit aligned */
+ /* check that user program has not modified breakpoint instruction */
+ retval = target_read_memory(target, breakpoint->address, 4, 1, current_instr);
+ if (retval != ERROR_OK)
+ return retval;
+ /**
+ * target_read_memory() gets us data in _target_ endianess.
+ * If we want to use this data on the host for comparisons with some macros
+ * we must first transform it to _host_ endianess using target_buffer_get_u16().
+ */
+ if (sdbbp32_instr == target_buffer_get_u32(target, current_instr)) {
+ retval = target_write_memory(target, breakpoint->address, 4, 1,
+ breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+ } else { /* 16bit alligned */
+ retval = target_read_memory(target, breakpoint->address, 2, 2, current_instr);
if (retval != ERROR_OK)
return retval;
+
+ if (sdbbp32_instr == target_buffer_get_u32(target, current_instr)) {
+ retval = target_write_memory(target, breakpoint->address, 2, 2,
+ breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+ }
}
} else {
- uint16_t current_instr;
-
/* check that user program has not modified breakpoint instruction */
- retval = target_read_memory(target, breakpoint->address, 2, 1,
- (uint8_t *)¤t_instr);
+ retval = target_read_memory(target, breakpoint->address, 2, 1, current_instr);
if (retval != ERROR_OK)
return retval;
- current_instr = target_buffer_get_u16(target, (uint8_t *)¤t_instr);
- if (current_instr == MIPS16_SDBBP) {
+
+ if (target_buffer_get_u16(target, current_instr) == MIPS16_SDBBP(isa_req)) {
retval = target_write_memory(target, breakpoint->address, 2, 1,
- breakpoint->orig_instr);
+ breakpoint->orig_instr);
if (retval != ERROR_OK)
return retval;
}
}
}
+
breakpoint->set = 0;
return ERROR_OK;
@@ -761,6 +827,12 @@ static int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *bre
{
struct mips32_common *mips32 = target_to_mips32(target);
+ if ((breakpoint->length > 5 || breakpoint->length < 2) || /* out of range */
+ (breakpoint->length == 4 && (breakpoint->address & 2)) || /* mips32 unaligned */
+ (mips32->isa_imp == MIPS32_ONLY && breakpoint->length != 4) || /* misp32 specific */
+ ((mips32->isa_imp & 1) != (breakpoint->length & 1))) /* isa not implemented */
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+
if (breakpoint->type == BKPT_HARD) {
if (mips32->num_inst_bpoints_avail < 1) {
LOG_INFO("no hardware breakpoint available");
@@ -944,13 +1016,13 @@ static void mips_m4k_enable_watchpoints(struct target *target)
}
}
-static int mips_m4k_read_memory(struct target *target, uint32_t address,
+static int mips_m4k_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
address, size, count);
if (target->state != TARGET_HALTED) {
@@ -1003,13 +1075,13 @@ static int mips_m4k_read_memory(struct target *target, uint32_t address,
return retval;
}
-static int mips_m4k_write_memory(struct target *target, uint32_t address,
+static int mips_m4k_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
address, size, count);
if (target->state != TARGET_HALTED) {
@@ -1102,39 +1174,33 @@ static int mips_m4k_target_create(struct target *target, Jim_Interp *interp)
static int mips_m4k_examine(struct target *target)
{
- int retval;
struct mips_m4k_common *mips_m4k = target_to_m4k(target);
struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
- uint32_t idcode = 0;
if (!target_was_examined(target)) {
- retval = mips_ejtag_get_idcode(ejtag_info, &idcode);
- if (retval != ERROR_OK)
+ int retval = mips_ejtag_get_idcode(ejtag_info);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("idcode read failed");
return retval;
- ejtag_info->idcode = idcode;
-
- if (((idcode >> 1) & 0x7FF) == 0x29) {
+ }
+ if (((ejtag_info->idcode >> 1) & 0x7FF) == 0x29) {
/* we are using a pic32mx so select ejtag port
* as it is not selected by default */
mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
- LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
+ LOG_DEBUG("PIC32 Detected - using EJTAG Interface");
mips_m4k->is_pic32mx = true;
}
}
/* init rest of ejtag interface */
- retval = mips_ejtag_init(ejtag_info);
+ int retval = mips_ejtag_init(ejtag_info);
if (retval != ERROR_OK)
return retval;
- retval = mips32_examine(target);
- if (retval != ERROR_OK)
- return retval;
-
- return ERROR_OK;
+ return mips32_examine(target);
}
-static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
+static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address,
uint32_t count, const uint8_t *buffer)
{
struct mips32_common *mips32 = target_to_mips32(target);
@@ -1143,7 +1209,8 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
int retval;
int write_t = 1;
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count);
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", count: 0x%8.8" PRIx32 "",
+ address, count);
/* check alignment */
if (address & 0x3u)
@@ -1170,8 +1237,8 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
if (address <= fast_data_area->address + fast_data_area->size &&
fast_data_area->address <= address + count) {
- LOG_ERROR("fast_data (0x%8.8" PRIx32 ") is within write area "
- "(0x%8.8" PRIx32 "-0x%8.8" PRIx32 ").",
+ LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area "
+ "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").",
fast_data_area->address, address, address + count);
LOG_ERROR("Change work-area-phys or load_image address!");
return ERROR_FAIL;
@@ -1334,7 +1401,7 @@ COMMAND_HANDLER(mips_m4k_handle_scan_delay_command)
return ERROR_COMMAND_SYNTAX_ERROR;
command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay);
- if (ejtag_info->scan_delay >= 20000000) {
+ if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {
ejtag_info->mode = 0;
command_print(CMD_CTX, "running in legacy mode");
} else {
diff --git a/src/target/mips_m4k.h b/src/target/mips_m4k.h
index de990599c..ea09ae527 100644
--- a/src/target/mips_m4k.h
+++ b/src/target/mips_m4k.h
@@ -18,13 +18,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef MIPS_M4K_H
-#define MIPS_M4K_H
+#ifndef OPENOCD_TARGET_MIPS_M4K_H
+#define OPENOCD_TARGET_MIPS_M4K_H
struct target;
@@ -43,6 +41,17 @@ target_to_m4k(struct target *target)
struct mips_m4k_common, mips32);
}
+static inline void mips_m4k_isa_filter(enum mips32_isa_imp isa_imp, target_addr_t *addr)
+{
+ if (isa_imp <= 1) { /* if only one isa implemented */
+ target_addr_t address = (*addr & ~1) | isa_imp;
+
+ if (address != *addr) {
+ LOG_USER("Warning: isa bit changed due to isa not implemented");
+ *addr = address;
+ }
+ }
+}
extern const struct command_registration mips_m4k_command_handlers[];
-#endif /*MIPS_M4K_H*/
+#endif /* OPENOCD_TARGET_MIPS_M4K_H */
diff --git a/src/target/nds32.c b/src/target/nds32.c
index b6c5f6122..e4bb17f9d 100644
--- a/src/target/nds32.c
+++ b/src/target/nds32.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -825,7 +823,7 @@ int nds32_read_memory(struct target *target, uint32_t address,
return aice_read_mem_unit(aice, address, size, count, buffer);
}
-int nds32_read_phys_memory(struct target *target, uint32_t address,
+int nds32_read_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct aice_port_s *aice = target_to_aice(target);
@@ -934,7 +932,7 @@ int nds32_write_memory(struct target *target, uint32_t address,
return aice_write_mem_unit(aice, address, size, count, buffer);
}
-int nds32_write_phys_memory(struct target *target, uint32_t address,
+int nds32_write_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct aice_port_s *aice = target_to_aice(target);
@@ -1676,7 +1674,7 @@ int nds32_init_arch_info(struct target *target, struct nds32 *nds32)
return ERROR_OK;
}
-int nds32_virtual_to_physical(struct target *target, uint32_t address, uint32_t *physical)
+int nds32_virtual_to_physical(struct target *target, target_addr_t address, target_addr_t *physical)
{
struct nds32 *nds32 = target_to_nds32(target);
@@ -1694,7 +1692,7 @@ int nds32_virtual_to_physical(struct target *target, uint32_t address, uint32_t
return ERROR_FAIL;
}
-int nds32_cache_sync(struct target *target, uint32_t address, uint32_t length)
+int nds32_cache_sync(struct target *target, target_addr_t address, uint32_t length)
{
struct aice_port_s *aice = target_to_aice(target);
struct nds32 *nds32 = target_to_nds32(target);
@@ -1740,7 +1738,7 @@ int nds32_cache_sync(struct target *target, uint32_t address, uint32_t length)
/* Because PSW.IT is turned off under debug exception, address MUST
* be physical address. L1I_VA_INVALIDATE uses PSW.IT to decide
* address translation or not. */
- uint32_t physical_addr;
+ target_addr_t physical_addr;
if (ERROR_FAIL == target->type->virt2phys(target, cur_address,
&physical_addr))
return ERROR_FAIL;
@@ -1766,7 +1764,7 @@ uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address)
}
int nds32_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
LOG_DEBUG("target->state: %s",
target_state_name(target));
@@ -1780,7 +1778,7 @@ int nds32_step(struct target *target, int current,
address = nds32_nextpc(nds32, current, address);
- LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : "");
+ LOG_DEBUG("STEP PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
/** set DSSIM */
uint32_t ir14_value;
@@ -2122,9 +2120,9 @@ int nds32_poll(struct target *target)
}
int nds32_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints, int debug_execution)
{
- LOG_DEBUG("current %d address %08" PRIx32
+ LOG_DEBUG("current %d address %08" TARGET_PRIxADDR
" handle_breakpoints %d"
" debug_execution %d",
current, address, handle_breakpoints, debug_execution);
@@ -2138,7 +2136,7 @@ int nds32_resume(struct target *target, int current,
address = nds32_nextpc(nds32, current, address);
- LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : "");
+ LOG_DEBUG("RESUME PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
if (!debug_execution)
target_free_all_working_areas(target);
@@ -2199,6 +2197,13 @@ int nds32_assert_reset(struct target *target)
struct aice_port_s *aice = target_to_aice(target);
struct nds32_cpu_version *cpu_version = &(nds32->cpu_version);
+ /* TODO: apply hw reset signal in not examined state */
+ if (!(target_was_examined(target))) {
+ LOG_WARNING("Reset is not asserted because the target is not examined.");
+ LOG_WARNING("Use a reset button or power cycle the target.");
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
+
if (target->reset_halt) {
if ((nds32->soft_reset_halt)
|| (nds32->edm.version < 0x51)
diff --git a/src/target/nds32.h b/src/target/nds32.h
index e4161e93b..141dbf4cb 100644
--- a/src/target/nds32.h
+++ b/src/target/nds32.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_H__
-#define __NDS32_H__
+#ifndef OPENOCD_TARGET_NDS32_H
+#define OPENOCD_TARGET_NDS32_H
#include
#include "target.h"
@@ -402,23 +400,23 @@ extern int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *
extern int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value);
extern int nds32_edm_config(struct nds32 *nds32);
-extern int nds32_cache_sync(struct target *target, uint32_t address, uint32_t length);
+extern int nds32_cache_sync(struct target *target, target_addr_t address, uint32_t length);
extern int nds32_mmu(struct target *target, int *enabled);
-extern int nds32_virtual_to_physical(struct target *target, uint32_t address,
- uint32_t *physical);
-extern int nds32_read_phys_memory(struct target *target, uint32_t address,
+extern int nds32_virtual_to_physical(struct target *target, target_addr_t address,
+ target_addr_t *physical);
+extern int nds32_read_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer);
-extern int nds32_write_phys_memory(struct target *target, uint32_t address,
+extern int nds32_write_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
extern uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address);
extern int nds32_examine_debug_reason(struct nds32 *nds32);
extern int nds32_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints);
+ target_addr_t address, int handle_breakpoints);
extern int nds32_target_state(struct nds32 *nds32, enum target_state *state);
extern int nds32_halt(struct target *target);
extern int nds32_poll(struct target *target);
extern int nds32_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution);
+ target_addr_t address, int handle_breakpoints, int debug_execution);
extern int nds32_assert_reset(struct target *target);
extern int nds32_init(struct nds32 *nds32);
extern int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info);
@@ -456,4 +454,4 @@ static inline bool nds32_reach_max_interrupt_level(struct nds32 *nds32)
return nds32->max_interrupt_level == nds32->current_interrupt_level;
}
-#endif /* __NDS32_H__ */
+#endif /* OPENOCD_TARGET_NDS32_H */
diff --git a/src/target/nds32_aice.c b/src/target/nds32_aice.c
index cfb6d86c8..e494a3e1c 100644
--- a/src/target/nds32_aice.c
+++ b/src/target/nds32_aice.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -44,8 +42,8 @@ int aice_write_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t val)
return aice->port->api->write_reg_64(aice->coreid, num, val);
}
-int aice_read_tlb(struct aice_port_s *aice, uint32_t virtual_address,
- uint32_t *physical_address)
+int aice_read_tlb(struct aice_port_s *aice, target_addr_t virtual_address,
+ target_addr_t *physical_address)
{
if (aice->port->api->read_tlb == NULL) {
LOG_WARNING("Not implemented: %s", __func__);
diff --git a/src/target/nds32_aice.h b/src/target/nds32_aice.h
index d53564330..5ea3b1611 100644
--- a/src/target/nds32_aice.h
+++ b/src/target/nds32_aice.h
@@ -13,19 +13,18 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_AICE_H__
-#define __NDS32_AICE_H__
+
+#ifndef OPENOCD_TARGET_NDS32_AICE_H
+#define OPENOCD_TARGET_NDS32_AICE_H
#include
int aice_read_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t *val);
int aice_write_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t val);
-int aice_read_tlb(struct aice_port_s *aice, uint32_t virtual_address,
- uint32_t *physical_address);
+int aice_read_tlb(struct aice_port_s *aice, target_addr_t virtual_address,
+ target_addr_t *physical_address);
int aice_cache_ctl(struct aice_port_s *aice, uint32_t subtype, uint32_t address);
int aice_set_retry_times(struct aice_port_s *aice, uint32_t a_retry_times);
int aice_program_edm(struct aice_port_s *aice, char *command_sequence);
@@ -159,4 +158,4 @@ static inline int aice_set_data_endian(struct aice_port_s *aice,
return aice->port->api->set_data_endian(aice->coreid, target_data_endian);
}
-#endif
+#endif /* OPENOCD_TARGET_NDS32_AICE_H */
diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c
index faf9e0aef..edb4872e4 100644
--- a/src/target/nds32_cmd.c
+++ b/src/target/nds32_cmd.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -846,7 +844,7 @@ static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *
}
int e;
- char *edm_sr_name;
+ const char *edm_sr_name;
int edm_sr_name_len;
e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len);
if (e != JIM_OK)
@@ -892,7 +890,7 @@ static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const
}
int e;
- char *edm_sr_name;
+ const char *edm_sr_name;
int edm_sr_name_len;
e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len);
if (e != JIM_OK)
diff --git a/src/target/nds32_cmd.h b/src/target/nds32_cmd.h
index 44d361e55..543ba54c6 100644
--- a/src/target/nds32_cmd.h
+++ b/src/target/nds32_cmd.h
@@ -13,15 +13,14 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_CMD_H__
-#define __NDS32_CMD_H__
+#ifndef OPENOCD_TARGET_NDS32_CMD_H
+#define OPENOCD_TARGET_NDS32_CMD_H
+
#include
extern const struct command_registration nds32_command_handlers[];
-#endif /* __NDS32_CMD_H__ */
+#endif /* OPENOCD_TARGET_NDS32_CMD_H */
diff --git a/src/target/nds32_disassembler.c b/src/target/nds32_disassembler.c
index 8565f855f..f27aba2cc 100644
--- a/src/target/nds32_disassembler.c
+++ b/src/target/nds32_disassembler.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/nds32_disassembler.h b/src/target/nds32_disassembler.h
index ac0222e66..9117cbb08 100644
--- a/src/target/nds32_disassembler.h
+++ b/src/target/nds32_disassembler.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_DISASSEMBLER_H__
-#define __NDS32_DISASSEMBLER_H__
+#ifndef OPENOCD_TARGET_NDS32_DISASSEMBLER_H
+#define OPENOCD_TARGET_NDS32_DISASSEMBLER_H
#include
@@ -55,4 +53,4 @@ int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value);
int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address,
struct nds32_instruction *instruction);
-#endif /* __NDS32_DISASSEMBLER_H__ */
+#endif /* OPENOCD_TARGET_NDS32_DISASSEMBLER_H */
diff --git a/src/target/nds32_edm.h b/src/target/nds32_edm.h
index 1eab7b007..1dec190f1 100644
--- a/src/target/nds32_edm.h
+++ b/src/target/nds32_edm.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_EDM_H__
-#define __NDS32_EDM_H__
+
+#ifndef OPENOCD_TARGET_NDS32_EDM_H
+#define OPENOCD_TARGET_NDS32_EDM_H
/**
* @file
@@ -113,4 +112,4 @@ enum nds_memory_select {
#define NDS_EDMSW_WDV (1 << 0)
#define NDS_EDMSW_RDV (1 << 1)
-#endif /* __NDS32_EDM_H__ */
+#endif /* OPENOCD_TARGET_NDS32_EDM_H */
diff --git a/src/target/nds32_insn.h b/src/target/nds32_insn.h
index 08d3c5ca9..eb6664517 100644
--- a/src/target/nds32_insn.h
+++ b/src/target/nds32_insn.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_INSN_H__
-#define __NDS32_INSN_H__
+#ifndef OPENOCD_TARGET_NDS32_INSN_H
+#define OPENOCD_TARGET_NDS32_INSN_H
#define NOP (0x40000009)
#define DSB (0x64000008)
@@ -77,5 +75,4 @@
extern const int NDS32_BREAK_16;
extern const int NDS32_BREAK_32;
-
-#endif /* __NDS32_INSN_H__ */
+#endif /* OPENOCD_TARGET_NDS32_INSN_H */
diff --git a/src/target/nds32_reg.c b/src/target/nds32_reg.c
index f82ffbfc4..7cefcb1a2 100644
--- a/src/target/nds32_reg.c
+++ b/src/target/nds32_reg.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/target/nds32_reg.h b/src/target/nds32_reg.h
index 1c61b6164..8808cd244 100644
--- a/src/target/nds32_reg.h
+++ b/src/target/nds32_reg.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_REG_H__
-#define __NDS32_REG_H__
+
+#ifndef OPENOCD_TARGET_NDS32_REG_H
+#define OPENOCD_TARGET_NDS32_REG_H
#define SRIDX(a, b, c) ((a << 7) | (b << 3) | c)
#define NDS32_REGISTER_DISABLE (0x0)
@@ -323,4 +322,4 @@ const char *nds32_reg_simple_name(uint32_t number);
const char *nds32_reg_symbolic_name(uint32_t number);
bool nds32_reg_exception(uint32_t number, uint32_t value);
-#endif
+#endif /* OPENOCD_TARGET_NDS32_REG_H */
diff --git a/src/target/nds32_tlb.c b/src/target/nds32_tlb.c
index 58322cf1e..c4bce1a6a 100644
--- a/src/target/nds32_tlb.c
+++ b/src/target/nds32_tlb.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -24,8 +22,8 @@
#include "nds32_aice.h"
#include "nds32_tlb.h"
-int nds32_probe_tlb(struct nds32 *nds32, const uint32_t virtual_address,
- uint32_t *physical_address)
+int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address,
+ target_addr_t *physical_address)
{
struct target *target = nds32->target;
struct aice_port_s *aice = target_to_aice(target);
@@ -40,8 +38,8 @@ struct page_table_walker_info_s page_table_info[PAGE_SIZE_NUM] = {
{0xFF000000, 22, 0x00FFE000, 11, 0x00001FFF, 0xFFFFF000, 0xFFFFE000, 0xFFFFE000},
};
-int nds32_walk_page_table(struct nds32 *nds32, const uint32_t virtual_address,
- uint32_t *physical_address)
+int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address,
+ target_addr_t *physical_address)
{
struct target *target = nds32->target;
uint32_t value_mr1;
diff --git a/src/target/nds32_tlb.h b/src/target/nds32_tlb.h
index 59e115730..62512c111 100644
--- a/src/target/nds32_tlb.h
+++ b/src/target/nds32_tlb.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_TLB_H__
-#define __NDS32_TLB_H__
+
+#ifndef OPENOCD_TARGET_NDS32_TLB_H
+#define OPENOCD_TARGET_NDS32_TLB_H
#include "nds32.h"
@@ -40,9 +39,9 @@ struct page_table_walker_info_s {
uint32_t ppn_mask;
};
-extern int nds32_probe_tlb(struct nds32 *nds32, const uint32_t virtual_address,
- uint32_t *physical_address);
-extern int nds32_walk_page_table(struct nds32 *nds32, const uint32_t virtual_address,
- uint32_t *physical_address);
+extern int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address,
+ target_addr_t *physical_address);
+extern int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address,
+ target_addr_t *physical_address);
-#endif
+#endif /* OPENOCD_TARGET_NDS32_TLB_H */
diff --git a/src/target/nds32_v2.c b/src/target/nds32_v2.c
index ac2aad0b8..29489a034 100644
--- a/src/target/nds32_v2.c
+++ b/src/target/nds32_v2.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -114,7 +112,7 @@ static int nds32_v2_activate_hardware_breakpoint(struct target *target)
/* enable breakpoint (physical address) */
aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA);
- LOG_DEBUG("Add hardware BP %" PRId32 " at %08" PRIx32, hbr_index,
+ LOG_DEBUG("Add hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
bp->address);
hbr_index++;
@@ -141,7 +139,7 @@ static int nds32_v2_deactivate_hardware_breakpoint(struct target *target)
else
return ERROR_FAIL;
- LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" PRIx32, hbr_index,
+ LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
bp->address);
hbr_index++;
@@ -186,7 +184,7 @@ static int nds32_v2_activate_hardware_watchpoint(struct target *target)
/* set value */
aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0);
- LOG_DEBUG("Add hardware wathcpoint %" PRId32 " at %08" PRIx32 " mask %08" PRIx32, wp_num,
+ LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32, wp_num,
wp->address, wp->mask);
}
@@ -206,7 +204,7 @@ static int nds32_v2_deactivate_hardware_watchpoint(struct target *target)
/* disable watchpoint */
aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0);
- LOG_DEBUG("Remove hardware wathcpoint %" PRId32 " at %08" PRIx32 " mask %08" PRIx32,
+ LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32,
wp_num, wp->address, wp->mask);
}
@@ -407,7 +405,7 @@ static int nds32_v2_deassert_reset(struct target *target)
}
static int nds32_v2_checksum_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *checksum)
+ target_addr_t address, uint32_t count, uint32_t *checksum)
{
LOG_WARNING("Not implemented: %s", __func__);
@@ -563,8 +561,8 @@ static int nds32_v2_run_algorithm(struct target *target,
struct mem_param *mem_params,
int num_reg_params,
struct reg_param *reg_params,
- uint32_t entry_point,
- uint32_t exit_point,
+ target_addr_t entry_point,
+ target_addr_t exit_point,
int timeout_ms,
void *arch_info)
{
@@ -637,11 +635,11 @@ static int nds32_v2_examine(struct target *target)
return ERROR_OK;
}
-static int nds32_v2_translate_address(struct target *target, uint32_t *address)
+static int nds32_v2_translate_address(struct target *target, target_addr_t *address)
{
struct nds32 *nds32 = target_to_nds32(target);
struct nds32_memory *memory = &(nds32->memory);
- uint32_t physical_address;
+ target_addr_t physical_address;
/* Following conditions need to do address translation
* 1. BUS mode
@@ -658,7 +656,7 @@ static int nds32_v2_translate_address(struct target *target, uint32_t *address)
return ERROR_OK;
}
-static int nds32_v2_read_buffer(struct target *target, uint32_t address,
+static int nds32_v2_read_buffer(struct target *target, target_addr_t address,
uint32_t size, uint8_t *buffer)
{
struct nds32 *nds32 = target_to_nds32(target);
@@ -678,7 +676,7 @@ static int nds32_v2_read_buffer(struct target *target, uint32_t address,
return nds32_read_buffer(target, address, size, buffer);
}
-static int nds32_v2_write_buffer(struct target *target, uint32_t address,
+static int nds32_v2_write_buffer(struct target *target, target_addr_t address,
uint32_t size, const uint8_t *buffer)
{
struct nds32 *nds32 = target_to_nds32(target);
@@ -698,7 +696,7 @@ static int nds32_v2_write_buffer(struct target *target, uint32_t address,
return nds32_write_buffer(target, address, size, buffer);
}
-static int nds32_v2_read_memory(struct target *target, uint32_t address,
+static int nds32_v2_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct nds32 *nds32 = target_to_nds32(target);
@@ -718,7 +716,7 @@ static int nds32_v2_read_memory(struct target *target, uint32_t address,
return nds32_read_memory(target, address, size, count, buffer);
}
-static int nds32_v2_write_memory(struct target *target, uint32_t address,
+static int nds32_v2_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct nds32 *nds32 = target_to_nds32(target);
diff --git a/src/target/nds32_v2.h b/src/target/nds32_v2.h
index b39805578..dcc08c29e 100644
--- a/src/target/nds32_v2.h
+++ b/src/target/nds32_v2.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_V2_H__
-#define __NDS32_V2_H__
+
+#ifndef OPENOCD_TARGET_NDS32_V2_H
+#define OPENOCD_TARGET_NDS32_V2_H
#include "nds32.h"
@@ -40,5 +39,4 @@ static inline struct nds32_v2_common *target_to_nds32_v2(struct target *target)
return container_of(target->arch_info, struct nds32_v2_common, nds32);
}
-
-#endif /* __NDS32_V2_H__ */
+#endif /* OPENOCD_TARGET_NDS32_V2_H */
diff --git a/src/target/nds32_v3.c b/src/target/nds32_v3.c
index 224665010..e5d146bb6 100644
--- a/src/target/nds32_v3.c
+++ b/src/target/nds32_v3.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -55,7 +53,7 @@ static int nds32_v3_activate_hardware_breakpoint(struct target *target)
/* enable breakpoint (physical address) */
aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA);
- LOG_DEBUG("Add hardware BP %" PRId32 " at %08" PRIx32, hbr_index,
+ LOG_DEBUG("Add hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
bp->address);
} else {
return ERROR_FAIL;
@@ -83,7 +81,7 @@ static int nds32_v3_deactivate_hardware_breakpoint(struct target *target)
return ERROR_FAIL;
}
- LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" PRIx32, hbr_index,
+ LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
bp->address);
}
@@ -130,7 +128,7 @@ static int nds32_v3_activate_hardware_watchpoint(struct target *target)
/* set value */
aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0);
- LOG_DEBUG("Add hardware wathcpoint %" PRId32 " at %08" PRIx32 " mask %08" PRIx32,
+ LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32,
wp_num, wp->address, wp->mask);
wp_num++;
@@ -171,7 +169,7 @@ static int nds32_v3_deactivate_hardware_watchpoint(struct target *target)
/* disable watchpoint */
aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0);
- LOG_DEBUG("Remove hardware wathcpoint %" PRId32 " at %08" PRIx32
+ LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR
" mask %08" PRIx32, wp_num,
wp->address, wp->mask);
wp_num++;
diff --git a/src/target/nds32_v3.h b/src/target/nds32_v3.h
index 7476b202c..a5df8fe52 100644
--- a/src/target/nds32_v3.h
+++ b/src/target/nds32_v3.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_V3_H__
-#define __NDS32_V3_H__
+
+#ifndef OPENOCD_TARGET_NDS32_V3_H
+#define OPENOCD_TARGET_NDS32_V3_H
#include "nds32.h"
@@ -43,4 +42,4 @@ static inline struct nds32_v3_common *target_to_nds32_v3(struct target *target)
return container_of(target->arch_info, struct nds32_v3_common, nds32);
}
-#endif /* __NDS32_V3_H__ */
+#endif /* OPENOCD_TARGET_NDS32_V3_H */
diff --git a/src/target/nds32_v3_common.c b/src/target/nds32_v3_common.c
index 6dc20982d..271ffdd1c 100644
--- a/src/target/nds32_v3_common.c
+++ b/src/target/nds32_v3_common.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -370,7 +368,7 @@ int nds32_v3_target_request_data(struct target *target,
}
int nds32_v3_checksum_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *checksum)
+ target_addr_t address, uint32_t count, uint32_t *checksum)
{
LOG_WARNING("Not implemented: %s", __func__);
@@ -436,8 +434,8 @@ int nds32_v3_run_algorithm(struct target *target,
struct mem_param *mem_params,
int num_reg_params,
struct reg_param *reg_params,
- uint32_t entry_point,
- uint32_t exit_point,
+ target_addr_t entry_point,
+ target_addr_t exit_point,
int timeout_ms,
void *arch_info)
{
@@ -446,7 +444,7 @@ int nds32_v3_run_algorithm(struct target *target,
return ERROR_FAIL;
}
-int nds32_v3_read_buffer(struct target *target, uint32_t address,
+int nds32_v3_read_buffer(struct target *target, target_addr_t address,
uint32_t size, uint8_t *buffer)
{
struct nds32 *nds32 = target_to_nds32(target);
@@ -458,7 +456,7 @@ int nds32_v3_read_buffer(struct target *target, uint32_t address,
return ERROR_TARGET_NOT_HALTED;
}
- uint32_t physical_address;
+ target_addr_t physical_address;
/* BUG: If access range crosses multiple pages, the translation will not correct
* for second page or so. */
@@ -504,7 +502,7 @@ int nds32_v3_read_buffer(struct target *target, uint32_t address,
return result;
}
-int nds32_v3_write_buffer(struct target *target, uint32_t address,
+int nds32_v3_write_buffer(struct target *target, target_addr_t address,
uint32_t size, const uint8_t *buffer)
{
struct nds32 *nds32 = target_to_nds32(target);
@@ -516,7 +514,7 @@ int nds32_v3_write_buffer(struct target *target, uint32_t address,
return ERROR_TARGET_NOT_HALTED;
}
- uint32_t physical_address;
+ target_addr_t physical_address;
/* BUG: If access range crosses multiple pages, the translation will not correct
* for second page or so. */
@@ -566,7 +564,7 @@ int nds32_v3_write_buffer(struct target *target, uint32_t address,
return nds32_write_buffer(target, address, size, buffer);
}
-int nds32_v3_read_memory(struct target *target, uint32_t address,
+int nds32_v3_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct nds32 *nds32 = target_to_nds32(target);
@@ -578,7 +576,7 @@ int nds32_v3_read_memory(struct target *target, uint32_t address,
return ERROR_TARGET_NOT_HALTED;
}
- uint32_t physical_address;
+ target_addr_t physical_address;
/* BUG: If access range crosses multiple pages, the translation will not correct
* for second page or so. */
@@ -624,7 +622,7 @@ int nds32_v3_read_memory(struct target *target, uint32_t address,
return result;
}
-int nds32_v3_write_memory(struct target *target, uint32_t address,
+int nds32_v3_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct nds32 *nds32 = target_to_nds32(target);
@@ -636,7 +634,7 @@ int nds32_v3_write_memory(struct target *target, uint32_t address,
return ERROR_TARGET_NOT_HALTED;
}
- uint32_t physical_address;
+ target_addr_t physical_address;
/* BUG: If access range crosses multiple pages, the translation will not correct
* for second page or so. */
diff --git a/src/target/nds32_v3_common.h b/src/target/nds32_v3_common.h
index fd4a59071..23393e55d 100644
--- a/src/target/nds32_v3_common.h
+++ b/src/target/nds32_v3_common.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_V3_COMMON_H__
-#define __NDS32_V3_COMMON_H__
+
+#ifndef OPENOCD_TARGET_NDS32_V3_COMMON_H
+#define OPENOCD_TARGET_NDS32_V3_COMMON_H
#include "target.h"
@@ -35,7 +34,7 @@ void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback
int nds32_v3_target_request_data(struct target *target,
uint32_t size, uint8_t *buffer);
int nds32_v3_checksum_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *checksum);
+ target_addr_t address, uint32_t count, uint32_t *checksum);
int nds32_v3_hit_watchpoint(struct target *target,
struct watchpoint **hit_watchpoint);
int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32);
@@ -44,19 +43,19 @@ int nds32_v3_run_algorithm(struct target *target,
struct mem_param *mem_params,
int num_reg_params,
struct reg_param *reg_params,
- uint32_t entry_point,
- uint32_t exit_point,
+ target_addr_t entry_point,
+ target_addr_t exit_point,
int timeout_ms,
void *arch_info);
-int nds32_v3_read_buffer(struct target *target, uint32_t address,
+int nds32_v3_read_buffer(struct target *target, target_addr_t address,
uint32_t size, uint8_t *buffer);
-int nds32_v3_write_buffer(struct target *target, uint32_t address,
+int nds32_v3_write_buffer(struct target *target, target_addr_t address,
uint32_t size, const uint8_t *buffer);
-int nds32_v3_read_memory(struct target *target, uint32_t address,
+int nds32_v3_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer);
-int nds32_v3_write_memory(struct target *target, uint32_t address,
+int nds32_v3_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
int nds32_v3_init_target(struct command_context *cmd_ctx,
struct target *target);
-#endif /* __NDS32_V3_COMMON_H__ */
+#endif /* OPENOCD_TARGET_NDS32_V3_COMMON_H */
diff --git a/src/target/nds32_v3m.c b/src/target/nds32_v3m.c
index accc8d056..86903a51b 100644
--- a/src/target/nds32_v3m.c
+++ b/src/target/nds32_v3m.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -52,7 +50,7 @@ static int nds32_v3m_activate_hardware_breakpoint(struct target *target)
/* enable breakpoint (physical address) */
aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0xA);
- LOG_DEBUG("Add hardware BP %u at %08" PRIx32, brp_num,
+ LOG_DEBUG("Add hardware BP %u at %08" TARGET_PRIxADDR, brp_num,
bp->address);
brp_num--;
@@ -80,7 +78,7 @@ static int nds32_v3m_deactivate_hardware_breakpoint(struct target *target)
else
return ERROR_FAIL;
- LOG_DEBUG("Remove hardware BP %u at %08" PRIx32, brp_num,
+ LOG_DEBUG("Remove hardware BP %u at %08" TARGET_PRIxADDR, brp_num,
bp->address);
brp_num--;
@@ -127,7 +125,7 @@ static int nds32_v3m_activate_hardware_watchpoint(struct target *target)
/* enable watchpoint */
aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config);
- LOG_DEBUG("Add hardware wathcpoint %" PRId32 " at %08" PRIx32
+ LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR
" mask %08" PRIx32, wp_num, wp->address, wp->mask);
wp_num++;
@@ -168,7 +166,7 @@ static int nds32_v3m_deactivate_hardware_watchpoint(struct target *target)
/* disable watchpoint */
aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0);
- LOG_DEBUG("Remove hardware wathcpoint %" PRId32 " at %08" PRIx32
+ LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR
" mask %08" PRIx32, wp_num, wp->address, wp->mask);
wp_num++;
} else if (nds32_v3m->nds32.global_stop) {
diff --git a/src/target/nds32_v3m.h b/src/target/nds32_v3m.h
index d72c2ad43..1e7427c48 100644
--- a/src/target/nds32_v3m.h
+++ b/src/target/nds32_v3m.h
@@ -13,12 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef __NDS32_V3M_H__
-#define __NDS32_V3M_H__
+
+#ifndef OPENOCD_TARGET_NDS32_V3M_H
+#define OPENOCD_TARGET_NDS32_V3M_H
#include "nds32.h"
@@ -49,5 +48,4 @@ static inline struct nds32_v3m_common *target_to_nds32_v3m(struct target *target
return container_of(target->arch_info, struct nds32_v3m_common, nds32);
}
-
-#endif /* __NDS32_V3M_H__ */
+#endif /* OPENOCD_TARGET_NDS32_V3M_H */
diff --git a/src/target/oocd_trace.c b/src/target/oocd_trace.c
index e723efe04..627366d5d 100644
--- a/src/target/oocd_trace.c
+++ b/src/target/oocd_trace.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/oocd_trace.h b/src/target/oocd_trace.h
index 5773674d3..e7584e4c9 100644
--- a/src/target/oocd_trace.h
+++ b/src/target/oocd_trace.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef OOCD_TRACE_H
-#define OOCD_TRACE_H
+#ifndef OPENOCD_TARGET_OOCD_TRACE_H
+#define OPENOCD_TARGET_OOCD_TRACE_H
#include
@@ -52,4 +50,4 @@ struct oocd_trace {
extern struct etm_capture_driver oocd_trace_capture_driver;
-#endif /* OOCD_TRACE_TRACE_H */
+#endif /* OPENOCD_TARGET_OOCD_TRACE_H */
diff --git a/src/target/openrisc/Makefile.am b/src/target/openrisc/Makefile.am
index b00a30d6f..5a2549a51 100644
--- a/src/target/openrisc/Makefile.am
+++ b/src/target/openrisc/Makefile.am
@@ -1,18 +1,12 @@
-include $(top_srcdir)/common.mk
-
-noinst_LTLIBRARIES = libopenrisc.la
-libopenrisc_la_SOURCES = $(OPENRISC_SRC)
-
-OPENRISC_SRC = \
- or1k.c \
- or1k_du_adv.c \
- or1k_tap_mohor.c \
- or1k_tap_vjtag.c \
- or1k_tap_xilinx_bscan.c \
- jsp_server.c
-
-noinst_HEADERS = \
- or1k.h \
- or1k_du.h \
- or1k_tap.h \
- jsp_server.h
+noinst_LTLIBRARIES += %D%/libopenrisc.la
+%C%_libopenrisc_la_SOURCES = \
+ %D%/or1k.c \
+ %D%/or1k_du_adv.c \
+ %D%/or1k_tap_mohor.c \
+ %D%/or1k_tap_vjtag.c \
+ %D%/or1k_tap_xilinx_bscan.c \
+ %D%/jsp_server.c \
+ %D%/or1k.h \
+ %D%/or1k_du.h \
+ %D%/or1k_tap.h \
+ %D%/jsp_server.h
diff --git a/src/target/openrisc/jsp_server.c b/src/target/openrisc/jsp_server.c
index 83e03ae3e..e581fb870 100644
--- a/src/target/openrisc/jsp_server.c
+++ b/src/target/openrisc/jsp_server.c
@@ -15,9 +15,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/openrisc/jsp_server.h b/src/target/openrisc/jsp_server.h
index 3e7c1145d..f8e71215a 100644
--- a/src/target/openrisc/jsp_server.h
+++ b/src/target/openrisc/jsp_server.h
@@ -1,5 +1,5 @@
-#ifndef _JSP_SERVER_H_
-#define _JSP_SERVER_H_
+#ifndef OPENOCD_TARGET_OPENRISC_JSP_SERVER_H
+#define OPENOCD_TARGET_OPENRISC_JSP_SERVER_H
#include "or1k_tap.h"
#include "or1k.h"
@@ -14,4 +14,4 @@ struct jsp_service {
int jsp_init(struct or1k_jtag *jtag_info, char *banner);
int jsp_register_commands(struct command_context *cmd_ctx);
-#endif /* _JSP_SERVER_H_ */
+#endif /* OPENOCD_TARGET_OPENRISC_JSP_SERVER_H */
diff --git a/src/target/openrisc/or1k.c b/src/target/openrisc/or1k.c
index 33de63e2d..3895ddfaf 100644
--- a/src/target/openrisc/or1k.c
+++ b/src/target/openrisc/or1k.c
@@ -18,6 +18,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -858,7 +861,7 @@ static int or1k_resume_or_step(struct target *target, int current,
/* Single step past breakpoint at current address */
breakpoint = breakpoint_find(target, resume_pc);
if (breakpoint) {
- LOG_DEBUG("Unset breakpoint at 0x%08" PRIx32, breakpoint->address);
+ LOG_DEBUG("Unset breakpoint at 0x%08" TARGET_PRIxADDR, breakpoint->address);
retval = or1k_remove_breakpoint(target, breakpoint);
if (retval != ERROR_OK)
return retval;
@@ -894,7 +897,8 @@ static int or1k_resume_or_step(struct target *target, int current,
}
static int or1k_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints,
+ int debug_execution)
{
return or1k_resume_or_step(target, current, address,
handle_breakpoints,
@@ -903,7 +907,7 @@ static int or1k_resume(struct target *target, int current,
}
static int or1k_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
return or1k_resume_or_step(target, current, address,
handle_breakpoints,
@@ -919,7 +923,7 @@ static int or1k_add_breakpoint(struct target *target,
struct or1k_du *du_core = or1k_to_du(or1k);
uint8_t data;
- LOG_DEBUG("Adding breakpoint: addr 0x%08" PRIx32 ", len %d, type %d, set: %d, id: %" PRId32,
+ LOG_DEBUG("Adding breakpoint: addr 0x%08" TARGET_PRIxADDR ", len %d, type %d, set: %d, id: %" PRId32,
breakpoint->address, breakpoint->length, breakpoint->type,
breakpoint->set, breakpoint->unique_id);
@@ -934,7 +938,7 @@ static int or1k_add_breakpoint(struct target *target,
1,
&data);
if (retval != ERROR_OK) {
- LOG_ERROR("Error while reading the instruction at 0x%08" PRIx32,
+ LOG_ERROR("Error while reading the instruction at 0x%08" TARGET_PRIxADDR,
breakpoint->address);
return retval;
}
@@ -955,14 +959,15 @@ static int or1k_add_breakpoint(struct target *target,
or1k_trap_insn);
if (retval != ERROR_OK) {
- LOG_ERROR("Error while writing OR1K_TRAP_INSTR at 0x%08" PRIx32,
+ LOG_ERROR("Error while writing OR1K_TRAP_INSTR at 0x%08" TARGET_PRIxADDR,
breakpoint->address);
return retval;
}
/* invalidate instruction cache */
+ uint32_t addr = breakpoint->address;
retval = du_core->or1k_jtag_write_cpu(&or1k->jtag,
- OR1K_ICBIR_CPU_REG_ADD, 1, &breakpoint->address);
+ OR1K_ICBIR_CPU_REG_ADD, 1, &addr);
if (retval != ERROR_OK) {
LOG_ERROR("Error while invalidating the ICACHE");
return retval;
@@ -977,7 +982,7 @@ static int or1k_remove_breakpoint(struct target *target,
struct or1k_common *or1k = target_to_or1k(target);
struct or1k_du *du_core = or1k_to_du(or1k);
- LOG_DEBUG("Removing breakpoint: addr 0x%08" PRIx32 ", len %d, type %d, set: %d, id: %" PRId32,
+ LOG_DEBUG("Removing breakpoint: addr 0x%08" TARGET_PRIxADDR ", len %d, type %d, set: %d, id: %" PRId32,
breakpoint->address, breakpoint->length, breakpoint->type,
breakpoint->set, breakpoint->unique_id);
@@ -993,14 +998,15 @@ static int or1k_remove_breakpoint(struct target *target,
breakpoint->orig_instr);
if (retval != ERROR_OK) {
- LOG_ERROR("Error while writing back the instruction at 0x%08" PRIx32,
+ LOG_ERROR("Error while writing back the instruction at 0x%08" TARGET_PRIxADDR,
breakpoint->address);
return retval;
}
/* invalidate instruction cache */
+ uint32_t addr = breakpoint->address;
retval = du_core->or1k_jtag_write_cpu(&or1k->jtag,
- OR1K_ICBIR_CPU_REG_ADD, 1, &breakpoint->address);
+ OR1K_ICBIR_CPU_REG_ADD, 1, &addr);
if (retval != ERROR_OK) {
LOG_ERROR("Error while invalidating the ICACHE");
return retval;
@@ -1023,13 +1029,13 @@ static int or1k_remove_watchpoint(struct target *target,
return ERROR_OK;
}
-static int or1k_read_memory(struct target *target, uint32_t address,
+static int or1k_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct or1k_common *or1k = target_to_or1k(target);
struct or1k_du *du_core = or1k_to_du(or1k);
- LOG_DEBUG("Read memory at 0x%08" PRIx32 ", size: %" PRIu32 ", count: 0x%08" PRIx32, address, size, count);
+ LOG_DEBUG("Read memory at 0x%08" TARGET_PRIxADDR ", size: %" PRIu32 ", count: 0x%08" PRIx32, address, size, count);
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
@@ -1050,13 +1056,13 @@ static int or1k_read_memory(struct target *target, uint32_t address,
return du_core->or1k_jtag_read_memory(&or1k->jtag, address, size, count, buffer);
}
-static int or1k_write_memory(struct target *target, uint32_t address,
+static int or1k_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct or1k_common *or1k = target_to_or1k(target);
struct or1k_du *du_core = or1k_to_du(or1k);
- LOG_DEBUG("Write memory at 0x%08" PRIx32 ", size: %" PRIu32 ", count: 0x%08" PRIx32, address, size, count);
+ LOG_DEBUG("Write memory at 0x%08" TARGET_PRIxADDR ", size: %" PRIu32 ", count: 0x%08" PRIx32, address, size, count);
if (target->state != TARGET_HALTED) {
LOG_WARNING("Target not halted");
@@ -1200,7 +1206,7 @@ int or1k_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *file
return ERROR_FAIL;
}
-static int or1k_checksum_memory(struct target *target, uint32_t address,
+static int or1k_checksum_memory(struct target *target, target_addr_t address,
uint32_t count, uint32_t *checksum) {
return ERROR_FAIL;
diff --git a/src/target/openrisc/or1k.h b/src/target/openrisc/or1k.h
index 25024dc3d..c456ccbe2 100644
--- a/src/target/openrisc/or1k.h
+++ b/src/target/openrisc/or1k.h
@@ -18,10 +18,13 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef OR1K_H
-#define OR1K_H
+#ifndef OPENOCD_TARGET_OPENRISC_OR1K_H
+#define OPENOCD_TARGET_OPENRISC_OR1K_H
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -152,4 +155,4 @@ enum or1k_debug_reg_nums {
*/
#define OR1K_ICBIR_CPU_REG_ADD ((4 << 11) + 2) /* IC Block Invalidate Register 0x2002 */
-#endif
+#endif /* OPENOCD_TARGET_OPENRISC_OR1K_H */
diff --git a/src/target/openrisc/or1k_du.h b/src/target/openrisc/or1k_du.h
index cc22fdb94..9828b0d22 100644
--- a/src/target/openrisc/or1k_du.h
+++ b/src/target/openrisc/or1k_du.h
@@ -11,10 +11,13 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef OR1K_DU
-#define OR1K_DU
+#ifndef OPENOCD_TARGET_OPENRISC_OR1K_DU_H
+#define OPENOCD_TARGET_OPENRISC_OR1K_DU_H
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -72,5 +75,4 @@ int or1k_adv_jtag_jsp_xfer(struct or1k_jtag *jtag_info,
int *out_len, unsigned char *out_buffer,
int *in_len, unsigned char *in_buffer);
-#endif
-
+#endif /* 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 e4681ffba..bdd6fc8cb 100644
--- a/src/target/openrisc/or1k_du_adv.c
+++ b/src/target/openrisc/or1k_du_adv.c
@@ -19,6 +19,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/openrisc/or1k_tap.h b/src/target/openrisc/or1k_tap.h
index cce118973..2cf7da804 100644
--- a/src/target/openrisc/or1k_tap.h
+++ b/src/target/openrisc/or1k_tap.h
@@ -11,10 +11,13 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef _OR1K_TAP_H_
-#define _OR1K_TAP_H_
+#ifndef OPENOCD_TARGET_OPENRISC_OR1K_TAP_H
+#define OPENOCD_TARGET_OPENRISC_OR1K_TAP_H
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -36,4 +39,4 @@ struct or1k_tap_ip {
const char *name;
};
-#endif
+#endif /* 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 b654b1b53..1415e321c 100644
--- a/src/target/openrisc/or1k_tap_mohor.c
+++ b/src/target/openrisc/or1k_tap_mohor.c
@@ -11,6 +11,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/openrisc/or1k_tap_vjtag.c b/src/target/openrisc/or1k_tap_vjtag.c
index c3b942b2e..607451a7c 100644
--- a/src/target/openrisc/or1k_tap_vjtag.c
+++ b/src/target/openrisc/or1k_tap_vjtag.c
@@ -11,6 +11,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#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 1e90b9398..a77c65ef8 100644
--- a/src/target/openrisc/or1k_tap_xilinx_bscan.c
+++ b/src/target/openrisc/or1k_tap_xilinx_bscan.c
@@ -11,6 +11,9 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/quark_x10xx.c b/src/target/quark_x10xx.c
index 9a1ccb65d..189f6cc65 100644
--- a/src/target/quark_x10xx.c
+++ b/src/target/quark_x10xx.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2013 Intel Corporation.
+ * Copyright(c) 2013-2016 Intel Corporation.
*
* Adrian Burns (adrian.burns@intel.com)
* Thomas Faust (thomas.faust@intel.com)
@@ -18,8 +18,7 @@
* 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., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*
* Contact Information:
* Intel Corporation
@@ -61,6 +60,7 @@ int quark_x10xx_target_create(struct target *t, Jim_Interp *interp)
}
x86_32_common_init_arch_info(t, x86_32);
lakemont_init_arch_info(t, x86_32);
+ x86_32->core_type = LMT1;
return ERROR_OK;
}
diff --git a/src/target/register.c b/src/target/register.c
index 1c1717c8f..1d63e12f7 100644
--- a/src/target/register.c
+++ b/src/target/register.c
@@ -16,9 +16,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/register.h b/src/target/register.h
index 7bac69b5a..d4c328160 100644
--- a/src/target/register.h
+++ b/src/target/register.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef REGISTER_H
-#define REGISTER_H
+#ifndef OPENOCD_TARGET_REGISTER_H
+#define OPENOCD_TARGET_REGISTER_H
struct target;
@@ -116,17 +114,32 @@ struct reg_data_type {
};
struct reg {
+ /** Canonical name of the register. */
const char *name;
+ /** Number that gdb uses to access this register. */
uint32_t number;
+ /* TODO. This should probably be const. */
struct reg_feature *feature;
+ /* TODO: When true, the caller will save this register before running any algorithm. */
bool caller_save;
+ /* Pointer to place where the value is stored, in the format understood by
+ * the binarybuffer.h functions. */
void *value;
+ /* The stored value needs to be written to the target. */
bool dirty;
+ /* When true, value is valid. */
bool valid;
+ /* When false, the register doesn't actually exist in the target. */
bool exist;
+ /* Size of the register in bits. */
uint32_t size;
+ /* Used for generating XML description of registers. Can be set to NULL for
+ * targets that don't use that. */
struct reg_data_type *reg_data_type;
+ /* Used for generating XML description of registers. Can be set to NULL for
+ * targets that don't use that. */
const char *group;
+ /* Pointer to architecture-specific info for this register. */
void *arch_info;
const struct reg_arch_type *type;
};
@@ -151,4 +164,4 @@ void register_cache_invalidate(struct reg_cache *cache);
void register_init_dummy(struct reg *reg);
-#endif /* REGISTER_H */
+#endif /* OPENOCD_TARGET_REGISTER_H */
diff --git a/src/target/smp.c b/src/target/smp.c
index da9ee8b46..bdf81a0ee 100644
--- a/src/target/smp.c
+++ b/src/target/smp.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -66,7 +64,8 @@ int gdb_read_smp_packet(struct connection *connection,
char hex_buffer[len * 2 + 1];
uint8_t buffer[len];
buf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]);
- int pkt_len = hexify(hex_buffer, (char *)buffer, sizeof(buffer), sizeof(hex_buffer));
+ size_t pkt_len = hexify(hex_buffer, buffer, sizeof(buffer),
+ sizeof(hex_buffer));
retval = gdb_put_packet(connection, hex_buffer, pkt_len);
}
diff --git a/src/target/smp.h b/src/target/smp.h
index 69a5cd855..c3e6c6cea 100644
--- a/src/target/smp.h
+++ b/src/target/smp.h
@@ -13,11 +13,12 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
+#ifndef OPENOCD_TARGET_SMP_H
+#define OPENOCD_TARGET_SMP_H
+
#include "server/server.h"
int gdb_read_smp_packet(struct connection *connection,
@@ -25,3 +26,4 @@ int gdb_read_smp_packet(struct connection *connection,
int gdb_write_smp_packet(struct connection *connection,
char const *packet, int packet_size);
+#endif /* OPENOCD_TARGET_SMP_H */
diff --git a/src/target/startup.tcl b/src/target/startup.tcl
index cf2813ba8..9bbc6e32c 100644
--- a/src/target/startup.tcl
+++ b/src/target/startup.tcl
@@ -65,7 +65,7 @@ proc ocd_process_reset_inner { MODE } {
foreach t $targets {
if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} {
$t invoke-event examine-start
- set err [catch "$t arp_examine"]
+ set err [catch "$t arp_examine allow-defer"]
if { $err == 0 } {
$t invoke-event examine-end
}
@@ -111,6 +111,12 @@ proc ocd_process_reset_inner { MODE } {
continue
}
+ # don't wait for targets where examination is deferred
+ # they can not be halted anyway at this point
+ if { ![$t was_examined] && [$t examine_deferred] } {
+ continue
+ }
+
# Wait upto 1 second for target to halt. Why 1sec? Cause
# the JTAG tap reset signal might be hooked to a slow
# resistor/capacitor circuit - and it might take a while
@@ -135,6 +141,12 @@ proc ocd_process_reset_inner { MODE } {
continue
}
+ # don't wait for targets where examination is deferred
+ # they can not be halted anyway at this point
+ if { ![$t was_examined] && [$t examine_deferred] } {
+ continue
+ }
+
set err [catch "$t arp_waitstate halted 5000"]
# Did it halt?
if { $err == 0 } {
diff --git a/src/target/target.c b/src/target/target.c
index 598d7d5a8..372255332 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -34,9 +34,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -60,21 +58,21 @@
/* default halt wait timeout (ms) */
#define DEFAULT_HALT_TIMEOUT 5000
-static int target_read_buffer_default(struct target *target, uint32_t address,
- uint32_t count, uint8_t *buffer);
-static int target_write_buffer_default(struct target *target, uint32_t address,
- uint32_t count, const uint8_t *buffer);
+static int target_read_buffer_default(struct target *target, target_addr_t address,
+ uint32_t count, uint8_t *buffer);
+static int target_write_buffer_default(struct target *target, target_addr_t address,
+ uint32_t count, const uint8_t *buffer);
static int target_array2mem(Jim_Interp *interp, struct target *target,
- int argc, Jim_Obj * const *argv);
+ int argc, Jim_Obj * const *argv);
static int target_mem2array(Jim_Interp *interp, struct target *target,
- int argc, Jim_Obj * const *argv);
+ int argc, Jim_Obj * const *argv);
static int target_register_user_commands(struct command_context *cmd_ctx);
static int target_get_gdb_fileio_info_default(struct target *target,
- struct gdb_fileio_info *fileio_info);
+ struct gdb_fileio_info *fileio_info);
static int target_gdb_fileio_end_default(struct target *target, int retcode,
- int fileio_errno, bool ctrl_c);
+ int fileio_errno, bool ctrl_c);
static int target_profiling_default(struct target *target, uint32_t *samples,
- uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);
+ uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);
/* targets */
extern struct target_type arm7tdmi_target;
@@ -90,8 +88,10 @@ extern struct target_type dragonite_target;
extern struct target_type xscale_target;
extern struct target_type cortexm_target;
extern struct target_type cortexa_target;
+extern struct target_type aarch64_target;
extern struct target_type cortexr4_target;
extern struct target_type arm11_target;
+extern struct target_type ls1_sap_target;
extern struct target_type mips_m4k_target;
extern struct target_type avr_target;
extern struct target_type dsp563xx_target;
@@ -104,6 +104,10 @@ extern struct target_type nds32_v3_target;
extern struct target_type nds32_v3m_target;
extern struct target_type or1k_target;
extern struct target_type quark_x10xx_target;
+extern struct target_type quark_d20xx_target;
+#if BUILD_RISCV == 1
+extern struct target_type riscv_target;
+#endif
static struct target_type *target_types[] = {
&arm7tdmi_target,
@@ -121,6 +125,7 @@ static struct target_type *target_types[] = {
&cortexa_target,
&cortexr4_target,
&arm11_target,
+ &ls1_sap_target,
&mips_m4k_target,
&avr_target,
&dsp563xx_target,
@@ -133,7 +138,14 @@ static struct target_type *target_types[] = {
&nds32_v3m_target,
&or1k_target,
&quark_x10xx_target,
- NULL,
+ &quark_d20xx_target,
+#if BUILD_TARGET64
+ &aarch64_target,
+#endif
+#if BUILD_RISCV == 1
+ &riscv_target,
+#endif
+ NULL,
};
struct target *all_targets;
@@ -144,421 +156,425 @@ LIST_HEAD(target_trace_callback_list);
static const int polling_interval = 100;
static const Jim_Nvp nvp_assert[] = {
- { .name = "assert", NVP_ASSERT },
- { .name = "deassert", NVP_DEASSERT },
- { .name = "T", NVP_ASSERT },
- { .name = "F", NVP_DEASSERT },
- { .name = "t", NVP_ASSERT },
- { .name = "f", NVP_DEASSERT },
- { .name = NULL, .value = -1 }
+ { .name = "assert", NVP_ASSERT },
+ { .name = "deassert", NVP_DEASSERT },
+ { .name = "T", NVP_ASSERT },
+ { .name = "F", NVP_DEASSERT },
+ { .name = "t", NVP_ASSERT },
+ { .name = "f", NVP_DEASSERT },
+ { .name = NULL, .value = -1 }
};
static const Jim_Nvp nvp_error_target[] = {
- { .value = ERROR_TARGET_INVALID, .name = "err-invalid" },
- { .value = ERROR_TARGET_INIT_FAILED, .name = "err-init-failed" },
- { .value = ERROR_TARGET_TIMEOUT, .name = "err-timeout" },
- { .value = ERROR_TARGET_NOT_HALTED, .name = "err-not-halted" },
- { .value = ERROR_TARGET_FAILURE, .name = "err-failure" },
- { .value = ERROR_TARGET_UNALIGNED_ACCESS , .name = "err-unaligned-access" },
- { .value = ERROR_TARGET_DATA_ABORT , .name = "err-data-abort" },
- { .value = ERROR_TARGET_RESOURCE_NOT_AVAILABLE , .name = "err-resource-not-available" },
- { .value = ERROR_TARGET_TRANSLATION_FAULT , .name = "err-translation-fault" },
- { .value = ERROR_TARGET_NOT_RUNNING, .name = "err-not-running" },
- { .value = ERROR_TARGET_NOT_EXAMINED, .name = "err-not-examined" },
- { .value = -1, .name = NULL }
+ { .value = ERROR_TARGET_INVALID, .name = "err-invalid" },
+ { .value = ERROR_TARGET_INIT_FAILED, .name = "err-init-failed" },
+ { .value = ERROR_TARGET_TIMEOUT, .name = "err-timeout" },
+ { .value = ERROR_TARGET_NOT_HALTED, .name = "err-not-halted" },
+ { .value = ERROR_TARGET_FAILURE, .name = "err-failure" },
+ { .value = ERROR_TARGET_UNALIGNED_ACCESS , .name = "err-unaligned-access" },
+ { .value = ERROR_TARGET_DATA_ABORT , .name = "err-data-abort" },
+ { .value = ERROR_TARGET_RESOURCE_NOT_AVAILABLE , .name = "err-resource-not-available" },
+ { .value = ERROR_TARGET_TRANSLATION_FAULT , .name = "err-translation-fault" },
+ { .value = ERROR_TARGET_NOT_RUNNING, .name = "err-not-running" },
+ { .value = ERROR_TARGET_NOT_EXAMINED, .name = "err-not-examined" },
+ { .value = -1, .name = NULL }
};
static const char *target_strerror_safe(int err)
{
- const Jim_Nvp *n;
-
- n = Jim_Nvp_value2name_simple(nvp_error_target, err);
- if (n->name == NULL)
- return "unknown";
- else
- return n->name;
+ const Jim_Nvp *n;
+
+ n = Jim_Nvp_value2name_simple(nvp_error_target, err);
+ if (n->name == NULL)
+ return "unknown";
+ else
+ return n->name;
}
static const Jim_Nvp nvp_target_event[] = {
-
- { .value = TARGET_EVENT_GDB_HALT, .name = "gdb-halt" },
- { .value = TARGET_EVENT_HALTED, .name = "halted" },
- { .value = TARGET_EVENT_RESUMED, .name = "resumed" },
- { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
- { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" },
-
- { .name = "gdb-start", .value = TARGET_EVENT_GDB_START },
- { .name = "gdb-end", .value = TARGET_EVENT_GDB_END },
-
- { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
- { .value = TARGET_EVENT_RESET_ASSERT_PRE, .name = "reset-assert-pre" },
- { .value = TARGET_EVENT_RESET_ASSERT, .name = "reset-assert" },
- { .value = TARGET_EVENT_RESET_ASSERT_POST, .name = "reset-assert-post" },
- { .value = TARGET_EVENT_RESET_DEASSERT_PRE, .name = "reset-deassert-pre" },
- { .value = TARGET_EVENT_RESET_DEASSERT_POST, .name = "reset-deassert-post" },
- { .value = TARGET_EVENT_RESET_HALT_PRE, .name = "reset-halt-pre" },
- { .value = TARGET_EVENT_RESET_HALT_POST, .name = "reset-halt-post" },
- { .value = TARGET_EVENT_RESET_WAIT_PRE, .name = "reset-wait-pre" },
- { .value = TARGET_EVENT_RESET_WAIT_POST, .name = "reset-wait-post" },
- { .value = TARGET_EVENT_RESET_INIT, .name = "reset-init" },
- { .value = TARGET_EVENT_RESET_END, .name = "reset-end" },
-
- { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" },
- { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" },
-
- { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" },
- { .value = TARGET_EVENT_DEBUG_RESUMED, .name = "debug-resumed" },
-
- { .value = TARGET_EVENT_GDB_ATTACH, .name = "gdb-attach" },
- { .value = TARGET_EVENT_GDB_DETACH, .name = "gdb-detach" },
-
- { .value = TARGET_EVENT_GDB_FLASH_WRITE_START, .name = "gdb-flash-write-start" },
- { .value = TARGET_EVENT_GDB_FLASH_WRITE_END , .name = "gdb-flash-write-end" },
-
- { .value = TARGET_EVENT_GDB_FLASH_ERASE_START, .name = "gdb-flash-erase-start" },
- { .value = TARGET_EVENT_GDB_FLASH_ERASE_END , .name = "gdb-flash-erase-end" },
-
- { .value = TARGET_EVENT_TRACE_CONFIG, .name = "trace-config" },
-
- { .name = NULL, .value = -1 }
+
+ { .value = TARGET_EVENT_GDB_HALT, .name = "gdb-halt" },
+ { .value = TARGET_EVENT_HALTED, .name = "halted" },
+ { .value = TARGET_EVENT_RESUMED, .name = "resumed" },
+ { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
+ { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" },
+
+ { .name = "gdb-start", .value = TARGET_EVENT_GDB_START },
+ { .name = "gdb-end", .value = TARGET_EVENT_GDB_END },
+
+ { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
+ { .value = TARGET_EVENT_RESET_ASSERT_PRE, .name = "reset-assert-pre" },
+ { .value = TARGET_EVENT_RESET_ASSERT, .name = "reset-assert" },
+ { .value = TARGET_EVENT_RESET_ASSERT_POST, .name = "reset-assert-post" },
+ { .value = TARGET_EVENT_RESET_DEASSERT_PRE, .name = "reset-deassert-pre" },
+ { .value = TARGET_EVENT_RESET_DEASSERT_POST, .name = "reset-deassert-post" },
+ { .value = TARGET_EVENT_RESET_HALT_PRE, .name = "reset-halt-pre" },
+ { .value = TARGET_EVENT_RESET_HALT_POST, .name = "reset-halt-post" },
+ { .value = TARGET_EVENT_RESET_WAIT_PRE, .name = "reset-wait-pre" },
+ { .value = TARGET_EVENT_RESET_WAIT_POST, .name = "reset-wait-post" },
+ { .value = TARGET_EVENT_RESET_INIT, .name = "reset-init" },
+ { .value = TARGET_EVENT_RESET_END, .name = "reset-end" },
+
+ { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" },
+ { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" },
+
+ { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" },
+ { .value = TARGET_EVENT_DEBUG_RESUMED, .name = "debug-resumed" },
+
+ { .value = TARGET_EVENT_GDB_ATTACH, .name = "gdb-attach" },
+ { .value = TARGET_EVENT_GDB_DETACH, .name = "gdb-detach" },
+
+ { .value = TARGET_EVENT_GDB_FLASH_WRITE_START, .name = "gdb-flash-write-start" },
+ { .value = TARGET_EVENT_GDB_FLASH_WRITE_END , .name = "gdb-flash-write-end" },
+
+ { .value = TARGET_EVENT_GDB_FLASH_ERASE_START, .name = "gdb-flash-erase-start" },
+ { .value = TARGET_EVENT_GDB_FLASH_ERASE_END , .name = "gdb-flash-erase-end" },
+
+ { .value = TARGET_EVENT_TRACE_CONFIG, .name = "trace-config" },
+
+ { .name = NULL, .value = -1 }
};
static const Jim_Nvp nvp_target_state[] = {
- { .name = "unknown", .value = TARGET_UNKNOWN },
- { .name = "running", .value = TARGET_RUNNING },
- { .name = "halted", .value = TARGET_HALTED },
- { .name = "reset", .value = TARGET_RESET },
- { .name = "debug-running", .value = TARGET_DEBUG_RUNNING },
- { .name = NULL, .value = -1 },
+ { .name = "unknown", .value = TARGET_UNKNOWN },
+ { .name = "running", .value = TARGET_RUNNING },
+ { .name = "halted", .value = TARGET_HALTED },
+ { .name = "reset", .value = TARGET_RESET },
+ { .name = "debug-running", .value = TARGET_DEBUG_RUNNING },
+ { .name = NULL, .value = -1 },
};
static const Jim_Nvp nvp_target_debug_reason[] = {
- { .name = "debug-request" , .value = DBG_REASON_DBGRQ },
- { .name = "breakpoint" , .value = DBG_REASON_BREAKPOINT },
- { .name = "watchpoint" , .value = DBG_REASON_WATCHPOINT },
- { .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT },
- { .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
- { .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
- { .name = "program-exit" , .value = DBG_REASON_EXIT },
- { .name = "undefined" , .value = DBG_REASON_UNDEFINED },
- { .name = NULL, .value = -1 },
+ { .name = "debug-request" , .value = DBG_REASON_DBGRQ },
+ { .name = "breakpoint" , .value = DBG_REASON_BREAKPOINT },
+ { .name = "watchpoint" , .value = DBG_REASON_WATCHPOINT },
+ { .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT },
+ { .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
+ { .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
+ { .name = "program-exit" , .value = DBG_REASON_EXIT },
+ { .name = "undefined" , .value = DBG_REASON_UNDEFINED },
+ { .name = NULL, .value = -1 },
};
static const Jim_Nvp nvp_target_endian[] = {
- { .name = "big", .value = TARGET_BIG_ENDIAN },
- { .name = "little", .value = TARGET_LITTLE_ENDIAN },
- { .name = "be", .value = TARGET_BIG_ENDIAN },
- { .name = "le", .value = TARGET_LITTLE_ENDIAN },
- { .name = NULL, .value = -1 },
+ { .name = "big", .value = TARGET_BIG_ENDIAN },
+ { .name = "little", .value = TARGET_LITTLE_ENDIAN },
+ { .name = "be", .value = TARGET_BIG_ENDIAN },
+ { .name = "le", .value = TARGET_LITTLE_ENDIAN },
+ { .name = NULL, .value = -1 },
};
static const Jim_Nvp nvp_reset_modes[] = {
- { .name = "unknown", .value = RESET_UNKNOWN },
- { .name = "run" , .value = RESET_RUN },
- { .name = "halt" , .value = RESET_HALT },
- { .name = "init" , .value = RESET_INIT },
- { .name = NULL , .value = -1 },
+ { .name = "unknown", .value = RESET_UNKNOWN },
+ { .name = "run" , .value = RESET_RUN },
+ { .name = "halt" , .value = RESET_HALT },
+ { .name = "init" , .value = RESET_INIT },
+ { .name = NULL , .value = -1 },
};
const char *debug_reason_name(struct target *t)
{
- const char *cp;
-
- cp = Jim_Nvp_value2name_simple(nvp_target_debug_reason,
- t->debug_reason)->name;
- if (!cp) {
- LOG_ERROR("Invalid debug reason: %d", (int)(t->debug_reason));
- cp = "(*BUG*unknown*BUG*)";
- }
- return cp;
+ const char *cp;
+
+ cp = Jim_Nvp_value2name_simple(nvp_target_debug_reason,
+ t->debug_reason)->name;
+ if (!cp) {
+ LOG_ERROR("Invalid debug reason: %d", (int)(t->debug_reason));
+ cp = "(*BUG*unknown*BUG*)";
+ }
+ return cp;
}
const char *target_state_name(struct target *t)
{
- const char *cp;
- cp = Jim_Nvp_value2name_simple(nvp_target_state, t->state)->name;
- if (!cp) {
- LOG_ERROR("Invalid target state: %d", (int)(t->state));
- cp = "(*BUG*unknown*BUG*)";
- }
- return cp;
+ const char *cp;
+ cp = Jim_Nvp_value2name_simple(nvp_target_state, t->state)->name;
+ if (!cp) {
+ LOG_ERROR("Invalid target state: %d", (int)(t->state));
+ cp = "(*BUG*unknown*BUG*)";
+ }
+
+ if (!target_was_examined(t) && t->defer_examine)
+ cp = "examine deferred";
+
+ return cp;
}
const char *target_event_name(enum target_event event)
{
- const char *cp;
- cp = Jim_Nvp_value2name_simple(nvp_target_event, event)->name;
- if (!cp) {
- LOG_ERROR("Invalid target event: %d", (int)(event));
- cp = "(*BUG*unknown*BUG*)";
- }
- return cp;
+ const char *cp;
+ cp = Jim_Nvp_value2name_simple(nvp_target_event, event)->name;
+ if (!cp) {
+ LOG_ERROR("Invalid target event: %d", (int)(event));
+ cp = "(*BUG*unknown*BUG*)";
+ }
+ return cp;
}
const char *target_reset_mode_name(enum target_reset_mode reset_mode)
{
- const char *cp;
- cp = Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode)->name;
- if (!cp) {
- LOG_ERROR("Invalid target reset mode: %d", (int)(reset_mode));
- cp = "(*BUG*unknown*BUG*)";
- }
- return cp;
+ const char *cp;
+ cp = Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode)->name;
+ if (!cp) {
+ LOG_ERROR("Invalid target reset mode: %d", (int)(reset_mode));
+ cp = "(*BUG*unknown*BUG*)";
+ }
+ return cp;
}
/* determine the number of the new target */
static int new_target_number(void)
{
- struct target *t;
- int x;
-
- /* number is 0 based */
- x = -1;
- t = all_targets;
- while (t) {
- if (x < t->target_number)
- x = t->target_number;
- t = t->next;
- }
- return x + 1;
+ struct target *t;
+ int x;
+
+ /* number is 0 based */
+ x = -1;
+ t = all_targets;
+ while (t) {
+ if (x < t->target_number)
+ x = t->target_number;
+ t = t->next;
+ }
+ return x + 1;
}
/* read a uint64_t from a buffer in target memory endianness */
uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer)
{
- if (target->endianness == TARGET_LITTLE_ENDIAN)
- return le_to_h_u64(buffer);
- else
- return be_to_h_u64(buffer);
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ return le_to_h_u64(buffer);
+ else
+ return be_to_h_u64(buffer);
}
/* read a uint32_t from a buffer in target memory endianness */
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
{
- if (target->endianness == TARGET_LITTLE_ENDIAN)
- return le_to_h_u32(buffer);
- else
- return be_to_h_u32(buffer);
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ return le_to_h_u32(buffer);
+ else
+ return be_to_h_u32(buffer);
}
/* read a uint24_t from a buffer in target memory endianness */
uint32_t target_buffer_get_u24(struct target *target, const uint8_t *buffer)
{
- if (target->endianness == TARGET_LITTLE_ENDIAN)
- return le_to_h_u24(buffer);
- else
- return be_to_h_u24(buffer);
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ return le_to_h_u24(buffer);
+ else
+ return be_to_h_u24(buffer);
}
/* read a uint16_t from a buffer in target memory endianness */
uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer)
{
- if (target->endianness == TARGET_LITTLE_ENDIAN)
- return le_to_h_u16(buffer);
- else
- return be_to_h_u16(buffer);
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ return le_to_h_u16(buffer);
+ else
+ return be_to_h_u16(buffer);
}
/* read a uint8_t from a buffer in target memory endianness */
static uint8_t target_buffer_get_u8(struct target *target, const uint8_t *buffer)
{
- return *buffer & 0x0ff;
+ return *buffer & 0x0ff;
}
/* write a uint64_t to a buffer in target memory endianness */
void target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value)
{
- if (target->endianness == TARGET_LITTLE_ENDIAN)
- h_u64_to_le(buffer, value);
- else
- h_u64_to_be(buffer, value);
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ h_u64_to_le(buffer, value);
+ else
+ h_u64_to_be(buffer, value);
}
/* write a uint32_t to a buffer in target memory endianness */
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
{
- if (target->endianness == TARGET_LITTLE_ENDIAN)
- h_u32_to_le(buffer, value);
- else
- h_u32_to_be(buffer, value);
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ h_u32_to_le(buffer, value);
+ else
+ h_u32_to_be(buffer, value);
}
/* write a uint24_t to a buffer in target memory endianness */
void target_buffer_set_u24(struct target *target, uint8_t *buffer, uint32_t value)
{
- if (target->endianness == TARGET_LITTLE_ENDIAN)
- h_u24_to_le(buffer, value);
- else
- h_u24_to_be(buffer, value);
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ h_u24_to_le(buffer, value);
+ else
+ h_u24_to_be(buffer, value);
}
/* write a uint16_t to a buffer in target memory endianness */
void target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t value)
{
- if (target->endianness == TARGET_LITTLE_ENDIAN)
- h_u16_to_le(buffer, value);
- else
- h_u16_to_be(buffer, value);
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ h_u16_to_le(buffer, value);
+ else
+ h_u16_to_be(buffer, value);
}
/* write a uint8_t to a buffer in target memory endianness */
static void target_buffer_set_u8(struct target *target, uint8_t *buffer, uint8_t value)
{
- *buffer = value;
+ *buffer = value;
}
/* write a uint64_t array to a buffer in target memory endianness */
void target_buffer_get_u64_array(struct target *target, const uint8_t *buffer, uint32_t count, uint64_t *dstbuf)
{
- uint32_t i;
- for (i = 0; i < count; i++)
- dstbuf[i] = target_buffer_get_u64(target, &buffer[i * 8]);
+ uint32_t i;
+ for (i = 0; i < count; i++)
+ dstbuf[i] = target_buffer_get_u64(target, &buffer[i * 8]);
}
/* write a uint32_t array to a buffer in target memory endianness */
void target_buffer_get_u32_array(struct target *target, const uint8_t *buffer, uint32_t count, uint32_t *dstbuf)
{
- uint32_t i;
- for (i = 0; i < count; i++)
- dstbuf[i] = target_buffer_get_u32(target, &buffer[i * 4]);
+ uint32_t i;
+ for (i = 0; i < count; i++)
+ dstbuf[i] = target_buffer_get_u32(target, &buffer[i * 4]);
}
/* write a uint16_t array to a buffer in target memory endianness */
void target_buffer_get_u16_array(struct target *target, const uint8_t *buffer, uint32_t count, uint16_t *dstbuf)
{
- uint32_t i;
- for (i = 0; i < count; i++)
- dstbuf[i] = target_buffer_get_u16(target, &buffer[i * 2]);
+ uint32_t i;
+ for (i = 0; i < count; i++)
+ dstbuf[i] = target_buffer_get_u16(target, &buffer[i * 2]);
}
/* write a uint64_t array to a buffer in target memory endianness */
void target_buffer_set_u64_array(struct target *target, uint8_t *buffer, uint32_t count, const uint64_t *srcbuf)
{
- uint32_t i;
- for (i = 0; i < count; i++)
- target_buffer_set_u64(target, &buffer[i * 8], srcbuf[i]);
+ uint32_t i;
+ for (i = 0; i < count; i++)
+ target_buffer_set_u64(target, &buffer[i * 8], srcbuf[i]);
}
/* write a uint32_t array to a buffer in target memory endianness */
void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf)
{
- uint32_t i;
- for (i = 0; i < count; i++)
- target_buffer_set_u32(target, &buffer[i * 4], srcbuf[i]);
+ uint32_t i;
+ for (i = 0; i < count; i++)
+ target_buffer_set_u32(target, &buffer[i * 4], srcbuf[i]);
}
/* write a uint16_t array to a buffer in target memory endianness */
void target_buffer_set_u16_array(struct target *target, uint8_t *buffer, uint32_t count, const uint16_t *srcbuf)
{
- uint32_t i;
- for (i = 0; i < count; i++)
- target_buffer_set_u16(target, &buffer[i * 2], srcbuf[i]);
+ uint32_t i;
+ for (i = 0; i < count; i++)
+ target_buffer_set_u16(target, &buffer[i * 2], srcbuf[i]);
}
/* return a pointer to a configured target; id is name or number */
struct target *get_target(const char *id)
{
- struct target *target;
-
- /* try as tcltarget name */
- for (target = all_targets; target; target = target->next) {
- if (target_name(target) == NULL)
- continue;
- if (strcmp(id, target_name(target)) == 0)
- return target;
- }
-
- /* It's OK to remove this fallback sometime after August 2010 or so */
-
- /* no match, try as number */
- unsigned num;
- if (parse_uint(id, &num) != ERROR_OK)
- return NULL;
-
- for (target = all_targets; target; target = target->next) {
- if (target->target_number == (int)num) {
- LOG_WARNING("use '%s' as target identifier, not '%u'",
- target_name(target), num);
- return target;
- }
- }
-
- return NULL;
+ struct target *target;
+
+ /* try as tcltarget name */
+ for (target = all_targets; target; target = target->next) {
+ if (target_name(target) == NULL)
+ continue;
+ if (strcmp(id, target_name(target)) == 0)
+ return target;
+ }
+
+ /* It's OK to remove this fallback sometime after August 2010 or so */
+
+ /* no match, try as number */
+ unsigned num;
+ if (parse_uint(id, &num) != ERROR_OK)
+ return NULL;
+
+ for (target = all_targets; target; target = target->next) {
+ if (target->target_number == (int)num) {
+ LOG_WARNING("use '%s' as target identifier, not '%u'",
+ target_name(target), num);
+ return target;
+ }
+ }
+
+ return NULL;
}
/* returns a pointer to the n-th configured target */
struct target *get_target_by_num(int num)
{
- struct target *target = all_targets;
-
- while (target) {
- if (target->target_number == num)
- return target;
- target = target->next;
- }
-
- return NULL;
+ struct target *target = all_targets;
+
+ while (target) {
+ if (target->target_number == num)
+ return target;
+ target = target->next;
+ }
+
+ return NULL;
}
struct target *get_current_target(struct command_context *cmd_ctx)
{
- struct target *target = get_target_by_num(cmd_ctx->current_target);
-
- if (target == NULL) {
- LOG_ERROR("BUG: current_target out of bounds");
- exit(-1);
- }
-
- return target;
+ struct target *target = get_target_by_num(cmd_ctx->current_target);
+
+ if (target == NULL) {
+ LOG_ERROR("BUG: current_target out of bounds");
+ exit(-1);
+ }
+
+ return target;
}
int target_poll(struct target *target)
{
- int retval;
-
- /* We can't poll until after examine */
- if (!target_was_examined(target)) {
- /* Fail silently lest we pollute the log */
- return ERROR_FAIL;
- }
-
- retval = target->type->poll(target);
- if (retval != ERROR_OK)
- return retval;
-
- if (target->halt_issued) {
- if (target->state == TARGET_HALTED)
- target->halt_issued = false;
- else {
- long long t = timeval_ms() - target->halt_issued_time;
- if (t > DEFAULT_HALT_TIMEOUT) {
- target->halt_issued = false;
- LOG_INFO("Halt timed out, wake up GDB.");
- target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
- }
- }
- }
-
- return ERROR_OK;
+ int retval;
+
+ /* We can't poll until after examine */
+ if (!target_was_examined(target)) {
+ /* Fail silently lest we pollute the log */
+ return ERROR_FAIL;
+ }
+
+ retval = target->type->poll(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (target->halt_issued) {
+ if (target->state == TARGET_HALTED)
+ target->halt_issued = false;
+ else {
+ int64_t t = timeval_ms() - target->halt_issued_time;
+ if (t > DEFAULT_HALT_TIMEOUT) {
+ target->halt_issued = false;
+ LOG_INFO("Halt timed out, wake up GDB.");
+ target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
+ }
+ }
+ }
+
+ return ERROR_OK;
}
int target_halt(struct target *target)
{
- int retval;
- /* We can't poll until after examine */
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- retval = target->type->halt(target);
- if (retval != ERROR_OK)
- return retval;
-
- target->halt_issued = true;
- target->halt_issued_time = timeval_ms();
-
- return ERROR_OK;
+ int retval;
+ /* We can't poll until after examine */
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ retval = target->type->halt(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ target->halt_issued = true;
+ target->halt_issued_time = timeval_ms();
+
+ return ERROR_OK;
}
/**
@@ -591,124 +607,125 @@ int target_halt(struct target *target)
* hand the infrastructure for running such helpers might use this
* procedure but rely on hardware breakpoint to detect termination.)
*/
-int target_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
-{
- int retval;
-
- /* We can't poll until after examine */
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- target_call_event_callbacks(target, TARGET_EVENT_RESUME_START);
-
- /* note that resume *must* be asynchronous. The CPU can halt before
- * we poll. The CPU can even halt at the current PC as a result of
- * a software breakpoint being inserted by (a bug?) the application.
- */
- retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution);
- if (retval != ERROR_OK)
- return retval;
-
- target_call_event_callbacks(target, TARGET_EVENT_RESUME_END);
-
- return retval;
+int target_resume(struct target *target, int current, target_addr_t address,
+ int handle_breakpoints, int debug_execution)
+{
+ int retval;
+
+ /* We can't poll until after examine */
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ target_call_event_callbacks(target, TARGET_EVENT_RESUME_START);
+
+ /* note that resume *must* be asynchronous. The CPU can halt before
+ * we poll. The CPU can even halt at the current PC as a result of
+ * a software breakpoint being inserted by (a bug?) the application.
+ */
+ retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution);
+ if (retval != ERROR_OK)
+ return retval;
+
+ target_call_event_callbacks(target, TARGET_EVENT_RESUME_END);
+
+ return retval;
}
static int target_process_reset(struct command_context *cmd_ctx, enum target_reset_mode reset_mode)
{
- char buf[100];
- int retval;
- Jim_Nvp *n;
- n = Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode);
- if (n->name == NULL) {
- LOG_ERROR("invalid reset mode");
- return ERROR_FAIL;
- }
-
- struct target *target;
- for (target = all_targets; target; target = target->next)
- target_call_reset_callbacks(target, reset_mode);
-
- /* disable polling during reset to make reset event scripts
- * 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);
-
- sprintf(buf, "ocd_process_reset %s", n->name);
- retval = Jim_Eval(cmd_ctx->interp, buf);
-
- jtag_poll_set_enabled(save_poll);
-
- if (retval != JIM_OK) {
- Jim_MakeErrorMessage(cmd_ctx->interp);
- command_print(NULL, "%s\n", Jim_GetString(Jim_GetResult(cmd_ctx->interp), NULL));
- return ERROR_FAIL;
- }
-
- /* We want any events to be processed before the prompt */
- retval = target_call_timer_callbacks_now();
-
- for (target = all_targets; target; target = target->next) {
- target->type->check_reset(target);
- target->running_alg = false;
- }
-
- return retval;
+ char buf[100];
+ int retval;
+ Jim_Nvp *n;
+ n = Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode);
+ if (n->name == NULL) {
+ LOG_ERROR("invalid reset mode");
+ return ERROR_FAIL;
+ }
+
+ struct target *target;
+ for (target = all_targets; target; target = target->next)
+ target_call_reset_callbacks(target, reset_mode);
+
+ /* disable polling during reset to make reset event scripts
+ * 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);
+
+ sprintf(buf, "ocd_process_reset %s", n->name);
+ retval = Jim_Eval(cmd_ctx->interp, buf);
+
+ jtag_poll_set_enabled(save_poll);
+
+ if (retval != JIM_OK) {
+ Jim_MakeErrorMessage(cmd_ctx->interp);
+ command_print(NULL, "%s\n", Jim_GetString(Jim_GetResult(cmd_ctx->interp), NULL));
+ return ERROR_FAIL;
+ }
+
+ /* We want any events to be processed before the prompt */
+ retval = target_call_timer_callbacks_now();
+
+ for (target = all_targets; target; target = target->next) {
+ target->type->check_reset(target);
+ target->running_alg = false;
+ }
+
+ return retval;
}
static int identity_virt2phys(struct target *target,
- uint32_t virtual, uint32_t *physical)
+ target_addr_t virtual, target_addr_t *physical)
{
- *physical = virtual;
- return ERROR_OK;
+ *physical = virtual;
+ return ERROR_OK;
}
static int no_mmu(struct target *target, int *enabled)
{
- *enabled = 0;
- return ERROR_OK;
+ *enabled = 0;
+ return ERROR_OK;
}
static int default_examine(struct target *target)
{
- target_set_examined(target);
- return ERROR_OK;
+ target_set_examined(target);
+ return ERROR_OK;
}
/* no check by default */
static int default_check_reset(struct target *target)
{
- return ERROR_OK;
+ return ERROR_OK;
}
int target_examine_one(struct target *target)
{
- target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_START);
-
- int retval = target->type->examine(target);
- if (retval != ERROR_OK)
- return retval;
-
- target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_END);
-
- return ERROR_OK;
+ target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_START);
+
+ int retval = target->type->examine(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_END);
+
+ return ERROR_OK;
}
static int jtag_enable_callback(enum jtag_event event, void *priv)
{
- struct target *target = priv;
-
- if (event != JTAG_TAP_EVENT_ENABLE || !target->tap->enabled)
- return ERROR_OK;
-
- jtag_unregister_event_callback(jtag_enable_callback, target);
-
- return target_examine_one(target);
+ struct target *target = priv;
+
+ if (event != JTAG_TAP_EVENT_ENABLE || !target->tap->enabled)
+ return ERROR_OK;
+
+ jtag_unregister_event_callback(jtag_enable_callback, target);
+
+ return target_examine_one(target);
}
/* Targets that correctly implement init + examine, i.e.
@@ -718,41 +735,44 @@ static int jtag_enable_callback(enum jtag_event event, void *priv)
*/
int target_examine(void)
{
- int retval = ERROR_OK;
- struct target *target;
-
- for (target = all_targets; target; target = target->next) {
- /* defer examination, but don't skip it */
- if (!target->tap->enabled) {
- jtag_register_event_callback(jtag_enable_callback,
- target);
- continue;
- }
-
- retval = target_examine_one(target);
- if (retval != ERROR_OK)
- return retval;
- }
- return retval;
+ int retval = ERROR_OK;
+ struct target *target;
+
+ for (target = all_targets; target; target = target->next) {
+ /* defer examination, but don't skip it */
+ if (!target->tap->enabled) {
+ jtag_register_event_callback(jtag_enable_callback,
+ target);
+ continue;
+ }
+
+ if (target->defer_examine)
+ continue;
+
+ retval = target_examine_one(target);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+ return retval;
}
const char *target_type_name(struct target *target)
{
- return target->type->name;
+ return target->type->name;
}
static int target_soft_reset_halt(struct target *target)
{
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
- if (!target->type->soft_reset_halt) {
- LOG_ERROR("Target %s does not support soft_reset_halt",
- target_name(target));
- return ERROR_FAIL;
- }
- return target->type->soft_reset_halt(target);
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+ if (!target->type->soft_reset_halt) {
+ LOG_ERROR("Target %s does not support soft_reset_halt",
+ target_name(target));
+ return ERROR_FAIL;
+ }
+ return target->type->soft_reset_halt(target);
}
/**
@@ -767,32 +787,32 @@ static int target_soft_reset_halt(struct target *target)
* @param arch_info target-specific description of the algorithm.
*/
int target_run_algorithm(struct target *target,
- int num_mem_params, struct mem_param *mem_params,
- int num_reg_params, struct reg_param *reg_param,
- uint32_t entry_point, uint32_t exit_point,
- int timeout_ms, void *arch_info)
-{
- int retval = ERROR_FAIL;
-
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- goto done;
- }
- if (!target->type->run_algorithm) {
- LOG_ERROR("Target type '%s' does not support %s",
- target_type_name(target), __func__);
- goto done;
- }
-
- target->running_alg = true;
- retval = target->type->run_algorithm(target,
- num_mem_params, mem_params,
- num_reg_params, reg_param,
- entry_point, exit_point, timeout_ms, arch_info);
- target->running_alg = false;
-
+ int num_mem_params, struct mem_param *mem_params,
+ int num_reg_params, struct reg_param *reg_param,
+ uint32_t entry_point, uint32_t exit_point,
+ int timeout_ms, void *arch_info)
+{
+ int retval = ERROR_FAIL;
+
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ goto done;
+ }
+ if (!target->type->run_algorithm) {
+ LOG_ERROR("Target type '%s' does not support %s",
+ target_type_name(target), __func__);
+ goto done;
+ }
+
+ target->running_alg = true;
+ retval = target->type->run_algorithm(target,
+ num_mem_params, mem_params,
+ num_reg_params, reg_param,
+ entry_point, exit_point, timeout_ms, arch_info);
+ target->running_alg = false;
+
done:
- return retval;
+ return retval;
}
/**
@@ -803,35 +823,35 @@ int target_run_algorithm(struct target *target,
* @param arch_info target-specific description of the algorithm.
*/
int target_start_algorithm(struct target *target,
- int num_mem_params, struct mem_param *mem_params,
- int num_reg_params, struct reg_param *reg_params,
- uint32_t entry_point, uint32_t exit_point,
- void *arch_info)
-{
- int retval = ERROR_FAIL;
-
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- goto done;
- }
- if (!target->type->start_algorithm) {
- LOG_ERROR("Target type '%s' does not support %s",
- target_type_name(target), __func__);
- goto done;
- }
- if (target->running_alg) {
- LOG_ERROR("Target is already running an algorithm");
- goto done;
- }
-
- target->running_alg = true;
- retval = target->type->start_algorithm(target,
- num_mem_params, mem_params,
- num_reg_params, reg_params,
- entry_point, exit_point, arch_info);
-
+ int num_mem_params, struct mem_param *mem_params,
+ int num_reg_params, struct reg_param *reg_params,
+ uint32_t entry_point, uint32_t exit_point,
+ void *arch_info)
+{
+ int retval = ERROR_FAIL;
+
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ goto done;
+ }
+ if (!target->type->start_algorithm) {
+ LOG_ERROR("Target type '%s' does not support %s",
+ target_type_name(target), __func__);
+ goto done;
+ }
+ if (target->running_alg) {
+ LOG_ERROR("Target is already running an algorithm");
+ goto done;
+ }
+
+ target->running_alg = true;
+ retval = target->type->start_algorithm(target,
+ num_mem_params, mem_params,
+ num_reg_params, reg_params,
+ entry_point, exit_point, arch_info);
+
done:
- return retval;
+ return retval;
}
/**
@@ -841,32 +861,32 @@ int target_start_algorithm(struct target *target,
* @param arch_info target-specific description of the algorithm.
*/
int target_wait_algorithm(struct target *target,
- int num_mem_params, struct mem_param *mem_params,
- int num_reg_params, struct reg_param *reg_params,
- uint32_t exit_point, int timeout_ms,
- void *arch_info)
-{
- int retval = ERROR_FAIL;
-
- if (!target->type->wait_algorithm) {
- LOG_ERROR("Target type '%s' does not support %s",
- target_type_name(target), __func__);
- goto done;
- }
- if (!target->running_alg) {
- LOG_ERROR("Target is not running an algorithm");
- goto done;
- }
-
- retval = target->type->wait_algorithm(target,
- num_mem_params, mem_params,
- num_reg_params, reg_params,
- exit_point, timeout_ms, arch_info);
- if (retval != ERROR_TARGET_TIMEOUT)
- target->running_alg = false;
-
+ int num_mem_params, struct mem_param *mem_params,
+ int num_reg_params, struct reg_param *reg_params,
+ uint32_t exit_point, int timeout_ms,
+ void *arch_info)
+{
+ int retval = ERROR_FAIL;
+
+ if (!target->type->wait_algorithm) {
+ LOG_ERROR("Target type '%s' does not support %s",
+ target_type_name(target), __func__);
+ goto done;
+ }
+ if (!target->running_alg) {
+ LOG_ERROR("Target is not running an algorithm");
+ goto done;
+ }
+
+ retval = target->type->wait_algorithm(target,
+ num_mem_params, mem_params,
+ num_reg_params, reg_params,
+ exit_point, timeout_ms, arch_info);
+ if (retval != ERROR_TARGET_TIMEOUT)
+ target->running_alg = false;
+
done:
- return retval;
+ return retval;
}
/**
@@ -879,305 +899,347 @@ int target_wait_algorithm(struct target *target,
*/
int target_run_flash_async_algorithm(struct target *target,
- const uint8_t *buffer, uint32_t count, int block_size,
- int num_mem_params, struct mem_param *mem_params,
- int num_reg_params, struct reg_param *reg_params,
- uint32_t buffer_start, uint32_t buffer_size,
- uint32_t entry_point, uint32_t exit_point, void *arch_info)
-{
- int retval;
- int timeout = 0;
-
- const uint8_t *buffer_orig = buffer;
-
- /* Set up working area. First word is write pointer, second word is read pointer,
- * rest is fifo data area. */
- uint32_t wp_addr = buffer_start;
- uint32_t rp_addr = buffer_start + 4;
- uint32_t fifo_start_addr = buffer_start + 8;
- uint32_t fifo_end_addr = buffer_start + buffer_size;
-
- uint32_t wp = fifo_start_addr;
- uint32_t rp = fifo_start_addr;
-
- /* validate block_size is 2^n */
- assert(!block_size || !(block_size & (block_size - 1)));
-
- retval = target_write_u32(target, wp_addr, wp);
- if (retval != ERROR_OK)
- return retval;
- retval = target_write_u32(target, rp_addr, rp);
- if (retval != ERROR_OK)
- return retval;
-
- /* Start up algorithm on target and let it idle while writing the first chunk */
- retval = target_start_algorithm(target, num_mem_params, mem_params,
- num_reg_params, reg_params,
- entry_point,
- exit_point,
- arch_info);
-
- if (retval != ERROR_OK) {
- LOG_ERROR("error starting target flash write algorithm");
- return retval;
- }
-
- while (count > 0) {
-
- retval = target_read_u32(target, rp_addr, &rp);
- if (retval != ERROR_OK) {
- LOG_ERROR("failed to get read pointer");
- break;
- }
-
- LOG_DEBUG("offs 0x%zx count 0x%" PRIx32 " wp 0x%" PRIx32 " rp 0x%" PRIx32,
- (size_t) (buffer - buffer_orig), count, wp, rp);
-
- if (rp == 0) {
- LOG_ERROR("flash write algorithm aborted by target");
- retval = ERROR_FLASH_OPERATION_FAILED;
- break;
- }
-
- if (((rp - fifo_start_addr) & (block_size - 1)) || rp < fifo_start_addr || rp >= fifo_end_addr) {
- LOG_ERROR("corrupted fifo read pointer 0x%" PRIx32, rp);
- break;
- }
-
- /* Count the number of bytes available in the fifo without
- * crossing the wrap around. Make sure to not fill it completely,
- * because that would make wp == rp and that's the empty condition. */
- uint32_t thisrun_bytes;
- if (rp > wp)
- thisrun_bytes = rp - wp - block_size;
- else if (rp > fifo_start_addr)
- thisrun_bytes = fifo_end_addr - wp;
- else
- thisrun_bytes = fifo_end_addr - wp - block_size;
-
- if (thisrun_bytes == 0) {
- /* Throttle polling a bit if transfer is (much) faster than flash
- * programming. The exact delay shouldn't matter as long as it's
- * less than buffer size / flash speed. This is very unlikely to
- * run when using high latency connections such as USB. */
- alive_sleep(10);
-
- /* to stop an infinite loop on some targets check and increment a timeout
- * this issue was observed on a stellaris using the new ICDI interface */
- if (timeout++ >= 500) {
- LOG_ERROR("timeout waiting for algorithm, a target reset is recommended");
- return ERROR_FLASH_OPERATION_FAILED;
- }
- continue;
- }
-
- /* reset our timeout */
- timeout = 0;
-
- /* Limit to the amount of data we actually want to write */
- if (thisrun_bytes > count * block_size)
- thisrun_bytes = count * block_size;
-
- /* Write data to fifo */
- retval = target_write_buffer(target, wp, thisrun_bytes, buffer);
- if (retval != ERROR_OK)
- break;
-
- /* Update counters and wrap write pointer */
- buffer += thisrun_bytes;
- count -= thisrun_bytes / block_size;
- wp += thisrun_bytes;
- if (wp >= fifo_end_addr)
- wp = fifo_start_addr;
-
- /* Store updated write pointer to target */
- retval = target_write_u32(target, wp_addr, wp);
- if (retval != ERROR_OK)
- break;
- }
-
- if (retval != ERROR_OK) {
- /* abort flash write algorithm on target */
- target_write_u32(target, wp_addr, 0);
- }
-
- int retval2 = target_wait_algorithm(target, num_mem_params, mem_params,
- num_reg_params, reg_params,
- exit_point,
- 10000,
- arch_info);
-
- if (retval2 != ERROR_OK) {
- LOG_ERROR("error waiting for target flash write algorithm");
- retval = retval2;
- }
-
- return retval;
+ const uint8_t *buffer, uint32_t count, int block_size,
+ int num_mem_params, struct mem_param *mem_params,
+ int num_reg_params, struct reg_param *reg_params,
+ uint32_t buffer_start, uint32_t buffer_size,
+ uint32_t entry_point, uint32_t exit_point, void *arch_info)
+{
+ int retval;
+ int timeout = 0;
+
+ const uint8_t *buffer_orig = buffer;
+
+ /* Set up working area. First word is write pointer, second word is read pointer,
+ * rest is fifo data area. */
+ uint32_t wp_addr = buffer_start;
+ uint32_t rp_addr = buffer_start + 4;
+ uint32_t fifo_start_addr = buffer_start + 8;
+ uint32_t fifo_end_addr = buffer_start + buffer_size;
+
+ uint32_t wp = fifo_start_addr;
+ uint32_t rp = fifo_start_addr;
+
+ /* validate block_size is 2^n */
+ assert(!block_size || !(block_size & (block_size - 1)));
+
+ retval = target_write_u32(target, wp_addr, wp);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_write_u32(target, rp_addr, rp);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* Start up algorithm on target and let it idle while writing the first chunk */
+ retval = target_start_algorithm(target, num_mem_params, mem_params,
+ num_reg_params, reg_params,
+ entry_point,
+ exit_point,
+ arch_info);
+
+ if (retval != ERROR_OK) {
+ LOG_ERROR("error starting target flash write algorithm");
+ return retval;
+ }
+
+ while (count > 0) {
+
+ retval = target_read_u32(target, rp_addr, &rp);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("failed to get read pointer");
+ break;
+ }
+
+ LOG_DEBUG("offs 0x%zx count 0x%" PRIx32 " wp 0x%" PRIx32 " rp 0x%" PRIx32,
+ (size_t) (buffer - buffer_orig), count, wp, rp);
+
+ if (rp == 0) {
+ LOG_ERROR("flash write algorithm aborted by target");
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ break;
+ }
+
+ if (((rp - fifo_start_addr) & (block_size - 1)) || rp < fifo_start_addr || rp >= fifo_end_addr) {
+ LOG_ERROR("corrupted fifo read pointer 0x%" PRIx32, rp);
+ break;
+ }
+
+ /* Count the number of bytes available in the fifo without
+ * crossing the wrap around. Make sure to not fill it completely,
+ * because that would make wp == rp and that's the empty condition. */
+ uint32_t thisrun_bytes;
+ if (rp > wp)
+ thisrun_bytes = rp - wp - block_size;
+ else if (rp > fifo_start_addr)
+ thisrun_bytes = fifo_end_addr - wp;
+ else
+ thisrun_bytes = fifo_end_addr - wp - block_size;
+
+ if (thisrun_bytes == 0) {
+ /* Throttle polling a bit if transfer is (much) faster than flash
+ * programming. The exact delay shouldn't matter as long as it's
+ * less than buffer size / flash speed. This is very unlikely to
+ * run when using high latency connections such as USB. */
+ alive_sleep(10);
+
+ /* to stop an infinite loop on some targets check and increment a timeout
+ * this issue was observed on a stellaris using the new ICDI interface */
+ if (timeout++ >= 500) {
+ LOG_ERROR("timeout waiting for algorithm, a target reset is recommended");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ continue;
+ }
+
+ /* reset our timeout */
+ timeout = 0;
+
+ /* Limit to the amount of data we actually want to write */
+ if (thisrun_bytes > count * block_size)
+ thisrun_bytes = count * block_size;
+
+ /* Write data to fifo */
+ retval = target_write_buffer(target, wp, thisrun_bytes, buffer);
+ if (retval != ERROR_OK)
+ break;
+
+ /* Update counters and wrap write pointer */
+ buffer += thisrun_bytes;
+ count -= thisrun_bytes / block_size;
+ wp += thisrun_bytes;
+ if (wp >= fifo_end_addr)
+ wp = fifo_start_addr;
+
+ /* Store updated write pointer to target */
+ retval = target_write_u32(target, wp_addr, wp);
+ if (retval != ERROR_OK)
+ break;
+ }
+
+ if (retval != ERROR_OK) {
+ /* abort flash write algorithm on target */
+ target_write_u32(target, wp_addr, 0);
+ }
+
+ int retval2 = target_wait_algorithm(target, num_mem_params, mem_params,
+ num_reg_params, reg_params,
+ exit_point,
+ 10000,
+ arch_info);
+
+ if (retval2 != ERROR_OK) {
+ LOG_ERROR("error waiting for target flash write algorithm");
+ retval = retval2;
+ }
+
+ if (retval == ERROR_OK) {
+ /* check if algorithm set rp = 0 after fifo writer loop finished */
+ retval = target_read_u32(target, rp_addr, &rp);
+ if (retval == ERROR_OK && rp == 0) {
+ LOG_ERROR("flash write algorithm aborted by target");
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ }
+ }
+
+ return retval;
}
int target_read_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+ target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
{
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
- if (!target->type->read_memory) {
- LOG_ERROR("Target %s doesn't support read_memory", target_name(target));
- return ERROR_FAIL;
- }
- return target->type->read_memory(target, address, size, count, buffer);
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+ if (!target->type->read_memory) {
+ LOG_ERROR("Target %s doesn't support read_memory", target_name(target));
+ return ERROR_FAIL;
+ }
+ return target->type->read_memory(target, address, size, count, buffer);
}
int target_read_phys_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+ target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
{
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
- if (!target->type->read_phys_memory) {
- LOG_ERROR("Target %s doesn't support read_phys_memory", target_name(target));
- return ERROR_FAIL;
- }
- return target->type->read_phys_memory(target, address, size, count, buffer);
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+ if (!target->type->read_phys_memory) {
+ LOG_ERROR("Target %s doesn't support read_phys_memory", target_name(target));
+ return ERROR_FAIL;
+ }
+ return target->type->read_phys_memory(target, address, size, count, buffer);
}
int target_write_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
+ target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
- if (!target->type->write_memory) {
- LOG_ERROR("Target %s doesn't support write_memory", target_name(target));
- return ERROR_FAIL;
- }
- return target->type->write_memory(target, address, size, count, buffer);
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+ if (!target->type->write_memory) {
+ LOG_ERROR("Target %s doesn't support write_memory", target_name(target));
+ return ERROR_FAIL;
+ }
+ return target->type->write_memory(target, address, size, count, buffer);
}
int target_write_phys_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
+ target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
- if (!target->type->write_phys_memory) {
- LOG_ERROR("Target %s doesn't support write_phys_memory", target_name(target));
- return ERROR_FAIL;
- }
- return target->type->write_phys_memory(target, address, size, count, buffer);
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+ if (!target->type->write_phys_memory) {
+ LOG_ERROR("Target %s doesn't support write_phys_memory", target_name(target));
+ return ERROR_FAIL;
+ }
+ return target->type->write_phys_memory(target, address, size, count, buffer);
}
int target_add_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
+ struct breakpoint *breakpoint)
{
- if ((target->state != TARGET_HALTED) && (breakpoint->type != BKPT_HARD)) {
- LOG_WARNING("target %s is not halted", target_name(target));
- return ERROR_TARGET_NOT_HALTED;
- }
- return target->type->add_breakpoint(target, breakpoint);
+ if ((target->state != TARGET_HALTED) && (breakpoint->type != BKPT_HARD)) {
+#if BUILD_RISCV == 1
+ LOG_WARNING("target %s is not halted (add breakpoint)", target_name(target));
+#else
+ LOG_WARNING("target %s is not halted", target_name(target));
+#endif
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return target->type->add_breakpoint(target, breakpoint);
}
int target_add_context_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
+ struct breakpoint *breakpoint)
{
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target_name(target));
- return ERROR_TARGET_NOT_HALTED;
- }
- return target->type->add_context_breakpoint(target, breakpoint);
+ if (target->state != TARGET_HALTED) {
+#if BUILD_RISCV == 1
+ LOG_WARNING("target %s is not halted (add context breakpoint)", target_name(target));
+#else
+ LOG_WARNING("target %s is not halted", target_name(target));
+#endif
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return target->type->add_context_breakpoint(target, breakpoint);
}
int target_add_hybrid_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
+ struct breakpoint *breakpoint)
{
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target_name(target));
- return ERROR_TARGET_NOT_HALTED;
- }
- return target->type->add_hybrid_breakpoint(target, breakpoint);
+ if (target->state != TARGET_HALTED) {
+#if BUILD_RISCV == 1
+ LOG_WARNING("target %s is not halted (add hybrid breakpoint)", target_name(target));
+#else
+ LOG_WARNING("target %s is not halted", target_name(target));
+#endif
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return target->type->add_hybrid_breakpoint(target, breakpoint);
}
int target_remove_breakpoint(struct target *target,
- struct breakpoint *breakpoint)
+ struct breakpoint *breakpoint)
{
- return target->type->remove_breakpoint(target, breakpoint);
+ return target->type->remove_breakpoint(target, breakpoint);
}
int target_add_watchpoint(struct target *target,
- struct watchpoint *watchpoint)
+ struct watchpoint *watchpoint)
{
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target_name(target));
- return ERROR_TARGET_NOT_HALTED;
- }
- return target->type->add_watchpoint(target, watchpoint);
+ if (target->state != TARGET_HALTED) {
+#if BUILD_RISCV == 1
+ LOG_WARNING("target %s is not halted (add watchpoint)", target_name(target));
+#else
+ LOG_WARNING("target %s is not halted", target_name(target));
+#endif
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return target->type->add_watchpoint(target, watchpoint);
}
int target_remove_watchpoint(struct target *target,
- struct watchpoint *watchpoint)
+ struct watchpoint *watchpoint)
{
- return target->type->remove_watchpoint(target, watchpoint);
+ return target->type->remove_watchpoint(target, watchpoint);
}
int target_hit_watchpoint(struct target *target,
- struct watchpoint **hit_watchpoint)
+ struct watchpoint **hit_watchpoint)
{
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target->cmd_name);
- return ERROR_TARGET_NOT_HALTED;
- }
-
- if (target->type->hit_watchpoint == NULL) {
- /* For backward compatible, if hit_watchpoint is not implemented,
- * return ERROR_FAIL such that gdb_server will not take the nonsense
- * information. */
- return ERROR_FAIL;
- }
-
- return target->type->hit_watchpoint(target, hit_watchpoint);
+ if (target->state != TARGET_HALTED) {
+#if BUILD_RISCV == 1
+ LOG_WARNING("target %s is not halted (hit watchpoint)", target->cmd_name);
+#else
+ LOG_WARNING("target %s is not halted", target->cmd_name);
+#endif
+
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (target->type->hit_watchpoint == NULL) {
+ /* For backward compatible, if hit_watchpoint is not implemented,
+ * return ERROR_FAIL such that gdb_server will not take the nonsense
+ * information. */
+ return ERROR_FAIL;
+ }
+
+ return target->type->hit_watchpoint(target, hit_watchpoint);
}
int target_get_gdb_reg_list(struct target *target,
- struct reg **reg_list[], int *reg_list_size,
- enum target_register_class reg_class)
+ struct reg **reg_list[], int *reg_list_size,
+ enum target_register_class reg_class)
{
- return target->type->get_gdb_reg_list(target, reg_list, reg_list_size, reg_class);
+ return target->type->get_gdb_reg_list(target, reg_list, reg_list_size, reg_class);
}
int target_step(struct target *target,
- int current, uint32_t address, int handle_breakpoints)
+ int current, target_addr_t address, int handle_breakpoints)
{
- return target->type->step(target, current, address, handle_breakpoints);
+ return target->type->step(target, current, address, handle_breakpoints);
}
int target_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info)
{
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target->cmd_name);
- return ERROR_TARGET_NOT_HALTED;
- }
- return target->type->get_gdb_fileio_info(target, fileio_info);
+ if (target->state != TARGET_HALTED) {
+#if BUILD_RISCV == 1
+ LOG_WARNING("target %s is not halted (gdb fileio)", target->cmd_name);
+#else
+ LOG_WARNING("target %s is not halted", target->cmd_name);
+#endif
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return target->type->get_gdb_fileio_info(target, fileio_info);
}
int target_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c)
{
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target->cmd_name);
- return ERROR_TARGET_NOT_HALTED;
- }
- return target->type->gdb_fileio_end(target, retcode, fileio_errno, ctrl_c);
+ if (target->state != TARGET_HALTED) {
+#if BUILD_RISCV == 1
+ LOG_WARNING("target %s is not halted (gdb fileio end)", target->cmd_name);
+#else
+ LOG_WARNING("target %s is not halted", target->cmd_name);
+#endif
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return target->type->gdb_fileio_end(target, retcode, fileio_errno, ctrl_c);
}
int target_profiling(struct target *target, uint32_t *samples,
- uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
+ uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
{
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target->cmd_name);
- return ERROR_TARGET_NOT_HALTED;
- }
- return target->type->profiling(target, samples, max_num_samples,
- num_samples, seconds);
+ if (target->state != TARGET_HALTED) {
+#if BUILD_RISCV == 1
+ LOG_WARNING("target %s is not halted (profiling)", target->cmd_name);
+#else
+ LOG_WARNING("target %s is not halted", target->cmd_name);
+#endif
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return target->type->profiling(target, samples, max_num_samples,
+ num_samples, seconds);
}
/**
@@ -1186,689 +1248,705 @@ int target_profiling(struct target *target, uint32_t *samples,
*/
static void target_reset_examined(struct target *target)
{
- target->examined = false;
+ target->examined = false;
}
static int handle_target(void *priv);
static int target_init_one(struct command_context *cmd_ctx,
- struct target *target)
-{
- target_reset_examined(target);
-
- struct target_type *type = target->type;
- if (type->examine == NULL)
- type->examine = default_examine;
-
- if (type->check_reset == NULL)
- type->check_reset = default_check_reset;
-
- assert(type->init_target != NULL);
-
- int retval = type->init_target(cmd_ctx, target);
- if (ERROR_OK != retval) {
- LOG_ERROR("target '%s' init failed", target_name(target));
- return retval;
- }
-
- /* Sanity-check MMU support ... stub in what we must, to help
- * implement it in stages, but warn if we need to do so.
- */
- if (type->mmu) {
- if (type->virt2phys == NULL) {
- LOG_ERROR("type '%s' is missing virt2phys", type->name);
- type->virt2phys = identity_virt2phys;
- }
- } else {
- /* Make sure no-MMU targets all behave the same: make no
- * distinction between physical and virtual addresses, and
- * ensure that virt2phys() is always an identity mapping.
- */
- if (type->write_phys_memory || type->read_phys_memory || type->virt2phys)
- LOG_WARNING("type '%s' has bad MMU hooks", type->name);
-
- type->mmu = no_mmu;
- type->write_phys_memory = type->write_memory;
- type->read_phys_memory = type->read_memory;
- type->virt2phys = identity_virt2phys;
- }
-
- if (target->type->read_buffer == NULL)
- target->type->read_buffer = target_read_buffer_default;
-
- if (target->type->write_buffer == NULL)
- target->type->write_buffer = target_write_buffer_default;
-
- if (target->type->get_gdb_fileio_info == NULL)
- target->type->get_gdb_fileio_info = target_get_gdb_fileio_info_default;
-
- if (target->type->gdb_fileio_end == NULL)
- target->type->gdb_fileio_end = target_gdb_fileio_end_default;
-
- if (target->type->profiling == NULL)
- target->type->profiling = target_profiling_default;
-
- return ERROR_OK;
+ struct target *target)
+{
+ target_reset_examined(target);
+
+ struct target_type *type = target->type;
+ if (type->examine == NULL)
+ type->examine = default_examine;
+
+ if (type->check_reset == NULL)
+ type->check_reset = default_check_reset;
+
+ assert(type->init_target != NULL);
+
+ int retval = type->init_target(cmd_ctx, target);
+ if (ERROR_OK != retval) {
+ LOG_ERROR("target '%s' init failed", target_name(target));
+ return retval;
+ }
+
+ /* Sanity-check MMU support ... stub in what we must, to help
+ * implement it in stages, but warn if we need to do so.
+ */
+ if (type->mmu) {
+ if (type->virt2phys == NULL) {
+ LOG_ERROR("type '%s' is missing virt2phys", type->name);
+ type->virt2phys = identity_virt2phys;
+ }
+ } else {
+ /* Make sure no-MMU targets all behave the same: make no
+ * distinction between physical and virtual addresses, and
+ * ensure that virt2phys() is always an identity mapping.
+ */
+ if (type->write_phys_memory || type->read_phys_memory || type->virt2phys)
+ LOG_WARNING("type '%s' has bad MMU hooks", type->name);
+
+ type->mmu = no_mmu;
+ type->write_phys_memory = type->write_memory;
+ type->read_phys_memory = type->read_memory;
+ type->virt2phys = identity_virt2phys;
+ }
+
+ if (target->type->read_buffer == NULL)
+ target->type->read_buffer = target_read_buffer_default;
+
+ if (target->type->write_buffer == NULL)
+ target->type->write_buffer = target_write_buffer_default;
+
+ if (target->type->get_gdb_fileio_info == NULL)
+ target->type->get_gdb_fileio_info = target_get_gdb_fileio_info_default;
+
+ if (target->type->gdb_fileio_end == NULL)
+ target->type->gdb_fileio_end = target_gdb_fileio_end_default;
+
+ if (target->type->profiling == NULL)
+ target->type->profiling = target_profiling_default;
+
+ return ERROR_OK;
}
static int target_init(struct command_context *cmd_ctx)
{
- struct target *target;
- int retval;
-
- for (target = all_targets; target; target = target->next) {
- retval = target_init_one(cmd_ctx, target);
- if (ERROR_OK != retval)
- return retval;
- }
-
- if (!all_targets)
- return ERROR_OK;
-
- retval = target_register_user_commands(cmd_ctx);
- if (ERROR_OK != retval)
- return retval;
-
- retval = target_register_timer_callback(&handle_target,
- polling_interval, 1, cmd_ctx->interp);
- if (ERROR_OK != retval)
- return retval;
-
- return ERROR_OK;
+ struct target *target;
+ int retval;
+
+ for (target = all_targets; target; target = target->next) {
+ retval = target_init_one(cmd_ctx, target);
+ if (ERROR_OK != retval)
+ return retval;
+ }
+
+ if (!all_targets)
+ return ERROR_OK;
+
+ retval = target_register_user_commands(cmd_ctx);
+ if (ERROR_OK != retval)
+ return retval;
+
+ retval = target_register_timer_callback(&handle_target,
+ polling_interval, 1, cmd_ctx->interp);
+ if (ERROR_OK != retval)
+ return retval;
+
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_target_init_command)
{
- int retval;
-
- if (CMD_ARGC != 0)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- static bool target_initialized;
- if (target_initialized) {
- LOG_INFO("'target init' has already been called");
- return ERROR_OK;
- }
- target_initialized = true;
-
- retval = command_run_line(CMD_CTX, "init_targets");
- if (ERROR_OK != retval)
- return retval;
-
- retval = command_run_line(CMD_CTX, "init_target_events");
- if (ERROR_OK != retval)
- return retval;
-
- retval = command_run_line(CMD_CTX, "init_board");
- if (ERROR_OK != retval)
- return retval;
-
- LOG_DEBUG("Initializing targets...");
- return target_init(CMD_CTX);
+ int retval;
+
+ if (CMD_ARGC != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ static bool target_initialized;
+ if (target_initialized) {
+ LOG_INFO("'target init' has already been called");
+ return ERROR_OK;
+ }
+ target_initialized = true;
+
+ retval = command_run_line(CMD_CTX, "init_targets");
+ if (ERROR_OK != retval)
+ return retval;
+
+ retval = command_run_line(CMD_CTX, "init_target_events");
+ if (ERROR_OK != retval)
+ return retval;
+
+ retval = command_run_line(CMD_CTX, "init_board");
+ if (ERROR_OK != retval)
+ return retval;
+
+ LOG_DEBUG("Initializing targets...");
+ return target_init(CMD_CTX);
}
int target_register_event_callback(int (*callback)(struct target *target,
- enum target_event event, void *priv), void *priv)
-{
- struct target_event_callback **callbacks_p = &target_event_callbacks;
-
- if (callback == NULL)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- if (*callbacks_p) {
- while ((*callbacks_p)->next)
- callbacks_p = &((*callbacks_p)->next);
- callbacks_p = &((*callbacks_p)->next);
- }
-
- (*callbacks_p) = malloc(sizeof(struct target_event_callback));
- (*callbacks_p)->callback = callback;
- (*callbacks_p)->priv = priv;
- (*callbacks_p)->next = NULL;
-
- return ERROR_OK;
+ enum target_event event, void *priv), void *priv)
+{
+ struct target_event_callback **callbacks_p = &target_event_callbacks;
+
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (*callbacks_p) {
+ while ((*callbacks_p)->next)
+ callbacks_p = &((*callbacks_p)->next);
+ callbacks_p = &((*callbacks_p)->next);
+ }
+
+ (*callbacks_p) = malloc(sizeof(struct target_event_callback));
+ (*callbacks_p)->callback = callback;
+ (*callbacks_p)->priv = priv;
+ (*callbacks_p)->next = NULL;
+
+ return ERROR_OK;
}
int target_register_reset_callback(int (*callback)(struct target *target,
- enum target_reset_mode reset_mode, void *priv), void *priv)
-{
- struct target_reset_callback *entry;
-
- if (callback == NULL)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- entry = malloc(sizeof(struct target_reset_callback));
- if (entry == NULL) {
- LOG_ERROR("error allocating buffer for reset callback entry");
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- entry->callback = callback;
- entry->priv = priv;
- list_add(&entry->list, &target_reset_callback_list);
-
-
- return ERROR_OK;
+ enum target_reset_mode reset_mode, void *priv), void *priv)
+{
+ struct target_reset_callback *entry;
+
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ entry = malloc(sizeof(struct target_reset_callback));
+ if (entry == NULL) {
+ LOG_ERROR("error allocating buffer for reset callback entry");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ entry->callback = callback;
+ entry->priv = priv;
+ list_add(&entry->list, &target_reset_callback_list);
+
+
+ return ERROR_OK;
}
int target_register_trace_callback(int (*callback)(struct target *target,
- size_t len, uint8_t *data, void *priv), void *priv)
-{
- struct target_trace_callback *entry;
-
- if (callback == NULL)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- entry = malloc(sizeof(struct target_trace_callback));
- if (entry == NULL) {
- LOG_ERROR("error allocating buffer for trace callback entry");
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- entry->callback = callback;
- entry->priv = priv;
- list_add(&entry->list, &target_trace_callback_list);
-
-
- return ERROR_OK;
+ size_t len, uint8_t *data, void *priv), void *priv)
+{
+ struct target_trace_callback *entry;
+
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ entry = malloc(sizeof(struct target_trace_callback));
+ if (entry == NULL) {
+ LOG_ERROR("error allocating buffer for trace callback entry");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ entry->callback = callback;
+ entry->priv = priv;
+ list_add(&entry->list, &target_trace_callback_list);
+
+
+ return ERROR_OK;
}
int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int periodic, void *priv)
{
- struct target_timer_callback **callbacks_p = &target_timer_callbacks;
- struct timeval now;
-
- if (callback == NULL)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- if (*callbacks_p) {
- while ((*callbacks_p)->next)
- callbacks_p = &((*callbacks_p)->next);
- callbacks_p = &((*callbacks_p)->next);
- }
-
- (*callbacks_p) = malloc(sizeof(struct target_timer_callback));
- (*callbacks_p)->callback = callback;
- (*callbacks_p)->periodic = periodic;
- (*callbacks_p)->time_ms = time_ms;
- (*callbacks_p)->removed = false;
-
- gettimeofday(&now, NULL);
- (*callbacks_p)->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
- time_ms -= (time_ms % 1000);
- (*callbacks_p)->when.tv_sec = now.tv_sec + (time_ms / 1000);
- if ((*callbacks_p)->when.tv_usec > 1000000) {
- (*callbacks_p)->when.tv_usec = (*callbacks_p)->when.tv_usec - 1000000;
- (*callbacks_p)->when.tv_sec += 1;
- }
-
- (*callbacks_p)->priv = priv;
- (*callbacks_p)->next = NULL;
-
- return ERROR_OK;
+ struct target_timer_callback **callbacks_p = &target_timer_callbacks;
+ struct timeval now;
+
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (*callbacks_p) {
+ while ((*callbacks_p)->next)
+ callbacks_p = &((*callbacks_p)->next);
+ callbacks_p = &((*callbacks_p)->next);
+ }
+
+ (*callbacks_p) = malloc(sizeof(struct target_timer_callback));
+ (*callbacks_p)->callback = callback;
+ (*callbacks_p)->periodic = periodic;
+ (*callbacks_p)->time_ms = time_ms;
+ (*callbacks_p)->removed = false;
+
+ gettimeofday(&now, NULL);
+ (*callbacks_p)->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
+ time_ms -= (time_ms % 1000);
+ (*callbacks_p)->when.tv_sec = now.tv_sec + (time_ms / 1000);
+ if ((*callbacks_p)->when.tv_usec > 1000000) {
+ (*callbacks_p)->when.tv_usec = (*callbacks_p)->when.tv_usec - 1000000;
+ (*callbacks_p)->when.tv_sec += 1;
+ }
+
+ (*callbacks_p)->priv = priv;
+ (*callbacks_p)->next = NULL;
+
+ return ERROR_OK;
}
int target_unregister_event_callback(int (*callback)(struct target *target,
- enum target_event event, void *priv), void *priv)
-{
- struct target_event_callback **p = &target_event_callbacks;
- struct target_event_callback *c = target_event_callbacks;
-
- if (callback == NULL)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- while (c) {
- struct target_event_callback *next = c->next;
- if ((c->callback == callback) && (c->priv == priv)) {
- *p = next;
- free(c);
- return ERROR_OK;
- } else
- p = &(c->next);
- c = next;
- }
-
- return ERROR_OK;
+ enum target_event event, void *priv), void *priv)
+{
+ struct target_event_callback **p = &target_event_callbacks;
+ struct target_event_callback *c = target_event_callbacks;
+
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ while (c) {
+ struct target_event_callback *next = c->next;
+ if ((c->callback == callback) && (c->priv == priv)) {
+ *p = next;
+ free(c);
+ return ERROR_OK;
+ } else
+ p = &(c->next);
+ c = next;
+ }
+
+ return ERROR_OK;
}
int target_unregister_reset_callback(int (*callback)(struct target *target,
- enum target_reset_mode reset_mode, void *priv), void *priv)
-{
- struct target_reset_callback *entry;
-
- if (callback == NULL)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- list_for_each_entry(entry, &target_reset_callback_list, list) {
- if (entry->callback == callback && entry->priv == priv) {
- list_del(&entry->list);
- free(entry);
- break;
- }
- }
-
- return ERROR_OK;
+ enum target_reset_mode reset_mode, void *priv), void *priv)
+{
+ struct target_reset_callback *entry;
+
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ list_for_each_entry(entry, &target_reset_callback_list, list) {
+ if (entry->callback == callback && entry->priv == priv) {
+ list_del(&entry->list);
+ free(entry);
+ break;
+ }
+ }
+
+ return ERROR_OK;
}
int target_unregister_trace_callback(int (*callback)(struct target *target,
- size_t len, uint8_t *data, void *priv), void *priv)
-{
- struct target_trace_callback *entry;
-
- if (callback == NULL)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- list_for_each_entry(entry, &target_trace_callback_list, list) {
- if (entry->callback == callback && entry->priv == priv) {
- list_del(&entry->list);
- free(entry);
- break;
- }
- }
-
- return ERROR_OK;
+ size_t len, uint8_t *data, void *priv), void *priv)
+{
+ struct target_trace_callback *entry;
+
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ list_for_each_entry(entry, &target_trace_callback_list, list) {
+ if (entry->callback == callback && entry->priv == priv) {
+ list_del(&entry->list);
+ free(entry);
+ break;
+ }
+ }
+
+ return ERROR_OK;
}
int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
{
- if (callback == NULL)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- for (struct target_timer_callback *c = target_timer_callbacks;
- c; c = c->next) {
- if ((c->callback == callback) && (c->priv == priv)) {
- c->removed = true;
- return ERROR_OK;
- }
- }
-
- return ERROR_FAIL;
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ for (struct target_timer_callback *c = target_timer_callbacks;
+ c; c = c->next) {
+ if ((c->callback == callback) && (c->priv == priv)) {
+ c->removed = true;
+ return ERROR_OK;
+ }
+ }
+
+ return ERROR_FAIL;
}
int target_call_event_callbacks(struct target *target, enum target_event event)
{
- struct target_event_callback *callback = target_event_callbacks;
- struct target_event_callback *next_callback;
-
- if (event == TARGET_EVENT_HALTED) {
- /* execute early halted first */
- target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
- }
-
- LOG_DEBUG("target event %i (%s)", event,
- Jim_Nvp_value2name_simple(nvp_target_event, event)->name);
-
- target_handle_event(target, event);
-
- while (callback) {
- next_callback = callback->next;
- callback->callback(target, event, callback->priv);
- callback = next_callback;
- }
-
- return ERROR_OK;
+ struct target_event_callback *callback = target_event_callbacks;
+ struct target_event_callback *next_callback;
+
+ if (event == TARGET_EVENT_HALTED) {
+ /* execute early halted first */
+ target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
+ }
+
+ LOG_DEBUG("target event %i (%s)", event,
+ Jim_Nvp_value2name_simple(nvp_target_event, event)->name);
+
+ target_handle_event(target, event);
+
+ while (callback) {
+ next_callback = callback->next;
+ callback->callback(target, event, callback->priv);
+ callback = next_callback;
+ }
+
+ return ERROR_OK;
}
int target_call_reset_callbacks(struct target *target, enum target_reset_mode reset_mode)
{
- struct target_reset_callback *callback;
-
- LOG_DEBUG("target reset %i (%s)", reset_mode,
- Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode)->name);
-
- list_for_each_entry(callback, &target_reset_callback_list, list)
- callback->callback(target, reset_mode, callback->priv);
-
- return ERROR_OK;
+ struct target_reset_callback *callback;
+
+ LOG_DEBUG("target reset %i (%s)", reset_mode,
+ Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode)->name);
+
+ list_for_each_entry(callback, &target_reset_callback_list, list)
+ callback->callback(target, reset_mode, callback->priv);
+
+ return ERROR_OK;
}
int target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data)
{
- struct target_trace_callback *callback;
-
- list_for_each_entry(callback, &target_trace_callback_list, list)
- callback->callback(target, len, data, callback->priv);
-
- return ERROR_OK;
+ struct target_trace_callback *callback;
+
+ list_for_each_entry(callback, &target_trace_callback_list, list)
+ callback->callback(target, len, data, callback->priv);
+
+ return ERROR_OK;
}
static int target_timer_callback_periodic_restart(
- struct target_timer_callback *cb, struct timeval *now)
+ struct target_timer_callback *cb, struct timeval *now)
{
- int time_ms = cb->time_ms;
- cb->when.tv_usec = now->tv_usec + (time_ms % 1000) * 1000;
- time_ms -= (time_ms % 1000);
- cb->when.tv_sec = now->tv_sec + time_ms / 1000;
- if (cb->when.tv_usec > 1000000) {
- cb->when.tv_usec = cb->when.tv_usec - 1000000;
- cb->when.tv_sec += 1;
- }
- return ERROR_OK;
+ int time_ms = cb->time_ms;
+ cb->when.tv_usec = now->tv_usec + (time_ms % 1000) * 1000;
+ time_ms -= (time_ms % 1000);
+ cb->when.tv_sec = now->tv_sec + time_ms / 1000;
+ if (cb->when.tv_usec > 1000000) {
+ cb->when.tv_usec = cb->when.tv_usec - 1000000;
+ cb->when.tv_sec += 1;
+ }
+ return ERROR_OK;
}
static int target_call_timer_callback(struct target_timer_callback *cb,
- struct timeval *now)
+ struct timeval *now)
{
- cb->callback(cb->priv);
-
- if (cb->periodic)
- return target_timer_callback_periodic_restart(cb, now);
-
- return target_unregister_timer_callback(cb->callback, cb->priv);
+ cb->callback(cb->priv);
+
+ if (cb->periodic)
+ return target_timer_callback_periodic_restart(cb, now);
+
+ return target_unregister_timer_callback(cb->callback, cb->priv);
}
static int target_call_timer_callbacks_check_time(int checktime)
{
- static bool callback_processing;
-
- /* Do not allow nesting */
- if (callback_processing)
- return ERROR_OK;
-
- callback_processing = true;
-
- keep_alive();
-
- struct timeval now;
- gettimeofday(&now, NULL);
-
- /* Store an address of the place containing a pointer to the
- * next item; initially, that's a standalone "root of the
- * list" variable. */
- struct target_timer_callback **callback = &target_timer_callbacks;
- while (*callback) {
- if ((*callback)->removed) {
- struct target_timer_callback *p = *callback;
- *callback = (*callback)->next;
- free(p);
- continue;
- }
-
- bool call_it = (*callback)->callback &&
- ((!checktime && (*callback)->periodic) ||
- now.tv_sec > (*callback)->when.tv_sec ||
- (now.tv_sec == (*callback)->when.tv_sec &&
- now.tv_usec >= (*callback)->when.tv_usec));
-
- if (call_it)
- target_call_timer_callback(*callback, &now);
-
- callback = &(*callback)->next;
- }
-
- callback_processing = false;
- return ERROR_OK;
+ static bool callback_processing;
+
+ /* Do not allow nesting */
+ if (callback_processing)
+ return ERROR_OK;
+
+ callback_processing = true;
+
+ keep_alive();
+
+ struct timeval now;
+ gettimeofday(&now, NULL);
+
+ /* Store an address of the place containing a pointer to the
+ * next item; initially, that's a standalone "root of the
+ * list" variable. */
+ struct target_timer_callback **callback = &target_timer_callbacks;
+ while (*callback) {
+ if ((*callback)->removed) {
+ struct target_timer_callback *p = *callback;
+ *callback = (*callback)->next;
+ free(p);
+ continue;
+ }
+
+ bool call_it = (*callback)->callback &&
+ ((!checktime && (*callback)->periodic) ||
+ now.tv_sec > (*callback)->when.tv_sec ||
+ (now.tv_sec == (*callback)->when.tv_sec &&
+ now.tv_usec >= (*callback)->when.tv_usec));
+
+ if (call_it)
+ target_call_timer_callback(*callback, &now);
+
+ callback = &(*callback)->next;
+ }
+
+ callback_processing = false;
+ return ERROR_OK;
}
int target_call_timer_callbacks(void)
{
- return target_call_timer_callbacks_check_time(1);
+ return target_call_timer_callbacks_check_time(1);
}
/* invoke periodic callbacks immediately */
int target_call_timer_callbacks_now(void)
{
- return target_call_timer_callbacks_check_time(0);
+ return target_call_timer_callbacks_check_time(0);
}
/* Prints the working area layout for debug purposes */
static void print_wa_layout(struct target *target)
{
- struct working_area *c = target->working_areas;
-
- while (c) {
- LOG_DEBUG("%c%c 0x%08"PRIx32"-0x%08"PRIx32" (%"PRIu32" bytes)",
- c->backup ? 'b' : ' ', c->free ? ' ' : '*',
- c->address, c->address + c->size - 1, c->size);
- c = c->next;
- }
+ struct working_area *c = target->working_areas;
+
+ while (c) {
+ LOG_DEBUG("%c%c " TARGET_ADDR_FMT "-" TARGET_ADDR_FMT " (%" PRIu32 " bytes)",
+ c->backup ? 'b' : ' ', c->free ? ' ' : '*',
+ c->address, c->address + c->size - 1, c->size);
+ c = c->next;
+ }
}
/* Reduce area to size bytes, create a new free area from the remaining bytes, if any. */
static void target_split_working_area(struct working_area *area, uint32_t size)
{
- assert(area->free); /* Shouldn't split an allocated area */
- assert(size <= area->size); /* Caller should guarantee this */
-
- /* Split only if not already the right size */
- if (size < area->size) {
- struct working_area *new_wa = malloc(sizeof(*new_wa));
-
- if (new_wa == NULL)
- return;
-
- new_wa->next = area->next;
- new_wa->size = area->size - size;
- new_wa->address = area->address + size;
- new_wa->backup = NULL;
- new_wa->user = NULL;
- new_wa->free = true;
-
- area->next = new_wa;
- area->size = size;
-
- /* If backup memory was allocated to this area, it has the wrong size
- * now so free it and it will be reallocated if/when needed */
- if (area->backup) {
- free(area->backup);
- area->backup = NULL;
- }
- }
+ assert(area->free); /* Shouldn't split an allocated area */
+ assert(size <= area->size); /* Caller should guarantee this */
+
+ /* Split only if not already the right size */
+ if (size < area->size) {
+ struct working_area *new_wa = malloc(sizeof(*new_wa));
+
+ if (new_wa == NULL)
+ return;
+
+ new_wa->next = area->next;
+ new_wa->size = area->size - size;
+ new_wa->address = area->address + size;
+ new_wa->backup = NULL;
+ new_wa->user = NULL;
+ new_wa->free = true;
+
+ area->next = new_wa;
+ area->size = size;
+
+ /* If backup memory was allocated to this area, it has the wrong size
+ * now so free it and it will be reallocated if/when needed */
+ if (area->backup) {
+ free(area->backup);
+ area->backup = NULL;
+ }
+ }
}
/* Merge all adjacent free areas into one */
static void target_merge_working_areas(struct target *target)
{
- struct working_area *c = target->working_areas;
-
- while (c && c->next) {
- assert(c->next->address == c->address + c->size); /* This is an invariant */
-
- /* Find two adjacent free areas */
- if (c->free && c->next->free) {
- /* Merge the last into the first */
- c->size += c->next->size;
-
- /* Remove the last */
- struct working_area *to_be_freed = c->next;
- c->next = c->next->next;
- if (to_be_freed->backup)
- free(to_be_freed->backup);
- free(to_be_freed);
-
- /* If backup memory was allocated to the remaining area, it's has
- * the wrong size now */
- if (c->backup) {
- free(c->backup);
- c->backup = NULL;
- }
- } else {
- c = c->next;
- }
- }
+ struct working_area *c = target->working_areas;
+
+ while (c && c->next) {
+ assert(c->next->address == c->address + c->size); /* This is an invariant */
+
+ /* Find two adjacent free areas */
+ if (c->free && c->next->free) {
+ /* Merge the last into the first */
+ c->size += c->next->size;
+
+ /* Remove the last */
+ struct working_area *to_be_freed = c->next;
+ c->next = c->next->next;
+ if (to_be_freed->backup)
+ free(to_be_freed->backup);
+ free(to_be_freed);
+
+ /* If backup memory was allocated to the remaining area, it's has
+ * the wrong size now */
+ if (c->backup) {
+ free(c->backup);
+ c->backup = NULL;
+ }
+ } else {
+ c = c->next;
+ }
+ }
}
int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
{
- /* Reevaluate working area address based on MMU state*/
- if (target->working_areas == NULL) {
- int retval;
- int enabled;
-
- retval = target->type->mmu(target, &enabled);
- if (retval != ERROR_OK)
- return retval;
-
- if (!enabled) {
- if (target->working_area_phys_spec) {
- LOG_DEBUG("MMU disabled, using physical "
- "address for working memory 0x%08"PRIx32,
- target->working_area_phys);
- target->working_area = target->working_area_phys;
- } else {
- LOG_ERROR("No working memory available. "
- "Specify -work-area-phys to target.");
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
- } else {
- if (target->working_area_virt_spec) {
- LOG_DEBUG("MMU enabled, using virtual "
- "address for working memory 0x%08"PRIx32,
- target->working_area_virt);
- target->working_area = target->working_area_virt;
- } else {
- LOG_ERROR("No working memory available. "
- "Specify -work-area-virt to target.");
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
- }
-
- /* Set up initial working area on first call */
- 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->address = target->working_area;
- new_wa->backup = NULL;
- new_wa->user = NULL;
- new_wa->free = true;
- }
-
- target->working_areas = new_wa;
- }
-
- /* only allocate multiples of 4 byte */
- if (size % 4)
- size = (size + 3) & (~3UL);
-
- struct working_area *c = target->working_areas;
-
- /* Find the first large enough working area */
- while (c) {
- if (c->free && c->size >= size)
- break;
- c = c->next;
- }
-
- if (c == NULL)
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-
- /* Split the working area into the requested size */
- target_split_working_area(c, size);
-
- LOG_DEBUG("allocated new working area of %"PRIu32" bytes at address 0x%08"PRIx32, size, c->address);
-
- if (target->backup_working_area) {
- if (c->backup == NULL) {
- c->backup = malloc(c->size);
- if (c->backup == NULL)
- return ERROR_FAIL;
- }
-
- int retval = target_read_memory(target, c->address, 4, c->size / 4, c->backup);
- if (retval != ERROR_OK)
- return retval;
- }
-
- /* mark as used, and return the new (reused) area */
- c->free = false;
- *area = c;
-
- /* user pointer */
- c->user = area;
-
- print_wa_layout(target);
-
- return ERROR_OK;
+ /* Reevaluate working area address based on MMU state*/
+ if (target->working_areas == NULL) {
+ int retval;
+ int enabled;
+
+ retval = target->type->mmu(target, &enabled);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (!enabled) {
+ if (target->working_area_phys_spec) {
+ LOG_DEBUG("MMU disabled, using physical "
+ "address for working memory " TARGET_ADDR_FMT,
+ target->working_area_phys);
+ target->working_area = target->working_area_phys;
+ } else {
+ LOG_ERROR("No working memory available. "
+ "Specify -work-area-phys to target.");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ } else {
+ if (target->working_area_virt_spec) {
+ LOG_DEBUG("MMU enabled, using virtual "
+ "address for working memory " TARGET_ADDR_FMT,
+ target->working_area_virt);
+ target->working_area = target->working_area_virt;
+ } else {
+ LOG_ERROR("No working memory available. "
+ "Specify -work-area-virt to target.");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ }
+
+ /* Set up initial working area on first call */
+ 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->address = target->working_area;
+ new_wa->backup = NULL;
+ new_wa->user = NULL;
+ new_wa->free = true;
+ }
+
+ target->working_areas = new_wa;
+ }
+
+ /* only allocate multiples of 4 byte */
+ if (size % 4)
+ size = (size + 3) & (~3UL);
+
+ struct working_area *c = target->working_areas;
+
+ /* Find the first large enough working area */
+ while (c) {
+ if (c->free && c->size >= size)
+ break;
+ c = c->next;
+ }
+
+ if (c == NULL)
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+
+ /* Split the working area into the requested size */
+ target_split_working_area(c, size);
+
+ LOG_DEBUG("allocated new working area of %" PRIu32 " bytes at address " TARGET_ADDR_FMT,
+ size, c->address);
+
+ if (target->backup_working_area) {
+ if (c->backup == NULL) {
+ c->backup = malloc(c->size);
+ if (c->backup == NULL)
+ return ERROR_FAIL;
+ }
+
+ int retval = target_read_memory(target, c->address, 4, c->size / 4, c->backup);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ /* mark as used, and return the new (reused) area */
+ c->free = false;
+ *area = c;
+
+ /* user pointer */
+ c->user = area;
+
+ print_wa_layout(target);
+
+ return ERROR_OK;
}
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
{
- int retval;
-
- retval = target_alloc_working_area_try(target, size, area);
- if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
- LOG_WARNING("not enough working area available(requested %"PRIu32")", size);
- return retval;
-
+ int retval;
+
+ retval = target_alloc_working_area_try(target, size, area);
+ if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
+ LOG_WARNING("not enough working area available(requested %"PRIu32")", size);
+ return retval;
+
}
static int target_restore_working_area(struct target *target, struct working_area *area)
{
- int retval = ERROR_OK;
-
- if (target->backup_working_area && area->backup != NULL) {
- retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup);
- if (retval != ERROR_OK)
- LOG_ERROR("failed to restore %"PRIu32" bytes of working area at address 0x%08"PRIx32,
- area->size, area->address);
- }
-
- return retval;
+ int retval = ERROR_OK;
+
+ if (target->backup_working_area && area->backup != NULL) {
+ retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup);
+ if (retval != ERROR_OK)
+ LOG_ERROR("failed to restore %" PRIu32 " bytes of working area at address " TARGET_ADDR_FMT,
+ area->size, area->address);
+ }
+
+ return retval;
}
/* Restore the area's backup memory, if any, and return the area to the allocation pool */
static int target_free_working_area_restore(struct target *target, struct working_area *area, int restore)
{
- int retval = ERROR_OK;
-
- if (area->free)
- return retval;
-
- if (restore) {
- retval = target_restore_working_area(target, area);
- /* REVISIT: Perhaps the area should be freed even if restoring fails. */
- if (retval != ERROR_OK)
- return retval;
- }
-
- area->free = true;
-
- LOG_DEBUG("freed %"PRIu32" bytes of working area at address 0x%08"PRIx32,
- area->size, area->address);
-
- /* mark user pointer invalid */
- /* TODO: Is this really safe? It points to some previous caller's memory.
- * How could we know that the area pointer is still in that place and not
- * some other vital data? What's the purpose of this, anyway? */
- *area->user = NULL;
- area->user = NULL;
-
- target_merge_working_areas(target);
-
- print_wa_layout(target);
-
- return retval;
+ int retval = ERROR_OK;
+
+ if (area->free)
+ return retval;
+
+ if (restore) {
+ retval = target_restore_working_area(target, area);
+ /* REVISIT: Perhaps the area should be freed even if restoring fails. */
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ area->free = true;
+
+ LOG_DEBUG("freed %" PRIu32 " bytes of working area at address " TARGET_ADDR_FMT,
+ area->size, area->address);
+
+ /* mark user pointer invalid */
+ /* TODO: Is this really safe? It points to some previous caller's memory.
+ * How could we know that the area pointer is still in that place and not
+ * some other vital data? What's the purpose of this, anyway? */
+ *area->user = NULL;
+ area->user = NULL;
+
+ target_merge_working_areas(target);
+
+ print_wa_layout(target);
+
+ return retval;
}
int target_free_working_area(struct target *target, struct working_area *area)
{
- return target_free_working_area_restore(target, area, 1);
+ return target_free_working_area_restore(target, area, 1);
+}
+
+static void target_destroy(struct target *target)
+{
+ if (target->type->deinit_target)
+ target->type->deinit_target(target);
+
+ free(target->type);
+ free(target->trace_info);
+ free(target->cmd_name);
+ free(target);
}
void target_quit(void)
{
- struct target_event_callback *pe = target_event_callbacks;
- while (pe) {
- struct target_event_callback *t = pe->next;
- free(pe);
- pe = t;
- }
- target_event_callbacks = NULL;
-
- struct target_timer_callback *pt = target_timer_callbacks;
- while (pt) {
- struct target_timer_callback *t = pt->next;
- free(pt);
- pt = t;
- }
- target_timer_callbacks = NULL;
-
- for (struct target *target = all_targets;
- target; target = target->next) {
- if (target->type->deinit_target)
- target->type->deinit_target(target);
- }
+ struct target_event_callback *pe = target_event_callbacks;
+ while (pe) {
+ struct target_event_callback *t = pe->next;
+ free(pe);
+ pe = t;
+ }
+ target_event_callbacks = NULL;
+
+ struct target_timer_callback *pt = target_timer_callbacks;
+ while (pt) {
+ struct target_timer_callback *t = pt->next;
+ free(pt);
+ pt = t;
+ }
+ target_timer_callbacks = NULL;
+
+ for (struct target *target = all_targets; target;) {
+ struct target *tmp;
+
+ tmp = target->next;
+ target_destroy(target);
+ target = tmp;
+ }
+
+ all_targets = NULL;
}
/* free resources and restore memory, if restoring memory fails,
@@ -1876,548 +1954,633 @@ void target_quit(void)
*/
static void target_free_all_working_areas_restore(struct target *target, int restore)
{
- struct working_area *c = target->working_areas;
-
- LOG_DEBUG("freeing all working areas");
-
- /* Loop through all areas, restoring the allocated ones and marking them as free */
- while (c) {
- if (!c->free) {
- if (restore)
- target_restore_working_area(target, c);
- c->free = true;
- *c->user = NULL; /* Same as above */
- c->user = NULL;
- }
- c = c->next;
- }
-
- /* Run a merge pass to combine all areas into one */
- target_merge_working_areas(target);
-
- print_wa_layout(target);
+ struct working_area *c = target->working_areas;
+
+ LOG_DEBUG("freeing all working areas");
+
+ /* Loop through all areas, restoring the allocated ones and marking them as free */
+ while (c) {
+ if (!c->free) {
+ if (restore)
+ target_restore_working_area(target, c);
+ c->free = true;
+ *c->user = NULL; /* Same as above */
+ c->user = NULL;
+ }
+ c = c->next;
+ }
+
+ /* Run a merge pass to combine all areas into one */
+ target_merge_working_areas(target);
+
+ print_wa_layout(target);
}
void target_free_all_working_areas(struct target *target)
{
- target_free_all_working_areas_restore(target, 1);
+ target_free_all_working_areas_restore(target, 1);
}
/* Find the largest number of bytes that can be allocated */
uint32_t target_get_working_area_avail(struct target *target)
{
- struct working_area *c = target->working_areas;
- uint32_t max_size = 0;
-
- if (c == NULL)
- return target->working_area_size;
-
- while (c) {
- if (c->free && max_size < c->size)
- max_size = c->size;
-
- c = c->next;
- }
-
- return max_size;
+ struct working_area *c = target->working_areas;
+ uint32_t max_size = 0;
+
+ if (c == NULL)
+ return target->working_area_size;
+
+ while (c) {
+ if (c->free && max_size < c->size)
+ max_size = c->size;
+
+ c = c->next;
+ }
+
+ return max_size;
}
int target_arch_state(struct target *target)
{
- int retval;
- if (target == NULL) {
- LOG_USER("No target has been configured");
- return ERROR_OK;
- }
-
- LOG_USER("%s: target state: %s", target_name(target),
- target_state_name(target));
-
- if (target->state != TARGET_HALTED)
- return ERROR_OK;
+ int retval;
+ if (target == NULL) {
+#if BUILD_RISCV == 1
+ LOG_USER("No target has been configured");
+#else
+ LOG_WARNING("No target has been configured");
+#endif
+
+ return ERROR_OK;
+ }
- retval = target->type->arch_state(target);
- return retval;
+ if (target->state != TARGET_HALTED)
+ return ERROR_OK;
+
+ retval = target->type->arch_state(target);
+ return retval;
}
static int target_get_gdb_fileio_info_default(struct target *target,
- struct gdb_fileio_info *fileio_info)
+ struct gdb_fileio_info *fileio_info)
{
- /* If target does not support semi-hosting function, target
- has no need to provide .get_gdb_fileio_info callback.
- It just return ERROR_FAIL and gdb_server will return "Txx"
- as target halted every time. */
- return ERROR_FAIL;
+ /* If target does not support semi-hosting function, target
+ has no need to provide .get_gdb_fileio_info callback.
+ It just return ERROR_FAIL and gdb_server will return "Txx"
+ as target halted every time. */
+ return ERROR_FAIL;
}
static int target_gdb_fileio_end_default(struct target *target,
- int retcode, int fileio_errno, bool ctrl_c)
+ int retcode, int fileio_errno, bool ctrl_c)
{
- return ERROR_OK;
+ return ERROR_OK;
}
static int target_profiling_default(struct target *target, uint32_t *samples,
- uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
-{
- struct timeval timeout, now;
-
- gettimeofday(&timeout, NULL);
- timeval_add_time(&timeout, seconds, 0);
-
- LOG_INFO("Starting profiling. Halting and resuming the"
- " target as often as we can...");
-
- uint32_t sample_count = 0;
- /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */
- struct reg *reg = register_get_by_name(target->reg_cache, "pc", 1);
-
- int retval = ERROR_OK;
- for (;;) {
- target_poll(target);
- if (target->state == TARGET_HALTED) {
- uint32_t t = buf_get_u32(reg->value, 0, 32);
- samples[sample_count++] = t;
- /* current pc, addr = 0, do not handle breakpoints, not debugging */
- retval = target_resume(target, 1, 0, 0, 0);
- target_poll(target);
- alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
- } else if (target->state == TARGET_RUNNING) {
- /* We want to quickly sample the PC. */
- retval = target_halt(target);
- } else {
- LOG_INFO("Target not halted or running");
- retval = ERROR_OK;
- break;
- }
-
- if (retval != ERROR_OK)
- break;
-
- gettimeofday(&now, NULL);
- if ((sample_count >= max_num_samples) ||
- ((now.tv_sec >= timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec))) {
- LOG_INFO("Profiling completed. %" PRIu32 " samples.", sample_count);
- break;
- }
- }
-
- *num_samples = sample_count;
- return retval;
+ uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
+{
+ struct timeval timeout, now;
+
+ gettimeofday(&timeout, NULL);
+ timeval_add_time(&timeout, seconds, 0);
+
+ LOG_INFO("Starting profiling. Halting and resuming the"
+ " target as often as we can...");
+
+ uint32_t sample_count = 0;
+ /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */
+ struct reg *reg = register_get_by_name(target->reg_cache, "pc", 1);
+
+ int retval = ERROR_OK;
+ for (;;) {
+ target_poll(target);
+ if (target->state == TARGET_HALTED) {
+ uint32_t t = buf_get_u32(reg->value, 0, 32);
+ samples[sample_count++] = t;
+ /* current pc, addr = 0, do not handle breakpoints, not debugging */
+ retval = target_resume(target, 1, 0, 0, 0);
+ target_poll(target);
+ alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
+ } else if (target->state == TARGET_RUNNING) {
+ /* We want to quickly sample the PC. */
+ retval = target_halt(target);
+ } else {
+ LOG_INFO("Target not halted or running");
+ retval = ERROR_OK;
+ break;
+ }
+
+ if (retval != ERROR_OK)
+ break;
+
+ gettimeofday(&now, NULL);
+ if ((sample_count >= max_num_samples) ||
+ ((now.tv_sec >= timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec))) {
+ LOG_INFO("Profiling completed. %" PRIu32 " samples.", sample_count);
+ break;
+ }
+ }
+
+ *num_samples = sample_count;
+ return retval;
}
/* Single aligned words are guaranteed to use 16 or 32 bit access
* mode respectively, otherwise data is handled as quickly as
* possible
*/
-int target_write_buffer(struct target *target, uint32_t address, uint32_t size, const uint8_t *buffer)
-{
- LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
- (int)size, (unsigned)address);
-
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- if (size == 0)
- return ERROR_OK;
-
- if ((address + size - 1) < address) {
- /* GDB can request this when e.g. PC is 0xfffffffc*/
- LOG_ERROR("address + size wrapped(0x%08x, 0x%08x)",
- (unsigned)address,
- (unsigned)size);
- return ERROR_FAIL;
- }
-
- return target->type->write_buffer(target, address, size, buffer);
-}
-
-static int target_write_buffer_default(struct target *target, uint32_t address, uint32_t count, const uint8_t *buffer)
-{
- uint32_t size;
-
- /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
- * will have something to do with the size we leave to it. */
- for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
- if (address & size) {
- int retval = target_write_memory(target, address, size, 1, buffer);
- if (retval != ERROR_OK)
- return retval;
- address += size;
- count -= size;
- buffer += size;
- }
- }
-
- /* Write the data with as large access size as possible. */
- for (; size > 0; size /= 2) {
- uint32_t aligned = count - count % size;
- if (aligned > 0) {
- int retval = target_write_memory(target, address, size, aligned / size, buffer);
- if (retval != ERROR_OK)
- return retval;
- address += aligned;
- count -= aligned;
- buffer += aligned;
- }
- }
-
- return ERROR_OK;
+int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
+{
+ LOG_DEBUG("writing buffer of %" PRIi32 " byte at " TARGET_ADDR_FMT,
+ size, address);
+
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ if (size == 0)
+ return ERROR_OK;
+
+ if ((address + size - 1) < address) {
+ /* GDB can request this when e.g. PC is 0xfffffffc */
+ LOG_ERROR("address + size wrapped (" TARGET_ADDR_FMT ", 0x%08" PRIx32 ")",
+ address,
+ size);
+ return ERROR_FAIL;
+ }
+
+ return target->type->write_buffer(target, address, size, buffer);
+}
+
+static int target_write_buffer_default(struct target *target,
+ target_addr_t address, uint32_t count, const uint8_t *buffer)
+{
+ uint32_t size;
+
+ /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
+ * will have something to do with the size we leave to it. */
+ for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
+ if (address & size) {
+ int retval = target_write_memory(target, address, size, 1, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += size;
+ count -= size;
+ buffer += size;
+ }
+ }
+
+ /* Write the data with as large access size as possible. */
+ for (; size > 0; size /= 2) {
+ uint32_t aligned = count - count % size;
+ if (aligned > 0) {
+ int retval = target_write_memory(target, address, size, aligned / size, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += aligned;
+ count -= aligned;
+ buffer += aligned;
+ }
+ }
+
+ return ERROR_OK;
}
/* Single aligned words are guaranteed to use 16 or 32 bit access
* mode respectively, otherwise data is handled as quickly as
* possible
*/
-int target_read_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
-{
- LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
- (int)size, (unsigned)address);
-
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- if (size == 0)
- return ERROR_OK;
-
- if ((address + size - 1) < address) {
- /* GDB can request this when e.g. PC is 0xfffffffc*/
- LOG_ERROR("address + size wrapped(0x%08" PRIx32 ", 0x%08" PRIx32 ")",
- address,
- size);
- return ERROR_FAIL;
- }
-
- return target->type->read_buffer(target, address, size, buffer);
-}
-
-static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer)
-{
- uint32_t size;
-
- /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
- * will have something to do with the size we leave to it. */
- for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
- if (address & size) {
- int retval = target_read_memory(target, address, size, 1, buffer);
- if (retval != ERROR_OK)
- return retval;
- address += size;
- count -= size;
- buffer += size;
- }
- }
-
- /* Read the data with as large access size as possible. */
- for (; size > 0; size /= 2) {
- uint32_t aligned = count - count % size;
- if (aligned > 0) {
- int retval = target_read_memory(target, address, size, aligned / size, buffer);
- if (retval != ERROR_OK)
- return retval;
- address += aligned;
- count -= aligned;
- buffer += aligned;
- }
- }
-
- return ERROR_OK;
-}
-
-int target_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t* crc)
-{
- uint8_t *buffer;
- int retval;
- uint32_t i;
- uint32_t checksum = 0;
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- retval = target->type->checksum_memory(target, address, size, &checksum);
- if (retval != ERROR_OK) {
- buffer = malloc(size);
- if (buffer == NULL) {
- LOG_ERROR("error allocating buffer for section (%d bytes)", (int)size);
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
- retval = target_read_buffer(target, address, size, buffer);
- if (retval != ERROR_OK) {
- free(buffer);
- return retval;
- }
-
- /* convert to target endianness */
- for (i = 0; i < (size/sizeof(uint32_t)); i++) {
- uint32_t target_data;
- target_data = target_buffer_get_u32(target, &buffer[i*sizeof(uint32_t)]);
- target_buffer_set_u32(target, &buffer[i*sizeof(uint32_t)], target_data);
- }
-
- retval = image_calculate_checksum(buffer, size, &checksum);
- free(buffer);
- }
-
- *crc = checksum;
-
- return retval;
-}
-
-int target_blank_check_memory(struct target *target, uint32_t address, uint32_t size, uint32_t* blank)
-{
- int retval;
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- if (target->type->blank_check_memory == 0)
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-
- retval = target->type->blank_check_memory(target, address, size, blank);
-
- return retval;
-}
-
-int target_read_u64(struct target *target, uint64_t address, uint64_t *value)
-{
- uint8_t value_buf[8];
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- int retval = target_read_memory(target, address, 8, 1, value_buf);
-
- if (retval == ERROR_OK) {
- *value = target_buffer_get_u64(target, value_buf);
- LOG_DEBUG("address: 0x%" PRIx64 ", value: 0x%16.16" PRIx64 "",
- address,
- *value);
- } else {
- *value = 0x0;
- LOG_DEBUG("address: 0x%" PRIx64 " failed",
- address);
- }
-
- return retval;
-}
-
-int target_read_u32(struct target *target, uint32_t address, uint32_t *value)
-{
- uint8_t value_buf[4];
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- int retval = target_read_memory(target, address, 4, 1, value_buf);
-
- if (retval == ERROR_OK) {
- *value = target_buffer_get_u32(target, value_buf);
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
- address,
- *value);
- } else {
- *value = 0x0;
- LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
- address);
- }
-
- return retval;
-}
-
-int target_read_u16(struct target *target, uint32_t address, uint16_t *value)
-{
- uint8_t value_buf[2];
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- int retval = target_read_memory(target, address, 2, 1, value_buf);
-
- if (retval == ERROR_OK) {
- *value = target_buffer_get_u16(target, value_buf);
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%4.4x",
- address,
- *value);
- } else {
- *value = 0x0;
- LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
- address);
- }
-
- return retval;
-}
-
-int target_read_u8(struct target *target, uint32_t address, uint8_t *value)
-{
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- int retval = target_read_memory(target, address, 1, 1, value);
-
- if (retval == ERROR_OK) {
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
- address,
- *value);
- } else {
- *value = 0x0;
- LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
- address);
- }
-
- return retval;
-}
-
-int target_write_u64(struct target *target, uint64_t address, uint64_t value)
-{
- int retval;
- uint8_t value_buf[8];
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- LOG_DEBUG("address: 0x%" PRIx64 ", value: 0x%16.16" PRIx64 "",
- address,
- value);
-
- target_buffer_set_u64(target, value_buf, value);
- retval = target_write_memory(target, address, 8, 1, value_buf);
- if (retval != ERROR_OK)
- LOG_DEBUG("failed: %i", retval);
-
- return retval;
-}
-
-int target_write_u32(struct target *target, uint32_t address, uint32_t value)
-{
- int retval;
- uint8_t value_buf[4];
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
- address,
- value);
-
- target_buffer_set_u32(target, value_buf, value);
- retval = target_write_memory(target, address, 4, 1, value_buf);
- if (retval != ERROR_OK)
- LOG_DEBUG("failed: %i", retval);
-
- return retval;
-}
-
-int target_write_u16(struct target *target, uint32_t address, uint16_t value)
-{
- int retval;
- uint8_t value_buf[2];
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8x",
- address,
- value);
-
- target_buffer_set_u16(target, value_buf, value);
- retval = target_write_memory(target, address, 2, 1, value_buf);
- if (retval != ERROR_OK)
- LOG_DEBUG("failed: %i", retval);
-
- return retval;
-}
-
-int target_write_u8(struct target *target, uint32_t address, uint8_t value)
-{
- int retval;
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
-
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
- address, value);
-
- retval = target_write_memory(target, address, 1, 1, &value);
- if (retval != ERROR_OK)
- LOG_DEBUG("failed: %i", retval);
-
- return retval;
+int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
+{
+ LOG_DEBUG("reading buffer of %" PRIi32 " byte at " TARGET_ADDR_FMT,
+ size, address);
+
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ if (size == 0)
+ return ERROR_OK;
+
+ if ((address + size - 1) < address) {
+ /* GDB can request this when e.g. PC is 0xfffffffc */
+ LOG_ERROR("address + size wrapped (" TARGET_ADDR_FMT ", 0x%08" PRIx32 ")",
+ address,
+ size);
+ return ERROR_FAIL;
+ }
+
+ return target->type->read_buffer(target, address, size, buffer);
+}
+
+static int target_read_buffer_default(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer)
+{
+ uint32_t size;
+
+ /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
+ * will have something to do with the size we leave to it. */
+ for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
+ if (address & size) {
+ int retval = target_read_memory(target, address, size, 1, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += size;
+ count -= size;
+ buffer += size;
+ }
+ }
+
+ /* Read the data with as large access size as possible. */
+ for (; size > 0; size /= 2) {
+ uint32_t aligned = count - count % size;
+ if (aligned > 0) {
+ int retval = target_read_memory(target, address, size, aligned / size, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += aligned;
+ count -= aligned;
+ buffer += aligned;
+ }
+ }
+
+ return ERROR_OK;
+}
+
+int target_checksum_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t* crc)
+{
+ uint8_t *buffer;
+ int retval;
+ uint32_t i;
+ uint32_t checksum = 0;
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ retval = target->type->checksum_memory(target, address, size, &checksum);
+ if (retval != ERROR_OK) {
+ buffer = malloc(size);
+ if (buffer == NULL) {
+ LOG_ERROR("error allocating buffer for section (%" PRId32 " bytes)", size);
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ retval = target_read_buffer(target, address, size, buffer);
+ if (retval != ERROR_OK) {
+ free(buffer);
+ return retval;
+ }
+
+ /* convert to target endianness */
+ for (i = 0; i < (size/sizeof(uint32_t)); i++) {
+ uint32_t target_data;
+ target_data = target_buffer_get_u32(target, &buffer[i*sizeof(uint32_t)]);
+ target_buffer_set_u32(target, &buffer[i*sizeof(uint32_t)], target_data);
+ }
+
+ retval = image_calculate_checksum(buffer, size, &checksum);
+ free(buffer);
+ }
+
+ *crc = checksum;
+
+ return retval;
+}
+
+int target_blank_check_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t* blank,
+ uint8_t erased_value)
+{
+ int retval;
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ if (target->type->blank_check_memory == 0)
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+
+ retval = target->type->blank_check_memory(target, address, size, blank, erased_value);
+
+ return retval;
+}
+
+int target_read_u64(struct target *target, target_addr_t address, uint64_t *value)
+{
+ uint8_t value_buf[8];
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ int retval = target_read_memory(target, address, 8, 1, value_buf);
+
+ if (retval == ERROR_OK) {
+ *value = target_buffer_get_u64(target, value_buf);
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%16.16" PRIx64 "",
+ address,
+ *value);
+ } else {
+ *value = 0x0;
+ LOG_DEBUG("address: " TARGET_ADDR_FMT " failed",
+ address);
+ }
+
+ return retval;
+}
+
+int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
+{
+ uint8_t value_buf[4];
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ int retval = target_read_memory(target, address, 4, 1, value_buf);
+
+ if (retval == ERROR_OK) {
+ *value = target_buffer_get_u32(target, value_buf);
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%8.8" PRIx32 "",
+ address,
+ *value);
+ } else {
+ *value = 0x0;
+ LOG_DEBUG("address: " TARGET_ADDR_FMT " failed",
+ address);
+ }
+
+ return retval;
+}
+
+int target_read_u16(struct target *target, target_addr_t address, uint16_t *value)
+{
+ uint8_t value_buf[2];
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ int retval = target_read_memory(target, address, 2, 1, value_buf);
+
+ if (retval == ERROR_OK) {
+ *value = target_buffer_get_u16(target, value_buf);
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%4.4" PRIx16,
+ address,
+ *value);
+ } else {
+ *value = 0x0;
+ LOG_DEBUG("address: " TARGET_ADDR_FMT " failed",
+ address);
+ }
+
+ return retval;
+}
+
+int target_read_u8(struct target *target, target_addr_t address, uint8_t *value)
+{
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ int retval = target_read_memory(target, address, 1, 1, value);
+
+ if (retval == ERROR_OK) {
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%2.2" PRIx8,
+ address,
+ *value);
+ } else {
+ *value = 0x0;
+ LOG_DEBUG("address: " TARGET_ADDR_FMT " failed",
+ address);
+ }
+
+ return retval;
+}
+
+int target_write_u64(struct target *target, target_addr_t address, uint64_t value)
+{
+ int retval;
+ uint8_t value_buf[8];
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%16.16" PRIx64 "",
+ address,
+ value);
+
+ target_buffer_set_u64(target, value_buf, value);
+ retval = target_write_memory(target, address, 8, 1, value_buf);
+ if (retval != ERROR_OK)
+ LOG_DEBUG("failed: %i", retval);
+
+ return retval;
+}
+
+int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
+{
+ int retval;
+ uint8_t value_buf[4];
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%8.8" PRIx32 "",
+ address,
+ value);
+
+ target_buffer_set_u32(target, value_buf, value);
+ retval = target_write_memory(target, address, 4, 1, value_buf);
+ if (retval != ERROR_OK)
+ LOG_DEBUG("failed: %i", retval);
+
+ return retval;
+}
+
+int target_write_u16(struct target *target, target_addr_t address, uint16_t value)
+{
+ int retval;
+ uint8_t value_buf[2];
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%8.8" PRIx16,
+ address,
+ value);
+
+ target_buffer_set_u16(target, value_buf, value);
+ retval = target_write_memory(target, address, 2, 1, value_buf);
+ if (retval != ERROR_OK)
+ LOG_DEBUG("failed: %i", retval);
+
+ return retval;
+}
+
+int target_write_u8(struct target *target, target_addr_t address, uint8_t value)
+{
+ int retval;
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%2.2" PRIx8,
+ address, value);
+
+ retval = target_write_memory(target, address, 1, 1, &value);
+ if (retval != ERROR_OK)
+ LOG_DEBUG("failed: %i", retval);
+
+ return retval;
+}
+
+int target_write_phys_u64(struct target *target, target_addr_t address, uint64_t value)
+{
+ int retval;
+ uint8_t value_buf[8];
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%16.16" PRIx64 "",
+ address,
+ value);
+
+ target_buffer_set_u64(target, value_buf, value);
+ retval = target_write_phys_memory(target, address, 8, 1, value_buf);
+ if (retval != ERROR_OK)
+ LOG_DEBUG("failed: %i", retval);
+
+ return retval;
+}
+
+int target_write_phys_u32(struct target *target, target_addr_t address, uint32_t value)
+{
+ int retval;
+ uint8_t value_buf[4];
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%8.8" PRIx32 "",
+ address,
+ value);
+
+ target_buffer_set_u32(target, value_buf, value);
+ retval = target_write_phys_memory(target, address, 4, 1, value_buf);
+ if (retval != ERROR_OK)
+ LOG_DEBUG("failed: %i", retval);
+
+ return retval;
+}
+
+int target_write_phys_u16(struct target *target, target_addr_t address, uint16_t value)
+{
+ int retval;
+ uint8_t value_buf[2];
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%8.8" PRIx16,
+ address,
+ value);
+
+ target_buffer_set_u16(target, value_buf, value);
+ retval = target_write_phys_memory(target, address, 2, 1, value_buf);
+ if (retval != ERROR_OK)
+ LOG_DEBUG("failed: %i", retval);
+
+ return retval;
+}
+
+int target_write_phys_u8(struct target *target, target_addr_t address, uint8_t value)
+{
+ int retval;
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", value: 0x%2.2" PRIx8,
+ address, value);
+
+ retval = target_write_phys_memory(target, address, 1, 1, &value);
+ if (retval != ERROR_OK)
+ LOG_DEBUG("failed: %i", retval);
+
+ return retval;
}
static int find_target(struct command_context *cmd_ctx, const char *name)
{
- struct target *target = get_target(name);
- if (target == NULL) {
- LOG_ERROR("Target: %s is unknown, try one of:\n", name);
- return ERROR_FAIL;
- }
- if (!target->tap->enabled) {
- LOG_USER("Target: TAP %s is disabled, "
- "can't be the current target\n",
- target->tap->dotted_name);
- return ERROR_FAIL;
- }
-
- cmd_ctx->current_target = target->target_number;
- return ERROR_OK;
+ struct target *target = get_target(name);
+ if (target == NULL) {
+ LOG_ERROR("Target: %s is unknown, try one of:\n", name);
+ return ERROR_FAIL;
+ }
+ if (!target->tap->enabled) {
+ LOG_USER("Target: TAP %s is disabled, "
+ "can't be the current target\n",
+ target->tap->dotted_name);
+ return ERROR_FAIL;
+ }
+
+ cmd_ctx->current_target = target->target_number;
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_targets_command)
{
- int retval = ERROR_OK;
- if (CMD_ARGC == 1) {
- retval = find_target(CMD_CTX, CMD_ARGV[0]);
- if (retval == ERROR_OK) {
- /* we're done! */
- return retval;
- }
- }
-
- struct target *target = all_targets;
- command_print(CMD_CTX, " TargetName Type Endian TapName State ");
- command_print(CMD_CTX, "-- ------------------ ---------- ------ ------------------ ------------");
- while (target) {
- const char *state;
- char marker = ' ';
-
- if (target->tap->enabled)
- state = target_state_name(target);
- else
- state = "tap-disabled";
-
- if (CMD_CTX->current_target == target->target_number)
- marker = '*';
-
- /* keep columns lined up to match the headers above */
- command_print(CMD_CTX,
- "%2d%c %-18s %-10s %-6s %-18s %s",
- target->target_number,
- marker,
- target_name(target),
- target_type_name(target),
- Jim_Nvp_value2name_simple(nvp_target_endian,
- target->endianness)->name,
- target->tap->dotted_name,
- state);
- target = target->next;
- }
-
- return retval;
+ int retval = ERROR_OK;
+ if (CMD_ARGC == 1) {
+ retval = find_target(CMD_CTX, CMD_ARGV[0]);
+ if (retval == ERROR_OK) {
+ /* we're done! */
+ return retval;
+ }
+ }
+
+ struct target *target = all_targets;
+ command_print(CMD_CTX, " TargetName Type Endian TapName State ");
+ command_print(CMD_CTX, "-- ------------------ ---------- ------ ------------------ ------------");
+ while (target) {
+ const char *state;
+ char marker = ' ';
+
+ if (target->tap->enabled)
+ state = target_state_name(target);
+ else
+ state = "tap-disabled";
+
+ if (CMD_CTX->current_target == target->target_number)
+ marker = '*';
+
+ /* keep columns lined up to match the headers above */
+ command_print(CMD_CTX,
+ "%2d%c %-18s %-10s %-6s %-18s %s",
+ target->target_number,
+ marker,
+ target_name(target),
+ target_type_name(target),
+ Jim_Nvp_value2name_simple(nvp_target_endian,
+ target->endianness)->name,
+ target->tap->dotted_name,
+ state);
+ target = target->next;
+ }
+
+ return retval;
}
/* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
@@ -2432,332 +2595,354 @@ static int runSrstDeasserted;
static int sense_handler(void)
{
- static int prevSrstAsserted;
- static int prevPowerdropout;
-
- int retval = jtag_power_dropout(&powerDropout);
- if (retval != ERROR_OK)
- return retval;
-
- int powerRestored;
- powerRestored = prevPowerdropout && !powerDropout;
- if (powerRestored)
- runPowerRestore = 1;
-
- long long current = timeval_ms();
- static long long lastPower;
- int waitMore = lastPower + 2000 > current;
- if (powerDropout && !waitMore) {
- runPowerDropout = 1;
- lastPower = current;
- }
-
- retval = jtag_srst_asserted(&srstAsserted);
- if (retval != ERROR_OK)
- return retval;
-
- int srstDeasserted;
- srstDeasserted = prevSrstAsserted && !srstAsserted;
-
- static long long lastSrst;
- waitMore = lastSrst + 2000 > current;
- if (srstDeasserted && !waitMore) {
- runSrstDeasserted = 1;
- lastSrst = current;
- }
-
- if (!prevSrstAsserted && srstAsserted)
- runSrstAsserted = 1;
-
- prevSrstAsserted = srstAsserted;
- prevPowerdropout = powerDropout;
-
- if (srstDeasserted || powerRestored) {
- /* Other than logging the event we can't do anything here.
- * Issuing a reset is a particularly bad idea as we might
- * be inside a reset already.
- */
- }
-
- return ERROR_OK;
+ static int prevSrstAsserted;
+ static int prevPowerdropout;
+
+ int retval = jtag_power_dropout(&powerDropout);
+ if (retval != ERROR_OK)
+ return retval;
+
+ int powerRestored;
+ powerRestored = prevPowerdropout && !powerDropout;
+ if (powerRestored)
+ runPowerRestore = 1;
+
+ int64_t current = timeval_ms();
+ static int64_t lastPower;
+ bool waitMore = lastPower + 2000 > current;
+ if (powerDropout && !waitMore) {
+ runPowerDropout = 1;
+ lastPower = current;
+ }
+
+ retval = jtag_srst_asserted(&srstAsserted);
+ if (retval != ERROR_OK)
+ return retval;
+
+ int srstDeasserted;
+ srstDeasserted = prevSrstAsserted && !srstAsserted;
+
+ static int64_t lastSrst;
+ waitMore = lastSrst + 2000 > current;
+ if (srstDeasserted && !waitMore) {
+ runSrstDeasserted = 1;
+ lastSrst = current;
+ }
+
+ if (!prevSrstAsserted && srstAsserted)
+ runSrstAsserted = 1;
+
+ prevSrstAsserted = srstAsserted;
+ prevPowerdropout = powerDropout;
+
+ if (srstDeasserted || powerRestored) {
+ /* Other than logging the event we can't do anything here.
+ * Issuing a reset is a particularly bad idea as we might
+ * be inside a reset already.
+ */
+ }
+
+ return ERROR_OK;
}
/* process target state changes */
static int handle_target(void *priv)
{
- Jim_Interp *interp = (Jim_Interp *)priv;
- int retval = ERROR_OK;
-
- if (!is_jtag_poll_safe()) {
- /* polling is disabled currently */
- return ERROR_OK;
- }
-
- /* we do not want to recurse here... */
- static int recursive;
- if (!recursive) {
- recursive = 1;
- sense_handler();
- /* danger! running these procedures can trigger srst assertions and power dropouts.
- * We need to avoid an infinite loop/recursion here and we do that by
- * clearing the flags after running these events.
- */
- int did_something = 0;
- if (runSrstAsserted) {
- LOG_INFO("srst asserted detected, running srst_asserted proc.");
- Jim_Eval(interp, "srst_asserted");
- did_something = 1;
- }
- if (runSrstDeasserted) {
- Jim_Eval(interp, "srst_deasserted");
- did_something = 1;
- }
- if (runPowerDropout) {
- LOG_INFO("Power dropout detected, running power_dropout proc.");
- Jim_Eval(interp, "power_dropout");
- did_something = 1;
- }
- if (runPowerRestore) {
- Jim_Eval(interp, "power_restore");
- did_something = 1;
- }
-
- if (did_something) {
- /* clear detect flags */
- sense_handler();
- }
-
- /* clear action flags */
-
- runSrstAsserted = 0;
- runSrstDeasserted = 0;
- runPowerRestore = 0;
- runPowerDropout = 0;
-
- recursive = 0;
- }
-
- /* Poll targets for state changes unless that's globally disabled.
- * Skip targets that are currently disabled.
- */
- for (struct target *target = all_targets;
- is_jtag_poll_safe() && target;
- target = target->next) {
-
- if (!target_was_examined(target))
- continue;
-
- if (!target->tap->enabled)
- continue;
-
- if (target->backoff.times > target->backoff.count) {
- /* do not poll this time as we failed previously */
- target->backoff.count++;
- continue;
- }
- target->backoff.count = 0;
-
- /* only poll target if we've got power and srst isn't asserted */
- if (!powerDropout && !srstAsserted) {
- /* polling may fail silently until the target has been examined */
- retval = target_poll(target);
- if (retval != ERROR_OK) {
- /* 100ms polling interval. Increase interval between polling up to 5000ms */
- if (target->backoff.times * polling_interval < 5000) {
- target->backoff.times *= 2;
- target->backoff.times++;
- }
-
- /* Tell GDB to halt the debugger. This allows the user to
- * run monitor commands to handle the situation.
- */
- target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
- }
- if (target->backoff.times > 0) {
- LOG_USER("Polling target %s failed, trying to reexamine", target_name(target));
- target_reset_examined(target);
- retval = target_examine_one(target);
- /* Target examination could have failed due to unstable connection,
- * but we set the examined flag anyway to repoll it later */
- if (retval != ERROR_OK) {
- target->examined = true;
- LOG_USER("Examination failed, GDB will be halted. Polling again in %dms",
- target->backoff.times * polling_interval);
- return retval;
- }
- }
-
- /* Since we succeeded, we reset backoff count */
- target->backoff.times = 0;
- }
- }
-
- return retval;
+ Jim_Interp *interp = (Jim_Interp *)priv;
+ int retval = ERROR_OK;
+
+ if (!is_jtag_poll_safe()) {
+ /* polling is disabled currently */
+ return ERROR_OK;
+ }
+
+ /* we do not want to recurse here... */
+ static int recursive;
+ if (!recursive) {
+ recursive = 1;
+ sense_handler();
+ /* danger! running these procedures can trigger srst assertions and power dropouts.
+ * We need to avoid an infinite loop/recursion here and we do that by
+ * clearing the flags after running these events.
+ */
+ int did_something = 0;
+ if (runSrstAsserted) {
+ LOG_INFO("srst asserted detected, running srst_asserted proc.");
+ Jim_Eval(interp, "srst_asserted");
+ did_something = 1;
+ }
+ if (runSrstDeasserted) {
+ Jim_Eval(interp, "srst_deasserted");
+ did_something = 1;
+ }
+ if (runPowerDropout) {
+ LOG_INFO("Power dropout detected, running power_dropout proc.");
+ Jim_Eval(interp, "power_dropout");
+ did_something = 1;
+ }
+ if (runPowerRestore) {
+ Jim_Eval(interp, "power_restore");
+ did_something = 1;
+ }
+
+ if (did_something) {
+ /* clear detect flags */
+ sense_handler();
+ }
+
+ /* clear action flags */
+
+ runSrstAsserted = 0;
+ runSrstDeasserted = 0;
+ runPowerRestore = 0;
+ runPowerDropout = 0;
+
+ recursive = 0;
+ }
+
+ /* Poll targets for state changes unless that's globally disabled.
+ * Skip targets that are currently disabled.
+ */
+ for (struct target *target = all_targets;
+ is_jtag_poll_safe() && target;
+ target = target->next) {
+
+ if (!target_was_examined(target))
+ continue;
+
+ if (!target->tap->enabled)
+ continue;
+
+ if (target->backoff.times > target->backoff.count) {
+ /* do not poll this time as we failed previously */
+ target->backoff.count++;
+ continue;
+ }
+ target->backoff.count = 0;
+
+ /* only poll target if we've got power and srst isn't asserted */
+ if (!powerDropout && !srstAsserted) {
+ /* polling may fail silently until the target has been examined */
+ retval = target_poll(target);
+ if (retval != ERROR_OK) {
+ /* 100ms polling interval. Increase interval between polling up to 5000ms */
+ if (target->backoff.times * polling_interval < 5000) {
+ target->backoff.times *= 2;
+ target->backoff.times++;
+ }
+
+ /* Tell GDB to halt the debugger. This allows the user to
+ * run monitor commands to handle the situation.
+ */
+ target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
+ }
+ if (target->backoff.times > 0) {
+ LOG_USER("Polling target %s failed, trying to reexamine", target_name(target));
+ target_reset_examined(target);
+ retval = target_examine_one(target);
+ /* Target examination could have failed due to unstable connection,
+ * but we set the examined flag anyway to repoll it later */
+ if (retval != ERROR_OK) {
+ target->examined = true;
+ LOG_USER("Examination failed, GDB will be halted. Polling again in %dms",
+ target->backoff.times * polling_interval);
+ return retval;
+ }
+ }
+
+ /* Since we succeeded, we reset backoff count */
+ target->backoff.times = 0;
+ }
+ }
+
+ return retval;
}
COMMAND_HANDLER(handle_reg_command)
{
- struct target *target;
- struct reg *reg = NULL;
- unsigned count = 0;
- char *value;
-
- LOG_DEBUG("-");
-
- target = get_current_target(CMD_CTX);
-
- /* list all available registers for the current target */
- if (CMD_ARGC == 0) {
- struct reg_cache *cache = target->reg_cache;
-
- count = 0;
- while (cache) {
- unsigned i;
-
- command_print(CMD_CTX, "===== %s", cache->name);
-
- for (i = 0, reg = cache->reg_list;
- i < cache->num_regs;
- i++, reg++, count++) {
- /* only print cached values if they are valid */
- if (reg->valid) {
- value = buf_to_str(reg->value,
- reg->size, 16);
- command_print(CMD_CTX,
- "(%i) %s (/%" PRIu32 "): 0x%s%s",
- count, reg->name,
- reg->size, value,
- reg->dirty
- ? " (dirty)"
- : "");
- free(value);
- } else {
- command_print(CMD_CTX, "(%i) %s (/%" PRIu32 ")",
- count, reg->name,
- reg->size) ;
- }
- }
- cache = cache->next;
- }
-
- return ERROR_OK;
- }
-
- /* access a single register by its ordinal number */
- if ((CMD_ARGV[0][0] >= '0') && (CMD_ARGV[0][0] <= '9')) {
- unsigned num;
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
-
- struct reg_cache *cache = target->reg_cache;
- count = 0;
- while (cache) {
- unsigned i;
- for (i = 0; i < cache->num_regs; i++) {
- if (count++ == num) {
- reg = &cache->reg_list[i];
- break;
- }
- }
- if (reg)
- break;
- cache = cache->next;
- }
-
- if (!reg) {
- command_print(CMD_CTX, "%i is out of bounds, the current target "
- "has only %i registers (0 - %i)", num, count, count - 1);
- return ERROR_OK;
- }
- } else {
- /* access a single register by its name */
- reg = register_get_by_name(target->reg_cache, CMD_ARGV[0], 1);
-
- if (!reg) {
- command_print(CMD_CTX, "register %s not found in current target", CMD_ARGV[0]);
- return ERROR_OK;
- }
- }
-
- assert(reg != NULL); /* give clang a hint that we *know* reg is != NULL here */
-
- /* display a register */
- if ((CMD_ARGC == 1) || ((CMD_ARGC == 2) && !((CMD_ARGV[1][0] >= '0')
- && (CMD_ARGV[1][0] <= '9')))) {
- if ((CMD_ARGC == 2) && (strcmp(CMD_ARGV[1], "force") == 0))
- reg->valid = 0;
-
- if (reg->valid == 0)
- reg->type->get(reg);
- value = buf_to_str(reg->value, reg->size, 16);
- command_print(CMD_CTX, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value);
- free(value);
- return ERROR_OK;
- }
-
- /* set register value */
- if (CMD_ARGC == 2) {
- uint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8));
- if (buf == NULL)
- return ERROR_FAIL;
- str_to_buf(CMD_ARGV[1], strlen(CMD_ARGV[1]), buf, reg->size, 0);
-
- reg->type->set(reg, buf);
-
- value = buf_to_str(reg->value, reg->size, 16);
- command_print(CMD_CTX, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value);
- free(value);
-
- free(buf);
-
- return ERROR_OK;
- }
-
- return ERROR_COMMAND_SYNTAX_ERROR;
+ struct target *target;
+ struct reg *reg = NULL;
+ unsigned count = 0;
+ char *value;
+#if BUILD_RISCV == 1
+ int retval;
+#endif
+
+ LOG_DEBUG("-");
+
+ target = get_current_target(CMD_CTX);
+
+ /* list all available registers for the current target */
+ if (CMD_ARGC == 0) {
+ struct reg_cache *cache = target->reg_cache;
+
+ count = 0;
+ while (cache) {
+ unsigned i;
+
+ command_print(CMD_CTX, "===== %s", cache->name);
+
+ for (i = 0, reg = cache->reg_list;
+ i < cache->num_regs;
+ i++, reg++, count++) {
+ /* only print cached values if they are valid */
+ if (reg->valid) {
+ value = buf_to_str(reg->value,
+ reg->size, 16);
+ command_print(CMD_CTX,
+ "(%i) %s (/%" PRIu32 "): 0x%s%s",
+ count, reg->name,
+ reg->size, value,
+ reg->dirty
+ ? " (dirty)"
+ : "");
+ free(value);
+ } else {
+ command_print(CMD_CTX, "(%i) %s (/%" PRIu32 ")",
+ count, reg->name,
+ reg->size) ;
+ }
+ }
+ cache = cache->next;
+ }
+
+ return ERROR_OK;
+ }
+
+ /* access a single register by its ordinal number */
+ if ((CMD_ARGV[0][0] >= '0') && (CMD_ARGV[0][0] <= '9')) {
+ unsigned num;
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
+
+ struct reg_cache *cache = target->reg_cache;
+ count = 0;
+ while (cache) {
+ unsigned i;
+ for (i = 0; i < cache->num_regs; i++) {
+ if (count++ == num) {
+ reg = &cache->reg_list[i];
+ break;
+ }
+ }
+ if (reg)
+ break;
+ cache = cache->next;
+ }
+
+ if (!reg) {
+ command_print(CMD_CTX, "%i is out of bounds, the current target "
+ "has only %i registers (0 - %i)", num, count, count - 1);
+ return ERROR_OK;
+ }
+ } else {
+ /* access a single register by its name */
+ reg = register_get_by_name(target->reg_cache, CMD_ARGV[0], 1);
+
+ if (!reg) {
+ command_print(CMD_CTX, "register %s not found in current target", CMD_ARGV[0]);
+ return ERROR_OK;
+ }
+ }
+
+ assert(reg != NULL); /* give clang a hint that we *know* reg is != NULL here */
+
+ /* display a register */
+ if ((CMD_ARGC == 1) || ((CMD_ARGC == 2) && !((CMD_ARGV[1][0] >= '0')
+ && (CMD_ARGV[1][0] <= '9')))) {
+ if ((CMD_ARGC == 2) && (strcmp(CMD_ARGV[1], "force") == 0))
+ reg->valid = 0;
+
+#if BUILD_RISCV == 1
+ if (reg->valid == 0) {
+ retval = reg->type->get(reg);
+ if (retval != ERROR_OK) {
+ LOG_DEBUG("Couldn't get register %s.", reg->name);
+ return retval;
+ }
+ }
+#else
+ if (reg->valid == 0)
+ reg->type->get(reg);
+#endif
+ value = buf_to_str(reg->value, reg->size, 16);
+ command_print(CMD_CTX, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value);
+ free(value);
+ return ERROR_OK;
+ }
+
+ /* set register value */
+ if (CMD_ARGC == 2) {
+ uint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8));
+ if (buf == NULL)
+ return ERROR_FAIL;
+ str_to_buf(CMD_ARGV[1], strlen(CMD_ARGV[1]), buf, reg->size, 0);
+
+#if BUILD_RISCV == 1
+ retval = reg->type->set(reg, buf);
+ if (retval != ERROR_OK) {
+ LOG_DEBUG("Couldn't set register %s.", reg->name);
+ free (buf);
+ return retval;
+ }
+#else
+ reg->type->set(reg, buf);
+#endif
+
+ value = buf_to_str(reg->value, reg->size, 16);
+ command_print(CMD_CTX, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value);
+ free(value);
+
+ free(buf);
+
+ return ERROR_OK;
+ }
+
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
COMMAND_HANDLER(handle_poll_command)
{
- int retval = ERROR_OK;
- struct target *target = get_current_target(CMD_CTX);
-
- if (CMD_ARGC == 0) {
- command_print(CMD_CTX, "background polling: %s",
- jtag_poll_get_enabled() ? "on" : "off");
- command_print(CMD_CTX, "TAP: %s (%s)",
- target->tap->dotted_name,
- target->tap->enabled ? "enabled" : "disabled");
- if (!target->tap->enabled)
- return ERROR_OK;
- retval = target_poll(target);
- if (retval != ERROR_OK)
- return retval;
- retval = target_arch_state(target);
- if (retval != ERROR_OK)
- return retval;
- } else if (CMD_ARGC == 1) {
- bool enable;
- COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);
- jtag_poll_set_enabled(enable);
- } else
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- return retval;
+ int retval = ERROR_OK;
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (CMD_ARGC == 0) {
+ command_print(CMD_CTX, "background polling: %s",
+ jtag_poll_get_enabled() ? "on" : "off");
+ command_print(CMD_CTX, "TAP: %s (%s)",
+ target->tap->dotted_name,
+ target->tap->enabled ? "enabled" : "disabled");
+ if (!target->tap->enabled)
+ return ERROR_OK;
+ retval = target_poll(target);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_arch_state(target);
+ if (retval != ERROR_OK)
+ return retval;
+ } else if (CMD_ARGC == 1) {
+ bool enable;
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);
+ jtag_poll_set_enabled(enable);
+ } else
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ return retval;
}
COMMAND_HANDLER(handle_wait_halt_command)
{
- if (CMD_ARGC > 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- unsigned ms = DEFAULT_HALT_TIMEOUT;
- if (1 == CMD_ARGC) {
- int retval = parse_uint(CMD_ARGV[0], &ms);
- if (ERROR_OK != retval)
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- struct target *target = get_current_target(CMD_CTX);
- return target_wait_state(target, TARGET_HALTED, ms);
+ if (CMD_ARGC > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ unsigned ms = DEFAULT_HALT_TIMEOUT;
+ if (1 == CMD_ARGC) {
+ int retval = parse_uint(CMD_ARGV[0], &ms);
+ if (ERROR_OK != retval)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ struct target *target = get_current_target(CMD_CTX);
+ return target_wait_state(target, TARGET_HALTED, ms);
}
/* wait for target state to change. The trick here is to have a low
@@ -2768,880 +2953,910 @@ COMMAND_HANDLER(handle_wait_halt_command)
*/
int target_wait_state(struct target *target, enum target_state state, int ms)
{
- int retval;
- long long then = 0, cur;
- int once = 1;
-
- for (;;) {
- retval = target_poll(target);
- if (retval != ERROR_OK)
- return retval;
- if (target->state == state)
- break;
- cur = timeval_ms();
- if (once) {
- once = 0;
- then = timeval_ms();
- LOG_DEBUG("waiting for target %s...",
- Jim_Nvp_value2name_simple(nvp_target_state, state)->name);
- }
-
- if (cur-then > 500)
- keep_alive();
-
- if ((cur-then) > ms) {
- LOG_ERROR("timed out while waiting for target %s",
- Jim_Nvp_value2name_simple(nvp_target_state, state)->name);
- return ERROR_FAIL;
- }
- }
-
- return ERROR_OK;
+ int retval;
+ int64_t then = 0, cur;
+ bool once = true;
+
+ for (;;) {
+ retval = target_poll(target);
+ if (retval != ERROR_OK)
+ return retval;
+ if (target->state == state)
+ break;
+ cur = timeval_ms();
+ if (once) {
+ once = false;
+ then = timeval_ms();
+ LOG_DEBUG("waiting for target %s...",
+ Jim_Nvp_value2name_simple(nvp_target_state, state)->name);
+ }
+
+ if (cur-then > 500)
+ keep_alive();
+
+ if ((cur-then) > ms) {
+ LOG_ERROR("timed out while waiting for target %s",
+ Jim_Nvp_value2name_simple(nvp_target_state, state)->name);
+ return ERROR_FAIL;
+ }
+ }
+
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_halt_command)
{
- LOG_DEBUG("-");
-
- struct target *target = get_current_target(CMD_CTX);
- int retval = target_halt(target);
- if (ERROR_OK != retval)
- return retval;
-
- if (CMD_ARGC == 1) {
- unsigned wait_local;
- retval = parse_uint(CMD_ARGV[0], &wait_local);
- if (ERROR_OK != retval)
- return ERROR_COMMAND_SYNTAX_ERROR;
- if (!wait_local)
- return ERROR_OK;
- }
-
- return CALL_COMMAND_HANDLER(handle_wait_halt_command);
+ LOG_DEBUG("-");
+
+ struct target *target = get_current_target(CMD_CTX);
+ int retval = target_halt(target);
+ if (ERROR_OK != retval)
+ return retval;
+
+ if (CMD_ARGC == 1) {
+ unsigned wait_local;
+ retval = parse_uint(CMD_ARGV[0], &wait_local);
+ if (ERROR_OK != retval)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ if (!wait_local)
+ return ERROR_OK;
+ }
+
+ return CALL_COMMAND_HANDLER(handle_wait_halt_command);
}
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");
-
- target_soft_reset_halt(target);
-
- return ERROR_OK;
+ struct target *target = get_current_target(CMD_CTX);
+
+ LOG_USER("requesting target halt and executing a soft reset");
+
+ target_soft_reset_halt(target);
+
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_reset_command)
{
- if (CMD_ARGC > 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- enum target_reset_mode reset_mode = RESET_RUN;
- if (CMD_ARGC == 1) {
- const Jim_Nvp *n;
- n = Jim_Nvp_name2value_simple(nvp_reset_modes, CMD_ARGV[0]);
- if ((n->name == NULL) || (n->value == RESET_UNKNOWN))
- return ERROR_COMMAND_SYNTAX_ERROR;
- reset_mode = n->value;
- }
-
- /* reset *all* targets */
- return target_process_reset(CMD_CTX, reset_mode);
+ if (CMD_ARGC > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ enum target_reset_mode reset_mode = RESET_RUN;
+ if (CMD_ARGC == 1) {
+ const Jim_Nvp *n;
+ n = Jim_Nvp_name2value_simple(nvp_reset_modes, CMD_ARGV[0]);
+ if ((n->name == NULL) || (n->value == RESET_UNKNOWN))
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ reset_mode = n->value;
+ }
+
+ /* reset *all* targets */
+ return target_process_reset(CMD_CTX, reset_mode);
}
COMMAND_HANDLER(handle_resume_command)
{
- int current = 1;
- if (CMD_ARGC > 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- struct target *target = get_current_target(CMD_CTX);
-
- /* with no CMD_ARGV, resume from current pc, addr = 0,
- * with one arguments, addr = CMD_ARGV[0],
- * handle breakpoints, not debugging */
- uint32_t addr = 0;
- if (CMD_ARGC == 1) {
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
- current = 0;
- }
-
- return target_resume(target, current, addr, 1, 0);
+ int current = 1;
+ if (CMD_ARGC > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct target *target = get_current_target(CMD_CTX);
+
+ /* with no CMD_ARGV, resume from current pc, addr = 0,
+ * with one arguments, addr = CMD_ARGV[0],
+ * handle breakpoints, not debugging */
+ target_addr_t addr = 0;
+ if (CMD_ARGC == 1) {
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
+ current = 0;
+ }
+
+ return target_resume(target, current, addr, 1, 0);
}
COMMAND_HANDLER(handle_step_command)
{
- if (CMD_ARGC > 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- LOG_DEBUG("-");
-
- /* with no CMD_ARGV, step from current pc, addr = 0,
- * with one argument addr = CMD_ARGV[0],
- * handle breakpoints, debugging */
- uint32_t addr = 0;
- int current_pc = 1;
- if (CMD_ARGC == 1) {
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
- current_pc = 0;
- }
-
- struct target *target = get_current_target(CMD_CTX);
-
- return target->type->step(target, current_pc, addr, 1);
+ if (CMD_ARGC > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ LOG_DEBUG("-");
+
+ /* with no CMD_ARGV, step from current pc, addr = 0,
+ * with one argument addr = CMD_ARGV[0],
+ * handle breakpoints, debugging */
+ target_addr_t addr = 0;
+ int current_pc = 1;
+ if (CMD_ARGC == 1) {
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
+ current_pc = 0;
+ }
+
+ struct target *target = get_current_target(CMD_CTX);
+
+ return target->type->step(target, current_pc, addr, 1);
}
static void handle_md_output(struct command_context *cmd_ctx,
- struct target *target, uint32_t address, unsigned size,
- unsigned count, const uint8_t *buffer)
-{
- const unsigned line_bytecnt = 32;
- unsigned line_modulo = line_bytecnt / size;
-
- char output[line_bytecnt * 4 + 1];
- unsigned output_len = 0;
-
- const char *value_fmt;
- switch (size) {
- case 4:
- value_fmt = "%8.8x ";
- break;
- case 2:
- value_fmt = "%4.4x ";
- break;
- case 1:
- value_fmt = "%2.2x ";
- break;
- default:
- /* "can't happen", caller checked */
- LOG_ERROR("invalid memory read size: %u", size);
- return;
- }
-
- for (unsigned i = 0; i < count; i++) {
- if (i % line_modulo == 0) {
- output_len += snprintf(output + output_len,
- sizeof(output) - output_len,
- "0x%8.8x: ",
- (unsigned)(address + (i*size)));
- }
-
- uint32_t value = 0;
- const uint8_t *value_ptr = buffer + i * size;
- switch (size) {
- case 4:
- value = target_buffer_get_u32(target, value_ptr);
- break;
- case 2:
- value = target_buffer_get_u16(target, value_ptr);
- break;
- case 1:
- value = *value_ptr;
- }
- output_len += snprintf(output + output_len,
- sizeof(output) - output_len,
- value_fmt, value);
-
- if ((i % line_modulo == line_modulo - 1) || (i == count - 1)) {
- command_print(cmd_ctx, "%s", output);
- output_len = 0;
- }
- }
+ struct target *target, target_addr_t address, unsigned size,
+ unsigned count, const uint8_t *buffer)
+{
+ const unsigned line_bytecnt = 32;
+ unsigned line_modulo = line_bytecnt / size;
+
+ char output[line_bytecnt * 4 + 1];
+ unsigned output_len = 0;
+
+ const char *value_fmt;
+ switch (size) {
+ case 8:
+ value_fmt = "%16.16llx ";
+ break;
+ case 4:
+ value_fmt = "%8.8x ";
+ break;
+ case 2:
+ value_fmt = "%4.4x ";
+ break;
+ case 1:
+ value_fmt = "%2.2x ";
+ break;
+ default:
+ /* "can't happen", caller checked */
+ LOG_ERROR("invalid memory read size: %u", size);
+ return;
+ }
+
+ for (unsigned i = 0; i < count; i++) {
+ if (i % line_modulo == 0) {
+ output_len += snprintf(output + output_len,
+ sizeof(output) - output_len,
+ TARGET_ADDR_FMT ": ",
+ (address + (i * size)));
+ }
+
+ uint64_t value = 0;
+ const uint8_t *value_ptr = buffer + i * size;
+ switch (size) {
+ case 8:
+ value = target_buffer_get_u64(target, value_ptr);
+ break;
+ case 4:
+ value = target_buffer_get_u32(target, value_ptr);
+ break;
+ case 2:
+ value = target_buffer_get_u16(target, value_ptr);
+ break;
+ case 1:
+ value = *value_ptr;
+ }
+ output_len += snprintf(output + output_len,
+ sizeof(output) - output_len,
+ value_fmt, value);
+
+ if ((i % line_modulo == line_modulo - 1) || (i == count - 1)) {
+ command_print(cmd_ctx, "%s", output);
+ output_len = 0;
+ }
+ }
}
COMMAND_HANDLER(handle_md_command)
{
- if (CMD_ARGC < 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- unsigned size = 0;
- switch (CMD_NAME[2]) {
- case 'w':
- size = 4;
- break;
- case 'h':
- size = 2;
- break;
- case 'b':
- size = 1;
- break;
- default:
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- bool physical = strcmp(CMD_ARGV[0], "phys") == 0;
- int (*fn)(struct target *target,
- uint32_t address, uint32_t size_value, uint32_t count, uint8_t *buffer);
- if (physical) {
- CMD_ARGC--;
- CMD_ARGV++;
- fn = target_read_phys_memory;
- } else
- fn = target_read_memory;
- if ((CMD_ARGC < 1) || (CMD_ARGC > 2))
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- uint32_t address;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
-
- unsigned count = 1;
- if (CMD_ARGC == 2)
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], count);
-
- uint8_t *buffer = calloc(count, size);
-
- struct target *target = get_current_target(CMD_CTX);
- int retval = fn(target, address, size, count, buffer);
- if (ERROR_OK == retval)
- handle_md_output(CMD_CTX, target, address, size, count, buffer);
-
- free(buffer);
-
- return retval;
+ if (CMD_ARGC < 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ unsigned size = 0;
+ switch (CMD_NAME[2]) {
+ case 'd':
+ size = 8;
+ break;
+ case 'w':
+ size = 4;
+ break;
+ case 'h':
+ size = 2;
+ break;
+ case 'b':
+ size = 1;
+ break;
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ bool physical = strcmp(CMD_ARGV[0], "phys") == 0;
+ int (*fn)(struct target *target,
+ target_addr_t address, uint32_t size_value, uint32_t count, uint8_t *buffer);
+ if (physical) {
+ CMD_ARGC--;
+ CMD_ARGV++;
+ fn = target_read_phys_memory;
+ } else
+ fn = target_read_memory;
+ if ((CMD_ARGC < 1) || (CMD_ARGC > 2))
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ target_addr_t address;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
+
+ unsigned count = 1;
+ if (CMD_ARGC == 2)
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], count);
+
+ uint8_t *buffer = calloc(count, size);
+
+ struct target *target = get_current_target(CMD_CTX);
+ int retval = fn(target, address, size, count, buffer);
+ if (ERROR_OK == retval)
+ handle_md_output(CMD_CTX, target, address, size, count, buffer);
+
+ free(buffer);
+
+ return retval;
}
typedef int (*target_write_fn)(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
+target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
static int target_fill_mem(struct target *target,
- uint32_t address,
- target_write_fn fn,
- unsigned data_size,
- /* value */
- uint32_t b,
- /* count */
- unsigned c)
-{
- /* We have to write in reasonably large chunks to be able
- * to fill large memory areas with any sane speed */
- const unsigned chunk_size = 16384;
- uint8_t *target_buf = malloc(chunk_size * data_size);
- if (target_buf == NULL) {
- LOG_ERROR("Out of memory");
- return ERROR_FAIL;
- }
-
- for (unsigned i = 0; i < chunk_size; i++) {
- switch (data_size) {
- case 4:
- target_buffer_set_u32(target, target_buf + i * data_size, b);
- break;
- case 2:
- target_buffer_set_u16(target, target_buf + i * data_size, b);
- break;
- case 1:
- target_buffer_set_u8(target, target_buf + i * data_size, b);
- break;
- default:
- exit(-1);
- }
- }
-
- int retval = ERROR_OK;
-
- for (unsigned x = 0; x < c; x += chunk_size) {
- unsigned current;
- current = c - x;
- if (current > chunk_size)
- current = chunk_size;
- retval = fn(target, address + x * data_size, data_size, current, target_buf);
- if (retval != ERROR_OK)
- break;
- /* avoid GDB timeouts */
- keep_alive();
- }
- free(target_buf);
-
- return retval;
+ target_addr_t address,
+ target_write_fn fn,
+ unsigned data_size,
+ /* value */
+ uint64_t b,
+ /* count */
+ unsigned c)
+{
+ /* We have to write in reasonably large chunks to be able
+ * to fill large memory areas with any sane speed */
+ const unsigned chunk_size = 16384;
+ uint8_t *target_buf = malloc(chunk_size * data_size);
+ if (target_buf == NULL) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+
+ for (unsigned i = 0; i < chunk_size; i++) {
+ switch (data_size) {
+ case 8:
+ target_buffer_set_u64(target, target_buf + i * data_size, b);
+ break;
+ case 4:
+ target_buffer_set_u32(target, target_buf + i * data_size, b);
+ break;
+ case 2:
+ target_buffer_set_u16(target, target_buf + i * data_size, b);
+ break;
+ case 1:
+ target_buffer_set_u8(target, target_buf + i * data_size, b);
+ break;
+ default:
+ exit(-1);
+ }
+ }
+
+ int retval = ERROR_OK;
+
+ for (unsigned x = 0; x < c; x += chunk_size) {
+ unsigned current;
+ current = c - x;
+ if (current > chunk_size)
+ current = chunk_size;
+ retval = fn(target, address + x * data_size, data_size, current, target_buf);
+ if (retval != ERROR_OK)
+ break;
+ /* avoid GDB timeouts */
+ keep_alive();
+ }
+ free(target_buf);
+
+ return retval;
}
COMMAND_HANDLER(handle_mw_command)
{
- if (CMD_ARGC < 2)
- return ERROR_COMMAND_SYNTAX_ERROR;
- bool physical = strcmp(CMD_ARGV[0], "phys") == 0;
- target_write_fn fn;
- if (physical) {
- CMD_ARGC--;
- CMD_ARGV++;
- fn = target_write_phys_memory;
- } else
- fn = target_write_memory;
- if ((CMD_ARGC < 2) || (CMD_ARGC > 3))
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- uint32_t address;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
-
- uint32_t value;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
-
- unsigned count = 1;
- if (CMD_ARGC == 3)
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], count);
-
- struct target *target = get_current_target(CMD_CTX);
- unsigned wordsize;
- switch (CMD_NAME[2]) {
- case 'w':
- wordsize = 4;
- break;
- case 'h':
- wordsize = 2;
- break;
- case 'b':
- wordsize = 1;
- break;
- default:
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- return target_fill_mem(target, address, fn, wordsize, value, count);
+ if (CMD_ARGC < 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ bool physical = strcmp(CMD_ARGV[0], "phys") == 0;
+ target_write_fn fn;
+ if (physical) {
+ CMD_ARGC--;
+ CMD_ARGV++;
+ fn = target_write_phys_memory;
+ } else
+ fn = target_write_memory;
+ if ((CMD_ARGC < 2) || (CMD_ARGC > 3))
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ target_addr_t address;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
+
+ target_addr_t value;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[1], value);
+
+ unsigned count = 1;
+ if (CMD_ARGC == 3)
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], count);
+
+ struct target *target = get_current_target(CMD_CTX);
+ unsigned wordsize;
+ switch (CMD_NAME[2]) {
+ case 'd':
+ wordsize = 8;
+ break;
+ case 'w':
+ wordsize = 4;
+ break;
+ case 'h':
+ wordsize = 2;
+ break;
+ case 'b':
+ wordsize = 1;
+ break;
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ return target_fill_mem(target, address, fn, wordsize, value, count);
}
static COMMAND_HELPER(parse_load_image_command_CMD_ARGV, struct image *image,
- uint32_t *min_address, uint32_t *max_address)
-{
- if (CMD_ARGC < 1 || CMD_ARGC > 5)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- /* a base address isn't always necessary,
- * default to 0x0 (i.e. don't relocate) */
- if (CMD_ARGC >= 2) {
- uint32_t addr;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], addr);
- image->base_address = addr;
- image->base_address_set = 1;
- } else
- image->base_address_set = 0;
-
- image->start_address_set = 0;
-
- if (CMD_ARGC >= 4)
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], *min_address);
- if (CMD_ARGC == 5) {
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], *max_address);
- /* use size (given) to find max (required) */
- *max_address += *min_address;
- }
-
- if (*min_address > *max_address)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- return ERROR_OK;
+ target_addr_t *min_address, target_addr_t *max_address)
+{
+ if (CMD_ARGC < 1 || CMD_ARGC > 5)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ /* a base address isn't always necessary,
+ * default to 0x0 (i.e. don't relocate) */
+ if (CMD_ARGC >= 2) {
+ target_addr_t addr;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[1], addr);
+ image->base_address = addr;
+ image->base_address_set = 1;
+ } else
+ image->base_address_set = 0;
+
+ image->start_address_set = 0;
+
+ if (CMD_ARGC >= 4)
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[3], *min_address);
+ if (CMD_ARGC == 5) {
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[4], *max_address);
+ /* use size (given) to find max (required) */
+ *max_address += *min_address;
+ }
+
+ if (*min_address > *max_address)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_load_image_command)
{
- uint8_t *buffer;
- size_t buf_cnt;
- uint32_t image_size;
- uint32_t min_address = 0;
- uint32_t max_address = 0xffffffff;
- int i;
- struct image image;
-
- int retval = CALL_COMMAND_HANDLER(parse_load_image_command_CMD_ARGV,
- &image, &min_address, &max_address);
- if (ERROR_OK != retval)
- return retval;
-
- struct target *target = get_current_target(CMD_CTX);
-
- struct duration bench;
- duration_start(&bench);
-
- if (image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK)
- return ERROR_OK;
-
- image_size = 0x0;
- retval = ERROR_OK;
- for (i = 0; i < image.num_sections; i++) {
- buffer = malloc(image.sections[i].size);
- if (buffer == NULL) {
- command_print(CMD_CTX,
- "error allocating buffer for section (%d bytes)",
- (int)(image.sections[i].size));
- break;
- }
-
- retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);
- if (retval != ERROR_OK) {
- free(buffer);
- break;
- }
-
- uint32_t offset = 0;
- uint32_t length = buf_cnt;
-
- /* DANGER!!! beware of unsigned comparision here!!! */
-
- if ((image.sections[i].base_address + buf_cnt >= min_address) &&
- (image.sections[i].base_address < max_address)) {
-
- if (image.sections[i].base_address < min_address) {
- /* clip addresses below */
- offset += min_address-image.sections[i].base_address;
- length -= offset;
- }
-
- if (image.sections[i].base_address + buf_cnt > max_address)
- length -= (image.sections[i].base_address + buf_cnt)-max_address;
-
- retval = target_write_buffer(target,
- image.sections[i].base_address + offset, length, buffer + offset);
- if (retval != ERROR_OK) {
- free(buffer);
- break;
- }
- image_size += length;
- command_print(CMD_CTX, "%u bytes written at address 0x%8.8" PRIx32 "",
- (unsigned int)length,
- image.sections[i].base_address + offset);
- }
-
- free(buffer);
- }
-
- if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
- command_print(CMD_CTX, "downloaded %" PRIu32 " bytes "
- "in %fs (%0.3f KiB/s)", image_size,
- duration_elapsed(&bench), duration_kbps(&bench, image_size));
- }
-
- image_close(&image);
-
- return retval;
-
+ uint8_t *buffer;
+ size_t buf_cnt;
+ uint32_t image_size;
+ target_addr_t min_address = 0;
+ target_addr_t max_address = -1;
+ int i;
+ struct image image;
+
+ int retval = CALL_COMMAND_HANDLER(parse_load_image_command_CMD_ARGV,
+ &image, &min_address, &max_address);
+ if (ERROR_OK != retval)
+ return retval;
+
+ struct target *target = get_current_target(CMD_CTX);
+
+ struct duration bench;
+ duration_start(&bench);
+
+ if (image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK)
+ return ERROR_FAIL;
+
+ image_size = 0x0;
+ retval = ERROR_OK;
+ for (i = 0; i < image.num_sections; i++) {
+ buffer = malloc(image.sections[i].size);
+ if (buffer == NULL) {
+ command_print(CMD_CTX,
+ "error allocating buffer for section (%d bytes)",
+ (int)(image.sections[i].size));
+ retval = ERROR_FAIL;
+ break;
+ }
+
+ retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);
+ if (retval != ERROR_OK) {
+ free(buffer);
+ break;
+ }
+
+ uint32_t offset = 0;
+ uint32_t length = buf_cnt;
+
+ /* DANGER!!! beware of unsigned comparision here!!! */
+
+ if ((image.sections[i].base_address + buf_cnt >= min_address) &&
+ (image.sections[i].base_address < max_address)) {
+
+ if (image.sections[i].base_address < min_address) {
+ /* clip addresses below */
+ offset += min_address-image.sections[i].base_address;
+ length -= offset;
+ }
+
+ if (image.sections[i].base_address + buf_cnt > max_address)
+ length -= (image.sections[i].base_address + buf_cnt)-max_address;
+
+ retval = target_write_buffer(target,
+ image.sections[i].base_address + offset, length, buffer + offset);
+ if (retval != ERROR_OK) {
+ free(buffer);
+ break;
+ }
+ image_size += length;
+ command_print(CMD_CTX, "%u bytes written at address " TARGET_ADDR_FMT "",
+ (unsigned int)length,
+ image.sections[i].base_address + offset);
+ }
+
+ free(buffer);
+ }
+
+ if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
+ command_print(CMD_CTX, "downloaded %" PRIu32 " bytes "
+ "in %fs (%0.3f KiB/s)", image_size,
+ duration_elapsed(&bench), duration_kbps(&bench, image_size));
+ }
+
+ image_close(&image);
+
+ return retval;
+
}
COMMAND_HANDLER(handle_dump_image_command)
{
- struct fileio fileio;
- uint8_t *buffer;
- int retval, retvaltemp;
- uint32_t address, size;
- struct duration bench;
- struct target *target = get_current_target(CMD_CTX);
-
- if (CMD_ARGC != 3)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], address);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], size);
-
- uint32_t buf_size = (size > 4096) ? 4096 : size;
- buffer = malloc(buf_size);
- if (!buffer)
- return ERROR_FAIL;
-
- retval = fileio_open(&fileio, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY);
- if (retval != ERROR_OK) {
- free(buffer);
- return retval;
- }
-
- duration_start(&bench);
-
- while (size > 0) {
- size_t size_written;
- uint32_t this_run_size = (size > buf_size) ? buf_size : size;
- retval = target_read_buffer(target, address, this_run_size, buffer);
- if (retval != ERROR_OK)
- break;
-
- retval = fileio_write(&fileio, this_run_size, buffer, &size_written);
- if (retval != ERROR_OK)
- break;
-
- size -= this_run_size;
- address += this_run_size;
- }
-
- free(buffer);
-
- if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
- size_t filesize;
- retval = fileio_size(&fileio, &filesize);
- if (retval != ERROR_OK)
- return retval;
- command_print(CMD_CTX,
- "dumped %zu bytes in %fs (%0.3f KiB/s)", filesize,
- duration_elapsed(&bench), duration_kbps(&bench, filesize));
- }
-
- retvaltemp = fileio_close(&fileio);
- if (retvaltemp != ERROR_OK)
- return retvaltemp;
-
- return retval;
-}
-
-static COMMAND_HELPER(handle_verify_image_command_internal, int verify)
-{
- uint8_t *buffer;
- size_t buf_cnt;
- uint32_t image_size;
- int i;
- int retval;
- uint32_t checksum = 0;
- uint32_t mem_checksum = 0;
-
- struct image image;
-
- struct target *target = get_current_target(CMD_CTX);
-
- if (CMD_ARGC < 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- if (!target) {
- LOG_ERROR("no target selected");
- return ERROR_FAIL;
- }
-
- struct duration bench;
- duration_start(&bench);
-
- if (CMD_ARGC >= 2) {
- uint32_t addr;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], addr);
- image.base_address = addr;
- image.base_address_set = 1;
- } else {
- image.base_address_set = 0;
- image.base_address = 0x0;
- }
-
- image.start_address_set = 0;
-
- retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);
- if (retval != ERROR_OK)
- return retval;
-
- image_size = 0x0;
- int diffs = 0;
- retval = ERROR_OK;
- for (i = 0; i < image.num_sections; i++) {
- buffer = malloc(image.sections[i].size);
- if (buffer == NULL) {
- command_print(CMD_CTX,
- "error allocating buffer for section (%d bytes)",
- (int)(image.sections[i].size));
- break;
- }
- retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);
- if (retval != ERROR_OK) {
- free(buffer);
- break;
- }
-
- if (verify) {
- /* calculate checksum of image */
- retval = image_calculate_checksum(buffer, buf_cnt, &checksum);
- if (retval != ERROR_OK) {
- free(buffer);
- break;
- }
-
- retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
- if (retval != ERROR_OK) {
- free(buffer);
- break;
- }
-
- if (checksum != mem_checksum) {
- /* failed crc checksum, fall back to a binary compare */
- uint8_t *data;
-
- if (diffs == 0)
- LOG_ERROR("checksum mismatch - attempting binary compare");
-
- data = malloc(buf_cnt);
-
- /* Can we use 32bit word accesses? */
- int size = 1;
- int count = buf_cnt;
- if ((count % 4) == 0) {
- size *= 4;
- count /= 4;
- }
- retval = target_read_memory(target, image.sections[i].base_address, size, count, data);
- if (retval == ERROR_OK) {
- uint32_t t;
- for (t = 0; t < buf_cnt; t++) {
- if (data[t] != buffer[t]) {
- command_print(CMD_CTX,
- "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
- diffs,
- (unsigned)(t + image.sections[i].base_address),
- data[t],
- buffer[t]);
- if (diffs++ >= 127) {
- command_print(CMD_CTX, "More than 128 errors, the rest are not printed.");
- free(data);
- free(buffer);
- goto done;
- }
- }
- keep_alive();
- }
- }
- free(data);
- }
- } else {
- command_print(CMD_CTX, "address 0x%08" PRIx32 " length 0x%08zx",
- image.sections[i].base_address,
- buf_cnt);
- }
-
- free(buffer);
- image_size += buf_cnt;
- }
- if (diffs > 0)
- command_print(CMD_CTX, "No more differences found.");
-done:
- if (diffs > 0)
- retval = ERROR_FAIL;
- if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
- command_print(CMD_CTX, "verified %" PRIu32 " bytes "
- "in %fs (%0.3f KiB/s)", image_size,
- duration_elapsed(&bench), duration_kbps(&bench, image_size));
- }
+ struct fileio *fileio;
+ uint8_t *buffer;
+ int retval, retvaltemp;
+ target_addr_t address, size;
+ struct duration bench;
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (CMD_ARGC != 3)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[1], address);
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[2], size);
+
+ uint32_t buf_size = (size > 4096) ? 4096 : size;
+ buffer = malloc(buf_size);
+ if (!buffer)
+ return ERROR_FAIL;
+
+ retval = fileio_open(&fileio, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY);
+ if (retval != ERROR_OK) {
+ free(buffer);
+ return retval;
+ }
+
+ duration_start(&bench);
+
+ while (size > 0) {
+ size_t size_written;
+ uint32_t this_run_size = (size > buf_size) ? buf_size : size;
+ retval = target_read_buffer(target, address, this_run_size, buffer);
+ if (retval != ERROR_OK)
+ break;
+
+ retval = fileio_write(fileio, this_run_size, buffer, &size_written);
+ if (retval != ERROR_OK)
+ break;
+
+ size -= this_run_size;
+ address += this_run_size;
+ }
+
+ free(buffer);
+
+ if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
+ size_t filesize;
+ retval = fileio_size(fileio, &filesize);
+ if (retval != ERROR_OK)
+ return retval;
+ command_print(CMD_CTX,
+ "dumped %zu bytes in %fs (%0.3f KiB/s)", filesize,
+ duration_elapsed(&bench), duration_kbps(&bench, filesize));
+ }
+
+ retvaltemp = fileio_close(fileio);
+ if (retvaltemp != ERROR_OK)
+ return retvaltemp;
+
+ return retval;
+}
+
+enum verify_mode {
+ IMAGE_TEST = 0,
+ IMAGE_VERIFY = 1,
+ IMAGE_CHECKSUM_ONLY = 2
+};
- image_close(&image);
+static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode verify)
+{
+ uint8_t *buffer;
+ size_t buf_cnt;
+ uint32_t image_size;
+ int i;
+ int retval;
+ uint32_t checksum = 0;
+ uint32_t mem_checksum = 0;
+
+ struct image image;
+
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (CMD_ARGC < 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (!target) {
+ LOG_ERROR("no target selected");
+ return ERROR_FAIL;
+ }
+
+ struct duration bench;
+ duration_start(&bench);
+
+ if (CMD_ARGC >= 2) {
+ target_addr_t addr;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[1], addr);
+ image.base_address = addr;
+ image.base_address_set = 1;
+ } else {
+ image.base_address_set = 0;
+ image.base_address = 0x0;
+ }
+
+ image.start_address_set = 0;
+
+ retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);
+ if (retval != ERROR_OK)
+ return retval;
+
+ image_size = 0x0;
+ int diffs = 0;
+ retval = ERROR_OK;
+ for (i = 0; i < image.num_sections; i++) {
+ buffer = malloc(image.sections[i].size);
+ if (buffer == NULL) {
+ command_print(CMD_CTX,
+ "error allocating buffer for section (%d bytes)",
+ (int)(image.sections[i].size));
+ break;
+ }
+ retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);
+ if (retval != ERROR_OK) {
+ free(buffer);
+ break;
+ }
+
+ if (verify >= IMAGE_VERIFY) {
+ /* calculate checksum of image */
+ retval = image_calculate_checksum(buffer, buf_cnt, &checksum);
+ if (retval != ERROR_OK) {
+ free(buffer);
+ break;
+ }
+
+ retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
+ if (retval != ERROR_OK) {
+ free(buffer);
+ break;
+ }
+ if ((checksum != mem_checksum) && (verify == IMAGE_CHECKSUM_ONLY)) {
+ LOG_ERROR("checksum mismatch");
+ free(buffer);
+ retval = ERROR_FAIL;
+ goto done;
+ }
+ if (checksum != mem_checksum) {
+ /* failed crc checksum, fall back to a binary compare */
+ uint8_t *data;
+
+ if (diffs == 0)
+ LOG_ERROR("checksum mismatch - attempting binary compare");
+
+ data = malloc(buf_cnt);
+
+ /* Can we use 32bit word accesses? */
+ int size = 1;
+ int count = buf_cnt;
+ if ((count % 4) == 0) {
+ size *= 4;
+ count /= 4;
+ }
+ retval = target_read_memory(target, image.sections[i].base_address, size, count, data);
+ if (retval == ERROR_OK) {
+ uint32_t t;
+ for (t = 0; t < buf_cnt; t++) {
+ if (data[t] != buffer[t]) {
+ command_print(CMD_CTX,
+ "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
+ diffs,
+ (unsigned)(t + image.sections[i].base_address),
+ data[t],
+ buffer[t]);
+ if (diffs++ >= 127) {
+ command_print(CMD_CTX, "More than 128 errors, the rest are not printed.");
+ free(data);
+ free(buffer);
+ goto done;
+ }
+ }
+ keep_alive();
+ }
+ }
+ free(data);
+ }
+ } else {
+ command_print(CMD_CTX, "address " TARGET_ADDR_FMT " length 0x%08zx",
+ image.sections[i].base_address,
+ buf_cnt);
+ }
+
+ free(buffer);
+ image_size += buf_cnt;
+ }
+ if (diffs > 0)
+ command_print(CMD_CTX, "No more differences found.");
+done:
+ if (diffs > 0)
+ retval = ERROR_FAIL;
+ if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
+ command_print(CMD_CTX, "verified %" PRIu32 " bytes "
+ "in %fs (%0.3f KiB/s)", image_size,
+ duration_elapsed(&bench), duration_kbps(&bench, image_size));
+ }
+
+ image_close(&image);
+
+ return retval;
+}
- return retval;
+COMMAND_HANDLER(handle_verify_image_checksum_command)
+{
+ return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, IMAGE_CHECKSUM_ONLY);
}
COMMAND_HANDLER(handle_verify_image_command)
{
- return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, 1);
+ return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, IMAGE_VERIFY);
}
COMMAND_HANDLER(handle_test_image_command)
{
- return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, 0);
+ return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, IMAGE_TEST);
}
static int handle_bp_command_list(struct command_context *cmd_ctx)
{
- struct target *target = get_current_target(cmd_ctx);
- struct breakpoint *breakpoint = target->breakpoints;
- while (breakpoint) {
- if (breakpoint->type == BKPT_SOFT) {
- char *buf = buf_to_str(breakpoint->orig_instr,
- breakpoint->length, 16);
- command_print(cmd_ctx, "IVA breakpoint: 0x%8.8" PRIx32 ", 0x%x, %i, 0x%s",
- breakpoint->address,
- breakpoint->length,
- breakpoint->set, buf);
- free(buf);
- } else {
- if ((breakpoint->address == 0) && (breakpoint->asid != 0))
- command_print(cmd_ctx, "Context breakpoint: 0x%8.8" PRIx32 ", 0x%x, %i",
- breakpoint->asid,
- breakpoint->length, breakpoint->set);
- else if ((breakpoint->address != 0) && (breakpoint->asid != 0)) {
- command_print(cmd_ctx, "Hybrid breakpoint(IVA): 0x%8.8" PRIx32 ", 0x%x, %i",
- breakpoint->address,
- breakpoint->length, breakpoint->set);
- command_print(cmd_ctx, "\t|--->linked with ContextID: 0x%8.8" PRIx32,
- breakpoint->asid);
- } else
- command_print(cmd_ctx, "Breakpoint(IVA): 0x%8.8" PRIx32 ", 0x%x, %i",
- breakpoint->address,
- breakpoint->length, breakpoint->set);
- }
-
- breakpoint = breakpoint->next;
- }
- return ERROR_OK;
+ struct target *target = get_current_target(cmd_ctx);
+ struct breakpoint *breakpoint = target->breakpoints;
+ while (breakpoint) {
+ if (breakpoint->type == BKPT_SOFT) {
+ char *buf = buf_to_str(breakpoint->orig_instr,
+ breakpoint->length, 16);
+ command_print(cmd_ctx, "IVA breakpoint: " TARGET_ADDR_FMT ", 0x%x, %i, 0x%s",
+ breakpoint->address,
+ breakpoint->length,
+ breakpoint->set, buf);
+ free(buf);
+ } else {
+ if ((breakpoint->address == 0) && (breakpoint->asid != 0))
+ command_print(cmd_ctx, "Context breakpoint: 0x%8.8" PRIx32 ", 0x%x, %i",
+ breakpoint->asid,
+ breakpoint->length, breakpoint->set);
+ else if ((breakpoint->address != 0) && (breakpoint->asid != 0)) {
+ command_print(cmd_ctx, "Hybrid breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %i",
+ breakpoint->address,
+ breakpoint->length, breakpoint->set);
+ command_print(cmd_ctx, "\t|--->linked with ContextID: 0x%8.8" PRIx32,
+ breakpoint->asid);
+ } else
+ command_print(cmd_ctx, "Breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %i",
+ breakpoint->address,
+ breakpoint->length, breakpoint->set);
+ }
+
+ breakpoint = breakpoint->next;
+ }
+ return ERROR_OK;
}
static int handle_bp_command_set(struct command_context *cmd_ctx,
- uint32_t addr, uint32_t asid, uint32_t length, int hw)
-{
- struct target *target = get_current_target(cmd_ctx);
- int retval;
-
- if (asid == 0) {
- retval = breakpoint_add(target, addr, length, hw);
- if (ERROR_OK == retval)
- command_print(cmd_ctx, "breakpoint set at 0x%8.8" PRIx32 "", addr);
- else {
- LOG_ERROR("Failure setting breakpoint, the same address(IVA) is already used");
- return retval;
- }
- } else if (addr == 0) {
- if (target->type->add_context_breakpoint == NULL) {
- LOG_WARNING("Context breakpoint not available");
- return ERROR_OK;
- }
- retval = context_breakpoint_add(target, asid, length, hw);
- if (ERROR_OK == retval)
- command_print(cmd_ctx, "Context breakpoint set at 0x%8.8" PRIx32 "", asid);
- else {
- LOG_ERROR("Failure setting breakpoint, the same address(CONTEXTID) is already used");
- return retval;
- }
- } else {
- if (target->type->add_hybrid_breakpoint == NULL) {
- LOG_WARNING("Hybrid breakpoint not available");
- return ERROR_OK;
- }
- retval = hybrid_breakpoint_add(target, addr, asid, length, hw);
- if (ERROR_OK == retval)
- command_print(cmd_ctx, "Hybrid breakpoint set at 0x%8.8" PRIx32 "", asid);
- else {
- LOG_ERROR("Failure setting breakpoint, the same address is already used");
- return retval;
- }
- }
- return ERROR_OK;
+ target_addr_t addr, uint32_t asid, uint32_t length, int hw)
+{
+ struct target *target = get_current_target(cmd_ctx);
+ int retval;
+
+ if (asid == 0) {
+ retval = breakpoint_add(target, addr, length, hw);
+ if (ERROR_OK == retval)
+ command_print(cmd_ctx, "breakpoint set at " TARGET_ADDR_FMT "", addr);
+ else {
+ LOG_ERROR("Failure setting breakpoint, the same address(IVA) is already used");
+ return retval;
+ }
+ } else if (addr == 0) {
+ if (target->type->add_context_breakpoint == NULL) {
+ LOG_WARNING("Context breakpoint not available");
+ return ERROR_OK;
+ }
+ retval = context_breakpoint_add(target, asid, length, hw);
+ if (ERROR_OK == retval)
+ command_print(cmd_ctx, "Context breakpoint set at 0x%8.8" PRIx32 "", asid);
+ else {
+ LOG_ERROR("Failure setting breakpoint, the same address(CONTEXTID) is already used");
+ return retval;
+ }
+ } else {
+ if (target->type->add_hybrid_breakpoint == NULL) {
+ LOG_WARNING("Hybrid breakpoint not available");
+ return ERROR_OK;
+ }
+ retval = hybrid_breakpoint_add(target, addr, asid, length, hw);
+ if (ERROR_OK == retval)
+ command_print(cmd_ctx, "Hybrid breakpoint set at 0x%8.8" PRIx32 "", asid);
+ else {
+ LOG_ERROR("Failure setting breakpoint, the same address is already used");
+ return retval;
+ }
+ }
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_bp_command)
{
- uint32_t addr;
- uint32_t asid;
- uint32_t length;
- int hw = BKPT_SOFT;
-
- switch (CMD_ARGC) {
- case 0:
- return handle_bp_command_list(CMD_CTX);
-
- case 2:
- asid = 0;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
- return handle_bp_command_set(CMD_CTX, addr, asid, length, hw);
-
- case 3:
- if (strcmp(CMD_ARGV[2], "hw") == 0) {
- hw = BKPT_HARD;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
-
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
-
- asid = 0;
- return handle_bp_command_set(CMD_CTX, addr, asid, length, hw);
- } else if (strcmp(CMD_ARGV[2], "hw_ctx") == 0) {
- hw = BKPT_HARD;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], asid);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
- addr = 0;
- return handle_bp_command_set(CMD_CTX, addr, asid, length, hw);
- }
-
- case 4:
- hw = BKPT_HARD;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], asid);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], length);
- return handle_bp_command_set(CMD_CTX, addr, asid, length, hw);
-
- default:
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
+ target_addr_t addr;
+ uint32_t asid;
+ uint32_t length;
+ int hw = BKPT_SOFT;
+
+ switch (CMD_ARGC) {
+ case 0:
+ return handle_bp_command_list(CMD_CTX);
+
+ case 2:
+ asid = 0;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
+ return handle_bp_command_set(CMD_CTX, addr, asid, length, hw);
+
+ case 3:
+ if (strcmp(CMD_ARGV[2], "hw") == 0) {
+ hw = BKPT_HARD;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
+ asid = 0;
+ return handle_bp_command_set(CMD_CTX, addr, asid, length, hw);
+ } else if (strcmp(CMD_ARGV[2], "hw_ctx") == 0) {
+ hw = BKPT_HARD;
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], asid);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
+ addr = 0;
+ return handle_bp_command_set(CMD_CTX, addr, asid, length, hw);
+ }
+
+ case 4:
+ hw = BKPT_HARD;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], asid);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], length);
+ return handle_bp_command_set(CMD_CTX, addr, asid, length, hw);
+
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
}
COMMAND_HANDLER(handle_rbp_command)
{
- if (CMD_ARGC != 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- uint32_t addr;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
-
- struct target *target = get_current_target(CMD_CTX);
- breakpoint_remove(target, addr);
-
- return ERROR_OK;
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ target_addr_t addr;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
+
+ struct target *target = get_current_target(CMD_CTX);
+ breakpoint_remove(target, addr);
+
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_wp_command)
{
- struct target *target = get_current_target(CMD_CTX);
-
- if (CMD_ARGC == 0) {
- struct watchpoint *watchpoint = target->watchpoints;
-
- while (watchpoint) {
- command_print(CMD_CTX, "address: 0x%8.8" PRIx32
- ", len: 0x%8.8" PRIx32
- ", r/w/a: %i, value: 0x%8.8" PRIx32
- ", mask: 0x%8.8" PRIx32,
- watchpoint->address,
- watchpoint->length,
- (int)watchpoint->rw,
- watchpoint->value,
- watchpoint->mask);
- watchpoint = watchpoint->next;
- }
- return ERROR_OK;
- }
-
- enum watchpoint_rw type = WPT_ACCESS;
- uint32_t addr = 0;
- uint32_t length = 0;
- uint32_t data_value = 0x0;
- uint32_t data_mask = 0xffffffff;
-
- switch (CMD_ARGC) {
- case 5:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], data_mask);
- /* fall through */
- case 4:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], data_value);
- /* fall through */
- case 3:
- switch (CMD_ARGV[2][0]) {
- case 'r':
- type = WPT_READ;
- break;
- case 'w':
- type = WPT_WRITE;
- break;
- case 'a':
- type = WPT_ACCESS;
- break;
- default:
- LOG_ERROR("invalid watchpoint mode ('%c')", CMD_ARGV[2][0]);
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
- /* fall through */
- case 2:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
- break;
-
- default:
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- int retval = watchpoint_add(target, addr, length, type,
- data_value, data_mask);
- if (ERROR_OK != retval)
- LOG_ERROR("Failure setting watchpoints");
-
- return retval;
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (CMD_ARGC == 0) {
+ struct watchpoint *watchpoint = target->watchpoints;
+
+ while (watchpoint) {
+ command_print(CMD_CTX, "address: " TARGET_ADDR_FMT
+ ", len: 0x%8.8" PRIx32
+ ", r/w/a: %i, value: 0x%8.8" PRIx32
+ ", mask: 0x%8.8" PRIx32,
+ watchpoint->address,
+ watchpoint->length,
+ (int)watchpoint->rw,
+ watchpoint->value,
+ watchpoint->mask);
+ watchpoint = watchpoint->next;
+ }
+ return ERROR_OK;
+ }
+
+ enum watchpoint_rw type = WPT_ACCESS;
+ uint32_t addr = 0;
+ uint32_t length = 0;
+ uint32_t data_value = 0x0;
+ uint32_t data_mask = 0xffffffff;
+
+ switch (CMD_ARGC) {
+ case 5:
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], data_mask);
+ /* fall through */
+ case 4:
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], data_value);
+ /* fall through */
+ case 3:
+ switch (CMD_ARGV[2][0]) {
+ case 'r':
+ type = WPT_READ;
+ break;
+ case 'w':
+ type = WPT_WRITE;
+ break;
+ case 'a':
+ type = WPT_ACCESS;
+ break;
+ default:
+ LOG_ERROR("invalid watchpoint mode ('%c')", CMD_ARGV[2][0]);
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ /* fall through */
+ case 2:
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
+ break;
+
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ int retval = watchpoint_add(target, addr, length, type,
+ data_value, data_mask);
+ if (ERROR_OK != retval)
+ LOG_ERROR("Failure setting watchpoints");
+
+ return retval;
}
COMMAND_HANDLER(handle_rwp_command)
{
- if (CMD_ARGC != 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- uint32_t addr;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
-
- struct target *target = get_current_target(CMD_CTX);
- watchpoint_remove(target, addr);
-
- return ERROR_OK;
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ uint32_t addr;
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
+
+ struct target *target = get_current_target(CMD_CTX);
+ watchpoint_remove(target, addr);
+
+ return ERROR_OK;
}
/**
@@ -3652,588 +3867,614 @@ COMMAND_HANDLER(handle_rwp_command)
*/
COMMAND_HANDLER(handle_virt2phys_command)
{
- if (CMD_ARGC != 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- uint32_t va;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], va);
- uint32_t pa;
-
- struct target *target = get_current_target(CMD_CTX);
- int retval = target->type->virt2phys(target, va, &pa);
- if (retval == ERROR_OK)
- command_print(CMD_CTX, "Physical address 0x%08" PRIx32 "", pa);
-
- return retval;
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ target_addr_t va;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], va);
+ target_addr_t pa;
+
+ struct target *target = get_current_target(CMD_CTX);
+ int retval = target->type->virt2phys(target, va, &pa);
+ if (retval == ERROR_OK)
+ command_print(CMD_CTX, "Physical address " TARGET_ADDR_FMT "", pa);
+
+ return retval;
}
static void writeData(FILE *f, const void *data, size_t len)
{
- size_t written = fwrite(data, 1, len, f);
- if (written != len)
- LOG_ERROR("failed to write %zu bytes: %s", len, strerror(errno));
+ size_t written = fwrite(data, 1, len, f);
+ if (written != len)
+ LOG_ERROR("failed to write %zu bytes: %s", len, strerror(errno));
}
static void writeLong(FILE *f, int l, struct target *target)
{
- uint8_t val[4];
-
- target_buffer_set_u32(target, val, l);
- writeData(f, val, 4);
+ uint8_t val[4];
+
+ target_buffer_set_u32(target, val, l);
+ writeData(f, val, 4);
}
static void writeString(FILE *f, char *s)
{
- writeData(f, s, strlen(s));
+ writeData(f, s, strlen(s));
}
typedef unsigned char UNIT[2]; /* unit of profiling */
/* Dump a gmon.out histogram file. */
static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filename, bool with_range,
- uint32_t start_address, uint32_t end_address, struct target *target)
-{
- uint32_t i;
- FILE *f = fopen(filename, "w");
- if (f == NULL)
- return;
- writeString(f, "gmon");
- writeLong(f, 0x00000001, target); /* Version */
- writeLong(f, 0, target); /* padding */
- writeLong(f, 0, target); /* padding */
- writeLong(f, 0, target); /* padding */
-
- uint8_t zero = 0; /* GMON_TAG_TIME_HIST */
- writeData(f, &zero, 1);
-
- /* figure out bucket size */
- uint32_t min;
- uint32_t max;
- if (with_range) {
- min = start_address;
- max = end_address;
- } else {
- min = samples[0];
- max = samples[0];
- for (i = 0; i < sampleNum; i++) {
- if (min > samples[i])
- min = samples[i];
- if (max < samples[i])
- max = samples[i];
- }
-
- /* max should be (largest sample + 1)
- * Refer to binutils/gprof/hist.c (find_histogram_for_pc) */
- max++;
- }
-
- int addressSpace = max - min;
- assert(addressSpace >= 2);
-
- /* FIXME: What is the reasonable number of buckets?
- * The profiling result will be more accurate if there are enough buckets. */
- static const uint32_t maxBuckets = 128 * 1024; /* maximum buckets. */
- uint32_t numBuckets = addressSpace / sizeof(UNIT);
- if (numBuckets > maxBuckets)
- numBuckets = maxBuckets;
- int *buckets = malloc(sizeof(int) * numBuckets);
- if (buckets == NULL) {
- fclose(f);
- return;
- }
- memset(buckets, 0, sizeof(int) * numBuckets);
- for (i = 0; i < sampleNum; i++) {
- uint32_t address = samples[i];
-
- if ((address < min) || (max <= address))
- continue;
-
- long long a = address - min;
- long long b = numBuckets;
- long long c = addressSpace;
- int index_t = (a * b) / c; /* danger!!!! int32 overflows */
- buckets[index_t]++;
- }
-
- /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
- writeLong(f, min, target); /* low_pc */
- writeLong(f, max, target); /* high_pc */
- writeLong(f, numBuckets, target); /* # of buckets */
- writeLong(f, 100, target); /* KLUDGE! We lie, ca. 100Hz best case. */
- writeString(f, "seconds");
- for (i = 0; i < (15-strlen("seconds")); i++)
- writeData(f, &zero, 1);
- writeString(f, "s");
-
- /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
-
- char *data = malloc(2 * numBuckets);
- if (data != NULL) {
- for (i = 0; i < numBuckets; i++) {
- int val;
- val = buckets[i];
- if (val > 65535)
- val = 65535;
- data[i * 2] = val&0xff;
- data[i * 2 + 1] = (val >> 8) & 0xff;
- }
- free(buckets);
- writeData(f, data, numBuckets * 2);
- free(data);
- } else
- free(buckets);
-
- fclose(f);
+ uint32_t start_address, uint32_t end_address, struct target *target)
+{
+ uint32_t i;
+ FILE *f = fopen(filename, "w");
+ if (f == NULL)
+ return;
+ writeString(f, "gmon");
+ writeLong(f, 0x00000001, target); /* Version */
+ writeLong(f, 0, target); /* padding */
+ writeLong(f, 0, target); /* padding */
+ writeLong(f, 0, target); /* padding */
+
+ uint8_t zero = 0; /* GMON_TAG_TIME_HIST */
+ writeData(f, &zero, 1);
+
+ /* figure out bucket size */
+ uint32_t min;
+ uint32_t max;
+ if (with_range) {
+ min = start_address;
+ max = end_address;
+ } else {
+ min = samples[0];
+ max = samples[0];
+ for (i = 0; i < sampleNum; i++) {
+ if (min > samples[i])
+ min = samples[i];
+ if (max < samples[i])
+ max = samples[i];
+ }
+
+ /* max should be (largest sample + 1)
+ * Refer to binutils/gprof/hist.c (find_histogram_for_pc) */
+ max++;
+ }
+
+ int addressSpace = max - min;
+ assert(addressSpace >= 2);
+
+ /* FIXME: What is the reasonable number of buckets?
+ * The profiling result will be more accurate if there are enough buckets. */
+ static const uint32_t maxBuckets = 128 * 1024; /* maximum buckets. */
+ uint32_t numBuckets = addressSpace / sizeof(UNIT);
+ if (numBuckets > maxBuckets)
+ numBuckets = maxBuckets;
+ int *buckets = malloc(sizeof(int) * numBuckets);
+ if (buckets == NULL) {
+ fclose(f);
+ return;
+ }
+ memset(buckets, 0, sizeof(int) * numBuckets);
+ for (i = 0; i < sampleNum; i++) {
+ uint32_t address = samples[i];
+
+ if ((address < min) || (max <= address))
+ continue;
+
+ long long a = address - min;
+ long long b = numBuckets;
+ long long c = addressSpace;
+ int index_t = (a * b) / c; /* danger!!!! int32 overflows */
+ buckets[index_t]++;
+ }
+
+ /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
+ writeLong(f, min, target); /* low_pc */
+ writeLong(f, max, target); /* high_pc */
+ writeLong(f, numBuckets, target); /* # of buckets */
+ writeLong(f, 100, target); /* KLUDGE! We lie, ca. 100Hz best case. */
+ writeString(f, "seconds");
+ for (i = 0; i < (15-strlen("seconds")); i++)
+ writeData(f, &zero, 1);
+ writeString(f, "s");
+
+ /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
+
+ char *data = malloc(2 * numBuckets);
+ if (data != NULL) {
+ for (i = 0; i < numBuckets; i++) {
+ int val;
+ val = buckets[i];
+ if (val > 65535)
+ val = 65535;
+ data[i * 2] = val&0xff;
+ data[i * 2 + 1] = (val >> 8) & 0xff;
+ }
+ free(buckets);
+ writeData(f, data, numBuckets * 2);
+ free(data);
+ } else
+ free(buckets);
+
+ fclose(f);
}
/* profiling samples the CPU PC as quickly as OpenOCD is able,
* which will be used as a random sampling of PC */
COMMAND_HANDLER(handle_profile_command)
{
- struct target *target = get_current_target(CMD_CTX);
-
- if ((CMD_ARGC != 2) && (CMD_ARGC != 4))
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- const uint32_t MAX_PROFILE_SAMPLE_NUM = 10000;
- uint32_t offset;
- uint32_t num_of_samples;
- int retval = ERROR_OK;
-
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], offset);
-
- uint32_t *samples = malloc(sizeof(uint32_t) * MAX_PROFILE_SAMPLE_NUM);
- if (samples == NULL) {
- LOG_ERROR("No memory to store samples.");
- return ERROR_FAIL;
- }
-
- /**
- * Some cores let us sample the PC without the
- * annoying halt/resume step; for example, ARMv7 PCSR.
- * Provide a way to use that more efficient mechanism.
- */
- retval = target_profiling(target, samples, MAX_PROFILE_SAMPLE_NUM,
- &num_of_samples, offset);
- if (retval != ERROR_OK) {
- free(samples);
- return retval;
- }
-
- assert(num_of_samples <= MAX_PROFILE_SAMPLE_NUM);
-
- retval = target_poll(target);
- if (retval != ERROR_OK) {
- free(samples);
- return retval;
- }
- if (target->state == TARGET_RUNNING) {
- retval = target_halt(target);
- if (retval != ERROR_OK) {
- free(samples);
- return retval;
- }
- }
-
- retval = target_poll(target);
- if (retval != ERROR_OK) {
- free(samples);
- return retval;
- }
-
- uint32_t start_address = 0;
- uint32_t end_address = 0;
- bool with_range = false;
- if (CMD_ARGC == 4) {
- with_range = true;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], start_address);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], end_address);
- }
-
- write_gmon(samples, num_of_samples, CMD_ARGV[1],
- with_range, start_address, end_address, target);
- command_print(CMD_CTX, "Wrote %s", CMD_ARGV[1]);
-
- free(samples);
- return retval;
+ struct target *target = get_current_target(CMD_CTX);
+
+ if ((CMD_ARGC != 2) && (CMD_ARGC != 4))
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ const uint32_t MAX_PROFILE_SAMPLE_NUM = 10000;
+ uint32_t offset;
+ uint32_t num_of_samples;
+ int retval = ERROR_OK;
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], offset);
+
+ uint32_t *samples = malloc(sizeof(uint32_t) * MAX_PROFILE_SAMPLE_NUM);
+ if (samples == NULL) {
+ LOG_ERROR("No memory to store samples.");
+ return ERROR_FAIL;
+ }
+
+ /**
+ * Some cores let us sample the PC without the
+ * annoying halt/resume step; for example, ARMv7 PCSR.
+ * Provide a way to use that more efficient mechanism.
+ */
+ retval = target_profiling(target, samples, MAX_PROFILE_SAMPLE_NUM,
+ &num_of_samples, offset);
+ if (retval != ERROR_OK) {
+ free(samples);
+ return retval;
+ }
+
+ assert(num_of_samples <= MAX_PROFILE_SAMPLE_NUM);
+
+ retval = target_poll(target);
+ if (retval != ERROR_OK) {
+ free(samples);
+ return retval;
+ }
+ if (target->state == TARGET_RUNNING) {
+ retval = target_halt(target);
+ if (retval != ERROR_OK) {
+ free(samples);
+ return retval;
+ }
+ }
+
+ retval = target_poll(target);
+ if (retval != ERROR_OK) {
+ free(samples);
+ return retval;
+ }
+
+ uint32_t start_address = 0;
+ uint32_t end_address = 0;
+ bool with_range = false;
+ if (CMD_ARGC == 4) {
+ with_range = true;
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], start_address);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], end_address);
+ }
+
+ write_gmon(samples, num_of_samples, CMD_ARGV[1],
+ with_range, start_address, end_address, target);
+ command_print(CMD_CTX, "Wrote %s", CMD_ARGV[1]);
+
+ free(samples);
+ return retval;
}
static int new_int_array_element(Jim_Interp *interp, const char *varname, int idx, uint32_t val)
{
- char *namebuf;
- Jim_Obj *nameObjPtr, *valObjPtr;
- int result;
-
- namebuf = alloc_printf("%s(%d)", varname, idx);
- if (!namebuf)
- return JIM_ERR;
-
- nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
- valObjPtr = Jim_NewIntObj(interp, val);
- if (!nameObjPtr || !valObjPtr) {
- free(namebuf);
- return JIM_ERR;
- }
-
- Jim_IncrRefCount(nameObjPtr);
- Jim_IncrRefCount(valObjPtr);
- result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
- Jim_DecrRefCount(interp, nameObjPtr);
- Jim_DecrRefCount(interp, valObjPtr);
- free(namebuf);
- /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
- return result;
+ char *namebuf;
+ Jim_Obj *nameObjPtr, *valObjPtr;
+ int result;
+
+ namebuf = alloc_printf("%s(%d)", varname, idx);
+ if (!namebuf)
+ return JIM_ERR;
+
+ nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
+ valObjPtr = Jim_NewIntObj(interp, val);
+ if (!nameObjPtr || !valObjPtr) {
+ free(namebuf);
+ return JIM_ERR;
+ }
+
+ Jim_IncrRefCount(nameObjPtr);
+ Jim_IncrRefCount(valObjPtr);
+ result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
+ Jim_DecrRefCount(interp, nameObjPtr);
+ Jim_DecrRefCount(interp, valObjPtr);
+ free(namebuf);
+ /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
+ return result;
}
static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- struct command_context *context;
- struct target *target;
-
- context = current_command_context(interp);
- assert(context != NULL);
-
- target = get_current_target(context);
- if (target == NULL) {
- LOG_ERROR("mem2array: no current target");
- return JIM_ERR;
- }
-
- return target_mem2array(interp, target, argc - 1, argv + 1);
+ struct command_context *context;
+ struct target *target;
+
+ context = current_command_context(interp);
+ assert(context != NULL);
+
+ target = get_current_target(context);
+ if (target == NULL) {
+ LOG_ERROR("mem2array: no current target");
+ return JIM_ERR;
+ }
+
+ return target_mem2array(interp, target, argc - 1, argv + 1);
}
static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv)
{
- long l;
- uint32_t width;
- int len;
- uint32_t addr;
- uint32_t count;
- uint32_t v;
- const char *varname;
- int n, e, retval;
- uint32_t i;
-
- /* argv[1] = name of array to receive the data
- * argv[2] = desired width
- * argv[3] = memory address
- * argv[4] = count of times to read
- */
- if (argc != 4) {
- Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
- return JIM_ERR;
- }
- varname = Jim_GetString(argv[0], &len);
- /* given "foo" get space for worse case "foo(%d)" .. add 20 */
-
- e = Jim_GetLong(interp, argv[1], &l);
- width = l;
- if (e != JIM_OK)
- return e;
-
- e = Jim_GetLong(interp, argv[2], &l);
- addr = l;
- if (e != JIM_OK)
- return e;
- e = Jim_GetLong(interp, argv[3], &l);
- len = l;
- if (e != JIM_OK)
- return e;
- switch (width) {
- case 8:
- width = 1;
- break;
- case 16:
- width = 2;
- break;
- case 32:
- width = 4;
- break;
- default:
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL);
- return JIM_ERR;
- }
- if (len == 0) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
- return JIM_ERR;
- }
- if ((addr + (len * width)) < addr) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
- return JIM_ERR;
- }
- /* absurd transfer size? */
- if (len > 65536) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
- return JIM_ERR;
- }
-
- if ((width == 1) ||
- ((width == 2) && ((addr & 1) == 0)) ||
- ((width == 4) && ((addr & 3) == 0))) {
- /* all is well */
- } else {
- char buf[100];
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads",
- addr,
- width);
- Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
- return JIM_ERR;
- }
-
- /* Transfer loop */
-
- /* index counter */
- n = 0;
-
- size_t buffersize = 4096;
- uint8_t *buffer = malloc(buffersize);
- if (buffer == NULL)
- return JIM_ERR;
-
- /* assume ok */
- e = JIM_OK;
- while (len) {
- /* Slurp... in buffer size chunks */
-
- count = len; /* in objects.. */
- if (count > (buffersize / width))
- count = (buffersize / width);
-
- retval = target_read_memory(target, addr, width, count, buffer);
- if (retval != ERROR_OK) {
- /* BOO !*/
- LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed",
- (unsigned int)addr,
- (int)width,
- (int)count);
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
- e = JIM_ERR;
- break;
- } else {
- v = 0; /* shut up gcc */
- for (i = 0; i < count ; i++, n++) {
- switch (width) {
- case 4:
- v = target_buffer_get_u32(target, &buffer[i*width]);
- break;
- case 2:
- v = target_buffer_get_u16(target, &buffer[i*width]);
- break;
- case 1:
- v = buffer[i] & 0x0ff;
- break;
- }
- new_int_array_element(interp, varname, n, v);
- }
- len -= count;
- addr += count * width;
- }
- }
-
- free(buffer);
-
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
-
- return e;
+ long l;
+ uint32_t width;
+ int len;
+ uint32_t addr;
+ uint32_t count;
+ uint32_t v;
+ const char *varname;
+ const char *phys;
+ bool is_phys;
+ int n, e, retval;
+ uint32_t i;
+
+ /* argv[1] = name of array to receive the data
+ * argv[2] = desired width
+ * argv[3] = memory address
+ * argv[4] = count of times to read
+ */
+ if (argc < 4 || argc > 5) {
+ Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems [phys]");
+ return JIM_ERR;
+ }
+ varname = Jim_GetString(argv[0], &len);
+ /* given "foo" get space for worse case "foo(%d)" .. add 20 */
+
+ e = Jim_GetLong(interp, argv[1], &l);
+ width = l;
+ if (e != JIM_OK)
+ return e;
+
+ e = Jim_GetLong(interp, argv[2], &l);
+ addr = l;
+ if (e != JIM_OK)
+ return e;
+ e = Jim_GetLong(interp, argv[3], &l);
+ len = l;
+ if (e != JIM_OK)
+ return e;
+ is_phys = false;
+ if (argc > 4) {
+ phys = Jim_GetString(argv[4], &n);
+ if (!strncmp(phys, "phys", n))
+ is_phys = true;
+ else
+ return JIM_ERR;
+ }
+ switch (width) {
+ case 8:
+ width = 1;
+ break;
+ case 16:
+ width = 2;
+ break;
+ case 32:
+ width = 4;
+ break;
+ default:
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL);
+ return JIM_ERR;
+ }
+ if (len == 0) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
+ return JIM_ERR;
+ }
+ if ((addr + (len * width)) < addr) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
+ return JIM_ERR;
+ }
+ /* absurd transfer size? */
+ if (len > 65536) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
+ return JIM_ERR;
+ }
+
+ if ((width == 1) ||
+ ((width == 2) && ((addr & 1) == 0)) ||
+ ((width == 4) && ((addr & 3) == 0))) {
+ /* all is well */
+ } else {
+ char buf[100];
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads",
+ addr,
+ width);
+ Jim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL);
+ return JIM_ERR;
+ }
+
+ /* Transfer loop */
+
+ /* index counter */
+ n = 0;
+
+ size_t buffersize = 4096;
+ uint8_t *buffer = malloc(buffersize);
+ if (buffer == NULL)
+ return JIM_ERR;
+
+ /* assume ok */
+ e = JIM_OK;
+ while (len) {
+ /* Slurp... in buffer size chunks */
+
+ count = len; /* in objects.. */
+ if (count > (buffersize / width))
+ count = (buffersize / width);
+
+ if (is_phys)
+ retval = target_read_phys_memory(target, addr, width, count, buffer);
+ else
+ retval = target_read_memory(target, addr, width, count, buffer);
+ if (retval != ERROR_OK) {
+ /* BOO !*/
+ LOG_ERROR("mem2array: Read @ 0x%08" PRIx32 ", w=%" PRId32 ", cnt=%" PRId32 ", failed",
+ addr,
+ width,
+ count);
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
+ e = JIM_ERR;
+ break;
+ } else {
+ v = 0; /* shut up gcc */
+ for (i = 0; i < count ; i++, n++) {
+ switch (width) {
+ case 4:
+ v = target_buffer_get_u32(target, &buffer[i*width]);
+ break;
+ case 2:
+ v = target_buffer_get_u16(target, &buffer[i*width]);
+ break;
+ case 1:
+ v = buffer[i] & 0x0ff;
+ break;
+ }
+ new_int_array_element(interp, varname, n, v);
+ }
+ len -= count;
+ addr += count * width;
+ }
+ }
+
+ free(buffer);
+
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+
+ return e;
}
static int get_int_array_element(Jim_Interp *interp, const char *varname, int idx, uint32_t *val)
{
- char *namebuf;
- Jim_Obj *nameObjPtr, *valObjPtr;
- int result;
- long l;
-
- namebuf = alloc_printf("%s(%d)", varname, idx);
- if (!namebuf)
- return JIM_ERR;
-
- nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
- if (!nameObjPtr) {
- free(namebuf);
- return JIM_ERR;
- }
-
- Jim_IncrRefCount(nameObjPtr);
- valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
- Jim_DecrRefCount(interp, nameObjPtr);
- free(namebuf);
- if (valObjPtr == NULL)
- return JIM_ERR;
-
- result = Jim_GetLong(interp, valObjPtr, &l);
- /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
- *val = l;
- return result;
+ char *namebuf;
+ Jim_Obj *nameObjPtr, *valObjPtr;
+ int result;
+ long l;
+
+ namebuf = alloc_printf("%s(%d)", varname, idx);
+ if (!namebuf)
+ return JIM_ERR;
+
+ nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
+ if (!nameObjPtr) {
+ free(namebuf);
+ return JIM_ERR;
+ }
+
+ Jim_IncrRefCount(nameObjPtr);
+ valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
+ Jim_DecrRefCount(interp, nameObjPtr);
+ free(namebuf);
+ if (valObjPtr == NULL)
+ return JIM_ERR;
+
+ result = Jim_GetLong(interp, valObjPtr, &l);
+ /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
+ *val = l;
+ return result;
}
static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- struct command_context *context;
- struct target *target;
-
- context = current_command_context(interp);
- assert(context != NULL);
-
- target = get_current_target(context);
- if (target == NULL) {
- LOG_ERROR("array2mem: no current target");
- return JIM_ERR;
- }
-
- return target_array2mem(interp, target, argc-1, argv + 1);
+ struct command_context *context;
+ struct target *target;
+
+ context = current_command_context(interp);
+ assert(context != NULL);
+
+ target = get_current_target(context);
+ if (target == NULL) {
+ LOG_ERROR("array2mem: no current target");
+ return JIM_ERR;
+ }
+
+ return target_array2mem(interp, target, argc-1, argv + 1);
}
static int target_array2mem(Jim_Interp *interp, struct target *target,
- int argc, Jim_Obj *const *argv)
-{
- long l;
- uint32_t width;
- int len;
- uint32_t addr;
- uint32_t count;
- uint32_t v;
- const char *varname;
- int n, e, retval;
- uint32_t i;
-
- /* argv[1] = name of array to get the data
- * argv[2] = desired width
- * argv[3] = memory address
- * argv[4] = count to write
- */
- if (argc != 4) {
- Jim_WrongNumArgs(interp, 0, argv, "varname width addr nelems");
- return JIM_ERR;
- }
- varname = Jim_GetString(argv[0], &len);
- /* given "foo" get space for worse case "foo(%d)" .. add 20 */
-
- e = Jim_GetLong(interp, argv[1], &l);
- width = l;
- if (e != JIM_OK)
- return e;
-
- e = Jim_GetLong(interp, argv[2], &l);
- addr = l;
- if (e != JIM_OK)
- return e;
- e = Jim_GetLong(interp, argv[3], &l);
- len = l;
- if (e != JIM_OK)
- return e;
- switch (width) {
- case 8:
- width = 1;
- break;
- case 16:
- width = 2;
- break;
- case 32:
- width = 4;
- break;
- default:
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "Invalid width param, must be 8/16/32", NULL);
- return JIM_ERR;
- }
- if (len == 0) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "array2mem: zero width read?", NULL);
- return JIM_ERR;
- }
- if ((addr + (len * width)) < addr) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "array2mem: addr + len - wraps to zero?", NULL);
- return JIM_ERR;
- }
- /* absurd transfer size? */
- if (len > 65536) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "array2mem: absurd > 64K item request", NULL);
- return JIM_ERR;
- }
-
- if ((width == 1) ||
- ((width == 2) && ((addr & 1) == 0)) ||
- ((width == 4) && ((addr & 3) == 0))) {
- /* all is well */
- } else {
- char buf[100];
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads",
- (unsigned int)addr,
- (int)width);
- Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
- return JIM_ERR;
- }
-
- /* Transfer loop */
-
- /* index counter */
- n = 0;
- /* assume ok */
- e = JIM_OK;
-
- size_t buffersize = 4096;
- uint8_t *buffer = malloc(buffersize);
- if (buffer == NULL)
- return JIM_ERR;
-
- while (len) {
- /* Slurp... in buffer size chunks */
-
- count = len; /* in objects.. */
- if (count > (buffersize / width))
- count = (buffersize / width);
-
- v = 0; /* shut up gcc */
- for (i = 0; i < count; i++, n++) {
- get_int_array_element(interp, varname, n, &v);
- switch (width) {
- case 4:
- target_buffer_set_u32(target, &buffer[i * width], v);
- break;
- case 2:
- target_buffer_set_u16(target, &buffer[i * width], v);
- break;
- case 1:
- buffer[i] = v & 0x0ff;
- break;
- }
- }
- len -= count;
-
- retval = target_write_memory(target, addr, width, count, buffer);
- if (retval != ERROR_OK) {
- /* BOO !*/
- LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed",
- (unsigned int)addr,
- (int)width,
- (int)count);
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL);
- e = JIM_ERR;
- break;
- }
- addr += count * width;
- }
-
- free(buffer);
-
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
-
- return e;
+ int argc, Jim_Obj *const *argv)
+{
+ long l;
+ uint32_t width;
+ int len;
+ uint32_t addr;
+ uint32_t count;
+ uint32_t v;
+ const char *varname;
+ const char *phys;
+ bool is_phys;
+ int n, e, retval;
+ uint32_t i;
+
+ /* argv[1] = name of array to get the data
+ * argv[2] = desired width
+ * argv[3] = memory address
+ * argv[4] = count to write
+ */
+ if (argc < 4 || argc > 5) {
+ Jim_WrongNumArgs(interp, 0, argv, "varname width addr nelems [phys]");
+ return JIM_ERR;
+ }
+ varname = Jim_GetString(argv[0], &len);
+ /* given "foo" get space for worse case "foo(%d)" .. add 20 */
+
+ e = Jim_GetLong(interp, argv[1], &l);
+ width = l;
+ if (e != JIM_OK)
+ return e;
+
+ e = Jim_GetLong(interp, argv[2], &l);
+ addr = l;
+ if (e != JIM_OK)
+ return e;
+ e = Jim_GetLong(interp, argv[3], &l);
+ len = l;
+ if (e != JIM_OK)
+ return e;
+ is_phys = false;
+ if (argc > 4) {
+ phys = Jim_GetString(argv[4], &n);
+ if (!strncmp(phys, "phys", n))
+ is_phys = true;
+ else
+ return JIM_ERR;
+ }
+ switch (width) {
+ case 8:
+ width = 1;
+ break;
+ case 16:
+ width = 2;
+ break;
+ case 32:
+ width = 4;
+ break;
+ default:
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp),
+ "Invalid width param, must be 8/16/32", NULL);
+ return JIM_ERR;
+ }
+ if (len == 0) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp),
+ "array2mem: zero width read?", NULL);
+ return JIM_ERR;
+ }
+ if ((addr + (len * width)) < addr) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp),
+ "array2mem: addr + len - wraps to zero?", NULL);
+ return JIM_ERR;
+ }
+ /* absurd transfer size? */
+ if (len > 65536) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp),
+ "array2mem: absurd > 64K item request", NULL);
+ return JIM_ERR;
+ }
+
+ if ((width == 1) ||
+ ((width == 2) && ((addr & 1) == 0)) ||
+ ((width == 4) && ((addr & 3) == 0))) {
+ /* all is well */
+ } else {
+ char buf[100];
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ sprintf(buf, "array2mem address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads",
+ addr,
+ width);
+ Jim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL);
+ return JIM_ERR;
+ }
+
+ /* Transfer loop */
+
+ /* index counter */
+ n = 0;
+ /* assume ok */
+ e = JIM_OK;
+
+ size_t buffersize = 4096;
+ uint8_t *buffer = malloc(buffersize);
+ if (buffer == NULL)
+ return JIM_ERR;
+
+ while (len) {
+ /* Slurp... in buffer size chunks */
+
+ count = len; /* in objects.. */
+ if (count > (buffersize / width))
+ count = (buffersize / width);
+
+ v = 0; /* shut up gcc */
+ for (i = 0; i < count; i++, n++) {
+ get_int_array_element(interp, varname, n, &v);
+ switch (width) {
+ case 4:
+ target_buffer_set_u32(target, &buffer[i * width], v);
+ break;
+ case 2:
+ target_buffer_set_u16(target, &buffer[i * width], v);
+ break;
+ case 1:
+ buffer[i] = v & 0x0ff;
+ break;
+ }
+ }
+ len -= count;
+
+ if (is_phys)
+ retval = target_write_phys_memory(target, addr, width, count, buffer);
+ else
+ retval = target_write_memory(target, addr, width, count, buffer);
+ if (retval != ERROR_OK) {
+ /* BOO !*/
+ LOG_ERROR("array2mem: Write @ 0x%08" PRIx32 ", w=%" PRId32 ", cnt=%" PRId32 ", failed",
+ addr,
+ width,
+ count);
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL);
+ e = JIM_ERR;
+ break;
+ }
+ addr += count * width;
+ }
+
+ free(buffer);
+
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+
+ return e;
}
/* FIX? should we propagate errors here rather than printing them
@@ -4241,23 +4482,23 @@ static int target_array2mem(Jim_Interp *interp, struct target *target,
*/
void target_handle_event(struct target *target, enum target_event e)
{
- struct target_event_action *teap;
-
- for (teap = target->event_action; teap != NULL; teap = teap->next) {
- if (teap->event == e) {
- LOG_DEBUG("target: (%d) %s (%s) event: %d (%s) action: %s",
- target->target_number,
- target_name(target),
- target_type_name(target),
- e,
- Jim_Nvp_value2name_simple(nvp_target_event, e)->name,
- Jim_GetString(teap->body, NULL));
- if (Jim_EvalObj(teap->interp, teap->body) != JIM_OK) {
- Jim_MakeErrorMessage(teap->interp);
- command_print(NULL, "%s\n", Jim_GetString(Jim_GetResult(teap->interp), NULL));
- }
- }
- }
+ struct target_event_action *teap;
+
+ for (teap = target->event_action; teap != NULL; teap = teap->next) {
+ if (teap->event == e) {
+ LOG_DEBUG("target: (%d) %s (%s) event: %d (%s) action: %s",
+ target->target_number,
+ target_name(target),
+ target_type_name(target),
+ e,
+ Jim_Nvp_value2name_simple(nvp_target_event, e)->name,
+ Jim_GetString(teap->body, NULL));
+ if (Jim_EvalObj(teap->interp, teap->body) != JIM_OK) {
+ Jim_MakeErrorMessage(teap->interp);
+ command_print(NULL, "%s\n", Jim_GetString(Jim_GetResult(teap->interp), NULL));
+ }
+ }
+ }
}
/**
@@ -4265,1919 +4506,2016 @@ void target_handle_event(struct target *target, enum target_event e)
*/
bool target_has_event_action(struct target *target, enum target_event event)
{
- struct target_event_action *teap;
-
- for (teap = target->event_action; teap != NULL; teap = teap->next) {
- if (teap->event == event)
- return true;
- }
- return false;
+ struct target_event_action *teap;
+
+ for (teap = target->event_action; teap != NULL; teap = teap->next) {
+ if (teap->event == event)
+ return true;
+ }
+ return false;
}
enum target_cfg_param {
- TCFG_TYPE,
- TCFG_EVENT,
- TCFG_WORK_AREA_VIRT,
- TCFG_WORK_AREA_PHYS,
- TCFG_WORK_AREA_SIZE,
- TCFG_WORK_AREA_BACKUP,
- TCFG_ENDIAN,
- TCFG_COREID,
- TCFG_CHAIN_POSITION,
- TCFG_DBGBASE,
- TCFG_RTOS,
+ TCFG_TYPE,
+ TCFG_EVENT,
+ TCFG_WORK_AREA_VIRT,
+ TCFG_WORK_AREA_PHYS,
+ TCFG_WORK_AREA_SIZE,
+ TCFG_WORK_AREA_BACKUP,
+ TCFG_ENDIAN,
+ TCFG_COREID,
+ TCFG_CHAIN_POSITION,
+ TCFG_DBGBASE,
+ TCFG_CTIBASE,
+ TCFG_RTOS,
+ TCFG_DEFER_EXAMINE,
};
static Jim_Nvp nvp_config_opts[] = {
- { .name = "-type", .value = TCFG_TYPE },
- { .name = "-event", .value = TCFG_EVENT },
- { .name = "-work-area-virt", .value = TCFG_WORK_AREA_VIRT },
- { .name = "-work-area-phys", .value = TCFG_WORK_AREA_PHYS },
- { .name = "-work-area-size", .value = TCFG_WORK_AREA_SIZE },
- { .name = "-work-area-backup", .value = TCFG_WORK_AREA_BACKUP },
- { .name = "-endian" , .value = TCFG_ENDIAN },
- { .name = "-coreid", .value = TCFG_COREID },
- { .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
- { .name = "-dbgbase", .value = TCFG_DBGBASE },
- { .name = "-rtos", .value = TCFG_RTOS },
- { .name = NULL, .value = -1 }
+ { .name = "-type", .value = TCFG_TYPE },
+ { .name = "-event", .value = TCFG_EVENT },
+ { .name = "-work-area-virt", .value = TCFG_WORK_AREA_VIRT },
+ { .name = "-work-area-phys", .value = TCFG_WORK_AREA_PHYS },
+ { .name = "-work-area-size", .value = TCFG_WORK_AREA_SIZE },
+ { .name = "-work-area-backup", .value = TCFG_WORK_AREA_BACKUP },
+ { .name = "-endian" , .value = TCFG_ENDIAN },
+ { .name = "-coreid", .value = TCFG_COREID },
+ { .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
+ { .name = "-dbgbase", .value = TCFG_DBGBASE },
+ { .name = "-ctibase", .value = TCFG_CTIBASE },
+ { .name = "-rtos", .value = TCFG_RTOS },
+ { .name = "-defer-examine", .value = TCFG_DEFER_EXAMINE },
+ { .name = NULL, .value = -1 }
};
static int target_configure(Jim_GetOptInfo *goi, struct target *target)
{
- Jim_Nvp *n;
- Jim_Obj *o;
- jim_wide w;
- int e;
-
- /* parse config or cget options ... */
- while (goi->argc > 0) {
- Jim_SetEmptyResult(goi->interp);
- /* Jim_GetOpt_Debug(goi); */
-
- if (target->type->target_jim_configure) {
- /* target defines a configure function */
- /* target gets first dibs on parameters */
- e = (*(target->type->target_jim_configure))(target, goi);
- if (e == JIM_OK) {
- /* more? */
- continue;
- }
- if (e == JIM_ERR) {
- /* An error */
- return e;
- }
- /* otherwise we 'continue' below */
- }
- e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
- if (e != JIM_OK) {
- Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
- return e;
- }
- switch (n->value) {
- case TCFG_TYPE:
- /* not setable */
- if (goi->isconfigure) {
- Jim_SetResultFormatted(goi->interp,
- "not settable: %s", n->name);
- return JIM_ERR;
- } else {
-no_params:
- if (goi->argc != 0) {
- Jim_WrongNumArgs(goi->interp,
- goi->argc, goi->argv,
- "NO PARAMS");
- return JIM_ERR;
- }
- }
- Jim_SetResultString(goi->interp,
- target_type_name(target), -1);
- /* loop for more */
- break;
- case TCFG_EVENT:
- if (goi->argc == 0) {
- Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ...");
- return JIM_ERR;
- }
-
- e = Jim_GetOpt_Nvp(goi, nvp_target_event, &n);
- if (e != JIM_OK) {
- Jim_GetOpt_NvpUnknown(goi, nvp_target_event, 1);
- return e;
- }
-
- if (goi->isconfigure) {
- if (goi->argc != 1) {
- Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
- return JIM_ERR;
- }
- } else {
- if (goi->argc != 0) {
- Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
- return JIM_ERR;
- }
- }
-
- {
- struct target_event_action *teap;
-
- teap = target->event_action;
- /* replace existing? */
- while (teap) {
- if (teap->event == (enum target_event)n->value)
- break;
- teap = teap->next;
- }
-
- if (goi->isconfigure) {
- bool replace = true;
- if (teap == NULL) {
- /* create new */
- teap = calloc(1, sizeof(*teap));
- replace = false;
- }
- teap->event = n->value;
- teap->interp = goi->interp;
- Jim_GetOpt_Obj(goi, &o);
- if (teap->body)
- Jim_DecrRefCount(teap->interp, teap->body);
- teap->body = Jim_DuplicateObj(goi->interp, o);
- /*
- * FIXME:
- * Tcl/TK - "tk events" have a nice feature.
- * See the "BIND" command.
- * We should support that here.
- * You can specify %X and %Y in the event code.
- * The idea is: %T - target name.
- * The idea is: %N - target number
- * The idea is: %E - event name.
- */
- Jim_IncrRefCount(teap->body);
-
- if (!replace) {
- /* add to head of event list */
- teap->next = target->event_action;
- target->event_action = teap;
- }
- Jim_SetEmptyResult(goi->interp);
- } else {
- /* get */
- if (teap == NULL)
- Jim_SetEmptyResult(goi->interp);
- else
- Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, teap->body));
- }
- }
- /* loop for more */
- break;
-
- case TCFG_WORK_AREA_VIRT:
- if (goi->isconfigure) {
- target_free_all_working_areas(target);
- e = Jim_GetOpt_Wide(goi, &w);
- if (e != JIM_OK)
- return e;
- target->working_area_virt = w;
- target->working_area_virt_spec = true;
- } else {
- if (goi->argc != 0)
- goto no_params;
- }
- Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_virt));
- /* loop for more */
- break;
-
- case TCFG_WORK_AREA_PHYS:
- if (goi->isconfigure) {
- target_free_all_working_areas(target);
- e = Jim_GetOpt_Wide(goi, &w);
- if (e != JIM_OK)
- return e;
- target->working_area_phys = w;
- target->working_area_phys_spec = true;
- } else {
- if (goi->argc != 0)
- goto no_params;
- }
- Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_phys));
- /* loop for more */
- break;
-
- case TCFG_WORK_AREA_SIZE:
- if (goi->isconfigure) {
- target_free_all_working_areas(target);
- e = Jim_GetOpt_Wide(goi, &w);
- if (e != JIM_OK)
- return e;
- target->working_area_size = w;
- } else {
- if (goi->argc != 0)
- goto no_params;
- }
- Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size));
- /* loop for more */
- break;
-
- case TCFG_WORK_AREA_BACKUP:
- if (goi->isconfigure) {
- target_free_all_working_areas(target);
- e = Jim_GetOpt_Wide(goi, &w);
- if (e != JIM_OK)
- return e;
- /* make this exactly 1 or 0 */
- target->backup_working_area = (!!w);
- } else {
- if (goi->argc != 0)
- goto no_params;
- }
- Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->backup_working_area));
- /* loop for more e*/
- break;
-
-
- case TCFG_ENDIAN:
- if (goi->isconfigure) {
- e = Jim_GetOpt_Nvp(goi, nvp_target_endian, &n);
- if (e != JIM_OK) {
- Jim_GetOpt_NvpUnknown(goi, nvp_target_endian, 1);
- return e;
- }
- target->endianness = n->value;
- } else {
- if (goi->argc != 0)
- goto no_params;
- }
- n = Jim_Nvp_value2name_simple(nvp_target_endian, target->endianness);
- if (n->name == NULL) {
- target->endianness = TARGET_LITTLE_ENDIAN;
- n = Jim_Nvp_value2name_simple(nvp_target_endian, target->endianness);
- }
- Jim_SetResultString(goi->interp, n->name, -1);
- /* loop for more */
- break;
-
- case TCFG_COREID:
- if (goi->isconfigure) {
- e = Jim_GetOpt_Wide(goi, &w);
- if (e != JIM_OK)
- return e;
- target->coreid = (int32_t)w;
- } else {
- if (goi->argc != 0)
- goto no_params;
- }
- Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size));
- /* loop for more */
- break;
-
- case TCFG_CHAIN_POSITION:
- if (goi->isconfigure) {
- Jim_Obj *o_t;
- struct jtag_tap *tap;
- target_free_all_working_areas(target);
- e = Jim_GetOpt_Obj(goi, &o_t);
- if (e != JIM_OK)
- return e;
- tap = jtag_tap_by_jim_obj(goi->interp, o_t);
- if (tap == NULL)
- return JIM_ERR;
- /* make this exactly 1 or 0 */
- target->tap = tap;
- } else {
- if (goi->argc != 0)
- goto no_params;
- }
- Jim_SetResultString(goi->interp, target->tap->dotted_name, -1);
- /* loop for more e*/
- break;
- case TCFG_DBGBASE:
- if (goi->isconfigure) {
- e = Jim_GetOpt_Wide(goi, &w);
- if (e != JIM_OK)
- return e;
- target->dbgbase = (uint32_t)w;
- target->dbgbase_set = true;
- } else {
- if (goi->argc != 0)
- goto no_params;
- }
- Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->dbgbase));
- /* loop for more */
- break;
-
- case TCFG_RTOS:
- /* RTOS */
- {
- int result = rtos_create(goi, target);
- if (result != JIM_OK)
- return result;
- }
- /* loop for more */
- break;
- }
- } /* while (goi->argc) */
-
-
- /* done - we return */
- return JIM_OK;
+ Jim_Nvp *n;
+ Jim_Obj *o;
+ jim_wide w;
+ int e;
+
+ /* parse config or cget options ... */
+ while (goi->argc > 0) {
+ Jim_SetEmptyResult(goi->interp);
+ /* Jim_GetOpt_Debug(goi); */
+
+ if (target->type->target_jim_configure) {
+ /* target defines a configure function */
+ /* target gets first dibs on parameters */
+ e = (*(target->type->target_jim_configure))(target, goi);
+ if (e == JIM_OK) {
+ /* more? */
+ continue;
+ }
+ if (e == JIM_ERR) {
+ /* An error */
+ return e;
+ }
+ /* otherwise we 'continue' below */
+ }
+ e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
+ if (e != JIM_OK) {
+ Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
+ return e;
+ }
+ switch (n->value) {
+ case TCFG_TYPE:
+ /* not setable */
+ if (goi->isconfigure) {
+ Jim_SetResultFormatted(goi->interp,
+ "not settable: %s", n->name);
+ return JIM_ERR;
+ } else {
+ no_params:
+ if (goi->argc != 0) {
+ Jim_WrongNumArgs(goi->interp,
+ goi->argc, goi->argv,
+ "NO PARAMS");
+ return JIM_ERR;
+ }
+ }
+ Jim_SetResultString(goi->interp,
+ target_type_name(target), -1);
+ /* loop for more */
+ break;
+ case TCFG_EVENT:
+ if (goi->argc == 0) {
+ Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ...");
+ return JIM_ERR;
+ }
+
+ e = Jim_GetOpt_Nvp(goi, nvp_target_event, &n);
+ if (e != JIM_OK) {
+ Jim_GetOpt_NvpUnknown(goi, nvp_target_event, 1);
+ return e;
+ }
+
+ if (goi->isconfigure) {
+ if (goi->argc != 1) {
+ Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
+ return JIM_ERR;
+ }
+ } else {
+ if (goi->argc != 0) {
+ Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
+ return JIM_ERR;
+ }
+ }
+
+ {
+ struct target_event_action *teap;
+
+ teap = target->event_action;
+ /* replace existing? */
+ while (teap) {
+ if (teap->event == (enum target_event)n->value)
+ break;
+ teap = teap->next;
+ }
+
+ if (goi->isconfigure) {
+ bool replace = true;
+ if (teap == NULL) {
+ /* create new */
+ teap = calloc(1, sizeof(*teap));
+ replace = false;
+ }
+ teap->event = n->value;
+ teap->interp = goi->interp;
+ Jim_GetOpt_Obj(goi, &o);
+ if (teap->body)
+ Jim_DecrRefCount(teap->interp, teap->body);
+ teap->body = Jim_DuplicateObj(goi->interp, o);
+ /*
+ * FIXME:
+ * Tcl/TK - "tk events" have a nice feature.
+ * See the "BIND" command.
+ * We should support that here.
+ * You can specify %X and %Y in the event code.
+ * The idea is: %T - target name.
+ * The idea is: %N - target number
+ * The idea is: %E - event name.
+ */
+ Jim_IncrRefCount(teap->body);
+
+ if (!replace) {
+ /* add to head of event list */
+ teap->next = target->event_action;
+ target->event_action = teap;
+ }
+ Jim_SetEmptyResult(goi->interp);
+ } else {
+ /* get */
+ if (teap == NULL)
+ Jim_SetEmptyResult(goi->interp);
+ else
+ Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, teap->body));
+ }
+ }
+ /* loop for more */
+ break;
+
+ case TCFG_WORK_AREA_VIRT:
+ if (goi->isconfigure) {
+ target_free_all_working_areas(target);
+ e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK)
+ return e;
+ target->working_area_virt = w;
+ target->working_area_virt_spec = true;
+ } else {
+ if (goi->argc != 0)
+ goto no_params;
+ }
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_virt));
+ /* loop for more */
+ break;
+
+ case TCFG_WORK_AREA_PHYS:
+ if (goi->isconfigure) {
+ target_free_all_working_areas(target);
+ e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK)
+ return e;
+ target->working_area_phys = w;
+ target->working_area_phys_spec = true;
+ } else {
+ if (goi->argc != 0)
+ goto no_params;
+ }
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_phys));
+ /* loop for more */
+ break;
+
+ case TCFG_WORK_AREA_SIZE:
+ if (goi->isconfigure) {
+ target_free_all_working_areas(target);
+ e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK)
+ return e;
+ target->working_area_size = w;
+ } else {
+ if (goi->argc != 0)
+ goto no_params;
+ }
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size));
+ /* loop for more */
+ break;
+
+ case TCFG_WORK_AREA_BACKUP:
+ if (goi->isconfigure) {
+ target_free_all_working_areas(target);
+ e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK)
+ return e;
+ /* make this exactly 1 or 0 */
+ target->backup_working_area = (!!w);
+ } else {
+ if (goi->argc != 0)
+ goto no_params;
+ }
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->backup_working_area));
+ /* loop for more e*/
+ break;
+
+
+ case TCFG_ENDIAN:
+ if (goi->isconfigure) {
+ e = Jim_GetOpt_Nvp(goi, nvp_target_endian, &n);
+ if (e != JIM_OK) {
+ Jim_GetOpt_NvpUnknown(goi, nvp_target_endian, 1);
+ return e;
+ }
+ target->endianness = n->value;
+ } else {
+ if (goi->argc != 0)
+ goto no_params;
+ }
+ n = Jim_Nvp_value2name_simple(nvp_target_endian, target->endianness);
+ if (n->name == NULL) {
+ target->endianness = TARGET_LITTLE_ENDIAN;
+ n = Jim_Nvp_value2name_simple(nvp_target_endian, target->endianness);
+ }
+ Jim_SetResultString(goi->interp, n->name, -1);
+ /* loop for more */
+ break;
+
+ case TCFG_COREID:
+ if (goi->isconfigure) {
+ e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK)
+ return e;
+ target->coreid = (int32_t)w;
+ } else {
+ if (goi->argc != 0)
+ goto no_params;
+ }
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size));
+ /* loop for more */
+ break;
+
+ case TCFG_CHAIN_POSITION:
+ if (goi->isconfigure) {
+ Jim_Obj *o_t;
+ struct jtag_tap *tap;
+ target_free_all_working_areas(target);
+ e = Jim_GetOpt_Obj(goi, &o_t);
+ if (e != JIM_OK)
+ return e;
+ tap = jtag_tap_by_jim_obj(goi->interp, o_t);
+ if (tap == NULL)
+ return JIM_ERR;
+ /* make this exactly 1 or 0 */
+ target->tap = tap;
+ } else {
+ if (goi->argc != 0)
+ goto no_params;
+ }
+ Jim_SetResultString(goi->interp, target->tap->dotted_name, -1);
+ /* loop for more e*/
+ break;
+ case TCFG_DBGBASE:
+ if (goi->isconfigure) {
+ e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK)
+ return e;
+ target->dbgbase = (uint32_t)w;
+ target->dbgbase_set = true;
+ } else {
+ if (goi->argc != 0)
+ goto no_params;
+ }
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->dbgbase));
+ /* loop for more */
+ break;
+ case TCFG_CTIBASE:
+ if (goi->isconfigure) {
+ e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK)
+ return e;
+ target->ctibase = (uint32_t)w;
+ target->ctibase_set = true;
+ } else {
+ if (goi->argc != 0)
+ goto no_params;
+ }
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->ctibase));
+ /* loop for more */
+ break;
+ case TCFG_RTOS:
+ /* RTOS */
+ {
+ int result = rtos_create(goi, target);
+ if (result != JIM_OK)
+ return result;
+ }
+ /* loop for more */
+ break;
+
+ case TCFG_DEFER_EXAMINE:
+ /* DEFER_EXAMINE */
+ target->defer_examine = true;
+ /* loop for more */
+ break;
+
+ }
+ } /* while (goi->argc) */
+
+
+ /* done - we return */
+ return JIM_OK;
}
static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
- Jim_GetOptInfo goi;
-
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
- goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure");
- int need_args = 1 + goi.isconfigure;
- if (goi.argc < need_args) {
- Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
- goi.isconfigure
- ? "missing: -option VALUE ..."
- : "missing: -option ...");
- return JIM_ERR;
- }
- struct target *target = Jim_CmdPrivData(goi.interp);
- return target_configure(&goi, target);
-}
-
-static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
-
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
-
- if (goi.argc < 2 || goi.argc > 4) {
- Jim_SetResultFormatted(goi.interp,
- "usage: %s [phys] []", cmd_name);
- return JIM_ERR;
- }
-
- target_write_fn fn;
- fn = target_write_memory;
-
- int e;
- if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) {
- /* consume it */
- struct Jim_Obj *obj;
- e = Jim_GetOpt_Obj(&goi, &obj);
- if (e != JIM_OK)
- return e;
-
- fn = target_write_phys_memory;
- }
-
- jim_wide a;
- e = Jim_GetOpt_Wide(&goi, &a);
- if (e != JIM_OK)
- return e;
-
- jim_wide b;
- e = Jim_GetOpt_Wide(&goi, &b);
- if (e != JIM_OK)
- return e;
-
- jim_wide c = 1;
- if (goi.argc == 1) {
- e = Jim_GetOpt_Wide(&goi, &c);
- if (e != JIM_OK)
- return e;
- }
-
- /* all args must be consumed */
- if (goi.argc != 0)
- return JIM_ERR;
-
- struct target *target = Jim_CmdPrivData(goi.interp);
- unsigned data_size;
- if (strcasecmp(cmd_name, "mww") == 0)
- data_size = 4;
- else if (strcasecmp(cmd_name, "mwh") == 0)
- data_size = 2;
- else if (strcasecmp(cmd_name, "mwb") == 0)
- data_size = 1;
- else {
- LOG_ERROR("command '%s' unknown: ", cmd_name);
- return JIM_ERR;
- }
-
- return (target_fill_mem(target, a, fn, data_size, b, c) == ERROR_OK) ? JIM_OK : JIM_ERR;
-}
-
-/**
-* @brief Reads an array of words/halfwords/bytes from target memory starting at specified address.
-*
-* Usage: mdw [phys] [] - for 32 bit reads
-* mdh [phys] [] - for 16 bit reads
-* mdb [phys] [] - for 8 bit reads
-*
-* Count defaults to 1.
-*
-* Calls target_read_memory or target_read_phys_memory depending on
-* the presence of the "phys" argument
-* Reads the target memory in blocks of max. 32 bytes, and returns an array of ints formatted
-* to int representation in base16.
-* Also outputs read data in a human readable form using command_print
-*
-* @param phys if present target_read_phys_memory will be used instead of target_read_memory
-* @param address address where to start the read. May be specified in decimal or hex using the standard "0x" prefix
-* @param count optional count parameter to read an array of values. If not specified, defaults to 1.
-* @returns: JIM_ERR on error or JIM_OK on success and sets the result string to an array of ascii formatted numbers
-* on success, with [] number of elements.
-*
-* In case of little endian target:
-* Example1: "mdw 0x00000000" returns "10123456"
-* Exmaple2: "mdh 0x00000000 1" returns "3456"
-* Example3: "mdb 0x00000000" returns "56"
-* Example4: "mdh 0x00000000 2" returns "3456 1012"
-* Example5: "mdb 0x00000000 3" returns "56 34 12"
-**/
-static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
-
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
-
- if ((goi.argc < 1) || (goi.argc > 3)) {
- Jim_SetResultFormatted(goi.interp,
- "usage: %s [phys] []", cmd_name);
- return JIM_ERR;
- }
-
- int (*fn)(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
- fn = target_read_memory;
-
- int e;
- if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) {
- /* consume it */
- struct Jim_Obj *obj;
- e = Jim_GetOpt_Obj(&goi, &obj);
- if (e != JIM_OK)
- return e;
-
- fn = target_read_phys_memory;
- }
-
- /* Read address parameter */
- jim_wide addr;
- e = Jim_GetOpt_Wide(&goi, &addr);
- if (e != JIM_OK)
- return JIM_ERR;
-
- /* If next parameter exists, read it out as the count parameter, if not, set it to 1 (default) */
- jim_wide count;
- if (goi.argc == 1) {
- e = Jim_GetOpt_Wide(&goi, &count);
- if (e != JIM_OK)
- return JIM_ERR;
- } else
- count = 1;
-
- /* all args must be consumed */
- if (goi.argc != 0)
- return JIM_ERR;
-
- jim_wide dwidth = 1; /* shut up gcc */
- if (strcasecmp(cmd_name, "mdw") == 0)
- dwidth = 4;
- else if (strcasecmp(cmd_name, "mdh") == 0)
- dwidth = 2;
- else if (strcasecmp(cmd_name, "mdb") == 0)
- dwidth = 1;
- else {
- LOG_ERROR("command '%s' unknown: ", cmd_name);
- return JIM_ERR;
- }
-
- /* convert count to "bytes" */
- int bytes = count * dwidth;
-
- struct target *target = Jim_CmdPrivData(goi.interp);
- uint8_t target_buf[32];
- jim_wide x, y, z;
- while (bytes > 0) {
- y = (bytes < 16) ? bytes : 16; /* y = min(bytes, 16); */
-
- /* Try to read out next block */
- e = fn(target, addr, dwidth, y / dwidth, target_buf);
-
- if (e != ERROR_OK) {
- Jim_SetResultFormatted(interp, "error reading target @ 0x%08lx", (long)addr);
- return JIM_ERR;
- }
-
- command_print_sameline(NULL, "0x%08x ", (int)(addr));
- switch (dwidth) {
- case 4:
- for (x = 0; x < 16 && x < y; x += 4) {
- z = target_buffer_get_u32(target, &(target_buf[x]));
- command_print_sameline(NULL, "%08x ", (int)(z));
- }
- for (; (x < 16) ; x += 4)
- command_print_sameline(NULL, " ");
- break;
- case 2:
- for (x = 0; x < 16 && x < y; x += 2) {
- z = target_buffer_get_u16(target, &(target_buf[x]));
- command_print_sameline(NULL, "%04x ", (int)(z));
- }
- for (; (x < 16) ; x += 2)
- command_print_sameline(NULL, " ");
- break;
- case 1:
- default:
- for (x = 0 ; (x < 16) && (x < y) ; x += 1) {
- z = target_buffer_get_u8(target, &(target_buf[x]));
- command_print_sameline(NULL, "%02x ", (int)(z));
- }
- for (; (x < 16) ; x += 1)
- command_print_sameline(NULL, " ");
- break;
- }
- /* ascii-ify the bytes */
- for (x = 0 ; x < y ; x++) {
- if ((target_buf[x] >= 0x20) &&
- (target_buf[x] <= 0x7e)) {
- /* good */
- } else {
- /* smack it */
- target_buf[x] = '.';
- }
- }
- /* space pad */
- while (x < 16) {
- target_buf[x] = ' ';
- x++;
- }
- /* terminate */
- target_buf[16] = 0;
- /* print - with a newline */
- command_print_sameline(NULL, "%s\n", target_buf);
- /* NEXT... */
- bytes -= 16;
- addr += 16;
- }
- return JIM_OK;
-}
-
-static int jim_target_mem2array(Jim_Interp *interp,
- int argc, Jim_Obj *const *argv)
-{
- struct target *target = Jim_CmdPrivData(interp);
- return target_mem2array(interp, target, argc - 1, argv + 1);
-}
-
-static int jim_target_array2mem(Jim_Interp *interp,
- int argc, Jim_Obj *const *argv)
-{
- struct target *target = Jim_CmdPrivData(interp);
- return target_array2mem(interp, target, argc - 1, argv + 1);
-}
-
-static int jim_target_tap_disabled(Jim_Interp *interp)
-{
- Jim_SetResultFormatted(interp, "[TAP is disabled]");
- return JIM_ERR;
-}
-
-static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
- return JIM_ERR;
- }
- struct target *target = Jim_CmdPrivData(interp);
- if (!target->tap->enabled)
- return jim_target_tap_disabled(interp);
-
- int e = target->type->examine(target);
- if (e != ERROR_OK)
- return JIM_ERR;
- return JIM_OK;
-}
-
-static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
- return JIM_ERR;
- }
- struct target *target = Jim_CmdPrivData(interp);
-
- if (target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT) != ERROR_OK)
- return JIM_ERR;
-
- return JIM_OK;
-}
-
-static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
- return JIM_ERR;
- }
- struct target *target = Jim_CmdPrivData(interp);
- if (!target->tap->enabled)
- return jim_target_tap_disabled(interp);
-
- int e;
- if (!(target_was_examined(target)))
- e = ERROR_TARGET_NOT_EXAMINED;
- else
- e = target->type->poll(target);
- if (e != ERROR_OK)
- return JIM_ERR;
- return JIM_OK;
-}
-
-static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
-
- if (goi.argc != 2) {
- Jim_WrongNumArgs(interp, 0, argv,
- "([tT]|[fF]|assert|deassert) BOOL");
- return JIM_ERR;
- }
-
- Jim_Nvp *n;
- int e = Jim_GetOpt_Nvp(&goi, nvp_assert, &n);
- if (e != JIM_OK) {
- Jim_GetOpt_NvpUnknown(&goi, nvp_assert, 1);
- return e;
- }
- /* the halt or not param */
- jim_wide a;
- e = Jim_GetOpt_Wide(&goi, &a);
- if (e != JIM_OK)
- return e;
-
- struct target *target = Jim_CmdPrivData(goi.interp);
- if (!target->tap->enabled)
- return jim_target_tap_disabled(interp);
- if (!(target_was_examined(target))) {
- LOG_ERROR("Target not examined yet");
- return ERROR_TARGET_NOT_EXAMINED;
- }
- if (!target->type->assert_reset || !target->type->deassert_reset) {
- Jim_SetResultFormatted(interp,
- "No target-specific reset for %s",
- target_name(target));
- return JIM_ERR;
- }
- /* determine if we should halt or not. */
- target->reset_halt = !!a;
- /* When this happens - all workareas are invalid. */
- target_free_all_working_areas_restore(target, 0);
-
- /* do the assert */
- if (n->value == NVP_ASSERT)
- e = target->type->assert_reset(target);
- else
- e = target->type->deassert_reset(target);
- return (e == ERROR_OK) ? JIM_OK : JIM_ERR;
-}
-
-static int jim_target_halt(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
- return JIM_ERR;
- }
- struct target *target = Jim_CmdPrivData(interp);
- if (!target->tap->enabled)
- return jim_target_tap_disabled(interp);
- int e = target->type->halt(target);
- return (e == ERROR_OK) ? JIM_OK : JIM_ERR;
-}
-
-static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
-
- /* params: statename timeoutmsecs */
- if (goi.argc != 2) {
- const char *cmd_name = Jim_GetString(argv[0], NULL);
- Jim_SetResultFormatted(goi.interp,
- "%s ", cmd_name);
- return JIM_ERR;
- }
-
- Jim_Nvp *n;
- int e = Jim_GetOpt_Nvp(&goi, nvp_target_state, &n);
- if (e != JIM_OK) {
- Jim_GetOpt_NvpUnknown(&goi, nvp_target_state, 1);
- return e;
- }
- jim_wide a;
- e = Jim_GetOpt_Wide(&goi, &a);
- if (e != JIM_OK)
- return e;
- struct target *target = Jim_CmdPrivData(interp);
- if (!target->tap->enabled)
- return jim_target_tap_disabled(interp);
-
- e = target_wait_state(target, n->value, a);
- if (e != ERROR_OK) {
- Jim_Obj *eObj = Jim_NewIntObj(interp, e);
- Jim_SetResultFormatted(goi.interp,
- "target: %s wait %s fails (%#s) %s",
- target_name(target), n->name,
- eObj, target_strerror_safe(e));
- Jim_FreeNewObj(interp, eObj);
- return JIM_ERR;
- }
- return JIM_OK;
-}
-/* List for human, Events defined for this target.
- * scripts/programs should use 'name cget -event NAME'
- */
-static int jim_target_event_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx != NULL);
-
- struct target *target = Jim_CmdPrivData(interp);
- struct target_event_action *teap = target->event_action;
- command_print(cmd_ctx, "Event actions for target (%d) %s\n",
- target->target_number,
- target_name(target));
- command_print(cmd_ctx, "%-25s | Body", "Event");
- command_print(cmd_ctx, "------------------------- | "
- "----------------------------------------");
- while (teap) {
- Jim_Nvp *opt = Jim_Nvp_value2name_simple(nvp_target_event, teap->event);
- command_print(cmd_ctx, "%-25s | %s",
- opt->name, Jim_GetString(teap->body, NULL));
- teap = teap->next;
- }
- command_print(cmd_ctx, "***END***");
- return JIM_OK;
-}
-static int jim_target_current_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
- return JIM_ERR;
- }
- struct target *target = Jim_CmdPrivData(interp);
- Jim_SetResultString(interp, target_state_name(target), -1);
- return JIM_OK;
-}
-static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
- if (goi.argc != 1) {
- const char *cmd_name = Jim_GetString(argv[0], NULL);
- Jim_SetResultFormatted(goi.interp, "%s ", cmd_name);
- return JIM_ERR;
- }
- Jim_Nvp *n;
- int e = Jim_GetOpt_Nvp(&goi, nvp_target_event, &n);
- if (e != JIM_OK) {
- Jim_GetOpt_NvpUnknown(&goi, nvp_target_event, 1);
- return e;
- }
- struct target *target = Jim_CmdPrivData(interp);
- target_handle_event(target, n->value);
- return JIM_OK;
-}
-
-static const struct command_registration target_instance_command_handlers[] = {
- {
- .name = "configure",
- .mode = COMMAND_CONFIG,
- .jim_handler = jim_target_configure,
- .help = "configure a new target for use",
- .usage = "[target_attribute ...]",
- },
- {
- .name = "cget",
- .mode = COMMAND_ANY,
- .jim_handler = jim_target_configure,
- .help = "returns the specified target attribute",
- .usage = "target_attribute",
- },
- {
- .name = "mww",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_mw,
- .help = "Write 32-bit word(s) to target memory",
- .usage = "address data [count]",
- },
- {
- .name = "mwh",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_mw,
- .help = "Write 16-bit half-word(s) to target memory",
- .usage = "address data [count]",
- },
- {
- .name = "mwb",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_mw,
- .help = "Write byte(s) to target memory",
- .usage = "address data [count]",
- },
- {
- .name = "mdw",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_md,
- .help = "Display target memory as 32-bit words",
- .usage = "address [count]",
- },
- {
- .name = "mdh",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_md,
- .help = "Display target memory as 16-bit half-words",
- .usage = "address [count]",
- },
- {
- .name = "mdb",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_md,
- .help = "Display target memory as 8-bit bytes",
- .usage = "address [count]",
- },
- {
- .name = "array2mem",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_array2mem,
- .help = "Writes Tcl array of 8/16/32 bit numbers "
- "to target memory",
- .usage = "arrayname bitwidth address count",
- },
- {
- .name = "mem2array",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_mem2array,
- .help = "Loads Tcl array of 8/16/32 bit numbers "
- "from target memory",
- .usage = "arrayname bitwidth address count",
- },
- {
- .name = "eventlist",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_event_list,
- .help = "displays a table of events defined for this target",
- },
- {
- .name = "curstate",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_current_state,
- .help = "displays the current state of this target",
- },
- {
- .name = "arp_examine",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_examine,
- .help = "used internally for reset processing",
- },
- {
- .name = "arp_halt_gdb",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_halt_gdb,
- .help = "used internally for reset processing to halt GDB",
- },
- {
- .name = "arp_poll",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_poll,
- .help = "used internally for reset processing",
- },
- {
- .name = "arp_reset",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_reset,
- .help = "used internally for reset processing",
- },
- {
- .name = "arp_halt",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_halt,
- .help = "used internally for reset processing",
- },
- {
- .name = "arp_waitstate",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_wait_state,
- .help = "used internally for reset processing",
- },
- {
- .name = "invoke-event",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_target_invoke_event,
- .help = "invoke handler for specified event",
- .usage = "event_name",
- },
- COMMAND_REGISTRATION_DONE
-};
-
-static int target_create(Jim_GetOptInfo *goi)
-{
- Jim_Obj *new_cmd;
- Jim_Cmd *cmd;
- const char *cp;
- char *cp2;
- int e;
- int x;
- struct target *target;
- struct command_context *cmd_ctx;
-
- cmd_ctx = current_command_context(goi->interp);
- assert(cmd_ctx != NULL);
-
- if (goi->argc < 3) {
- Jim_WrongNumArgs(goi->interp, 1, goi->argv, "?name? ?type? ..options...");
- return JIM_ERR;
- }
-
- /* COMMAND */
- Jim_GetOpt_Obj(goi, &new_cmd);
- /* does this command exist? */
- cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
- if (cmd) {
- cp = Jim_GetString(new_cmd, NULL);
- Jim_SetResultFormatted(goi->interp, "Command/target: %s Exists", cp);
- return JIM_ERR;
- }
-
- /* TYPE */
- e = Jim_GetOpt_String(goi, &cp2, NULL);
- if (e != JIM_OK)
- return e;
- cp = cp2;
- struct transport *tr = get_current_transport();
- if (tr->override_target) {
- e = tr->override_target(&cp);
- if (e != ERROR_OK) {
- LOG_ERROR("The selected transport doesn't support this target");
- return JIM_ERR;
- }
- LOG_INFO("The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD");
- }
- /* now does target type exist */
- for (x = 0 ; target_types[x] ; x++) {
- if (0 == strcmp(cp, target_types[x]->name)) {
- /* found */
- break;
- }
-
- /* check for deprecated name */
- if (target_types[x]->deprecated_name) {
- if (0 == strcmp(cp, target_types[x]->deprecated_name)) {
- /* found */
- LOG_WARNING("target name is deprecated use: \'%s\'", target_types[x]->name);
- break;
- }
- }
- }
- if (target_types[x] == NULL) {
- Jim_SetResultFormatted(goi->interp, "Unknown target type %s, try one of ", cp);
- for (x = 0 ; target_types[x] ; x++) {
- if (target_types[x + 1]) {
- Jim_AppendStrings(goi->interp,
- Jim_GetResult(goi->interp),
- target_types[x]->name,
- ", ", NULL);
- } else {
- Jim_AppendStrings(goi->interp,
- Jim_GetResult(goi->interp),
- " or ",
- target_types[x]->name, NULL);
- }
- }
- return JIM_ERR;
- }
-
- /* Create it */
- target = calloc(1, sizeof(struct target));
- /* set target number */
- target->target_number = new_target_number();
- cmd_ctx->current_target = target->target_number;
-
- /* allocate memory for each unique target type */
- target->type = calloc(1, sizeof(struct target_type));
-
- memcpy(target->type, target_types[x], sizeof(struct target_type));
-
- /* will be set by "-endian" */
- target->endianness = TARGET_ENDIAN_UNKNOWN;
-
- /* default to first core, override with -coreid */
- target->coreid = 0;
-
- target->working_area = 0x0;
- target->working_area_size = 0x0;
- target->working_areas = NULL;
- target->backup_working_area = 0;
-
- target->state = TARGET_UNKNOWN;
- target->debug_reason = DBG_REASON_UNDEFINED;
- target->reg_cache = NULL;
- target->breakpoints = NULL;
- target->watchpoints = NULL;
- target->next = NULL;
- target->arch_info = NULL;
-
- target->display = 1;
-
- target->halt_issued = false;
-
- /* initialize trace information */
- target->trace_info = malloc(sizeof(struct trace));
- target->trace_info->num_trace_points = 0;
- target->trace_info->trace_points_size = 0;
- target->trace_info->trace_points = NULL;
- target->trace_info->trace_history_size = 0;
- target->trace_info->trace_history = NULL;
- target->trace_info->trace_history_pos = 0;
- target->trace_info->trace_history_overflowed = 0;
-
- target->dbgmsg = NULL;
- target->dbg_msg_enabled = 0;
-
- target->endianness = TARGET_ENDIAN_UNKNOWN;
-
- target->rtos = NULL;
- target->rtos_auto_detect = false;
-
- /* Do the rest as "configure" options */
- goi->isconfigure = 1;
- e = target_configure(goi, target);
-
- if (target->tap == NULL) {
- Jim_SetResultString(goi->interp, "-chain-position required when creating target", -1);
- e = JIM_ERR;
- }
-
- if (e != JIM_OK) {
- free(target->type);
- free(target);
- return e;
- }
-
- if (target->endianness == TARGET_ENDIAN_UNKNOWN) {
- /* default endian to little if not specified */
- target->endianness = TARGET_LITTLE_ENDIAN;
- }
-
- cp = Jim_GetString(new_cmd, NULL);
- target->cmd_name = strdup(cp);
-
- /* create the target specific commands */
- if (target->type->commands) {
- e = register_commands(cmd_ctx, NULL, target->type->commands);
- if (ERROR_OK != e)
- LOG_ERROR("unable to register '%s' commands", cp);
- }
- if (target->type->target_create)
- (*(target->type->target_create))(target, goi->interp);
-
- /* append to end of list */
- {
- struct target **tpp;
- tpp = &(all_targets);
- while (*tpp)
- tpp = &((*tpp)->next);
- *tpp = target;
- }
-
- /* now - create the new target name command */
- const struct command_registration target_subcommands[] = {
- {
- .chain = target_instance_command_handlers,
- },
- {
- .chain = target->type->commands,
- },
- COMMAND_REGISTRATION_DONE
- };
- const struct command_registration target_commands[] = {
- {
- .name = cp,
- .mode = COMMAND_ANY,
- .help = "target command group",
- .usage = "",
- .chain = target_subcommands,
- },
- COMMAND_REGISTRATION_DONE
- };
- e = register_commands(cmd_ctx, NULL, target_commands);
- if (ERROR_OK != e)
- return JIM_ERR;
-
- struct command *c = command_find_in_context(cmd_ctx, cp);
- assert(c);
- command_set_handler_data(c, target);
-
- return (ERROR_OK == e) ? JIM_OK : JIM_ERR;
-}
-
-static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
- return JIM_ERR;
- }
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx != NULL);
-
- Jim_SetResultString(interp, target_name(get_current_target(cmd_ctx)), -1);
- return JIM_OK;
-}
-
-static int jim_target_types(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
- return JIM_ERR;
- }
- Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
- for (unsigned x = 0; NULL != target_types[x]; x++) {
- Jim_ListAppendElement(interp, Jim_GetResult(interp),
- Jim_NewStringObj(interp, target_types[x]->name, -1));
- }
- return JIM_OK;
-}
-
-static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
- return JIM_ERR;
- }
- Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
- struct target *target = all_targets;
- while (target) {
- Jim_ListAppendElement(interp, Jim_GetResult(interp),
- Jim_NewStringObj(interp, target_name(target), -1));
- target = target->next;
- }
- return JIM_OK;
-}
-
-static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- int i;
- const char *targetname;
- int retval, len;
- struct target *target = (struct target *) NULL;
- struct target_list *head, *curr, *new;
- curr = (struct target_list *) NULL;
- head = (struct target_list *) NULL;
-
- retval = 0;
- LOG_DEBUG("%d", argc);
- /* argv[1] = target to associate in smp
- * argv[2] = target to assoicate in smp
- * argv[3] ...
- */
-
- for (i = 1; i < argc; i++) {
-
- targetname = Jim_GetString(argv[i], &len);
- target = get_target(targetname);
- LOG_DEBUG("%s ", targetname);
- if (target) {
- new = malloc(sizeof(struct target_list));
- new->target = target;
- new->next = (struct target_list *)NULL;
- if (head == (struct target_list *)NULL) {
- head = new;
- curr = head;
- } else {
- curr->next = new;
- curr = new;
- }
- }
- }
- /* now parse the list of cpu and put the target in smp mode*/
- curr = head;
-
- while (curr != (struct target_list *)NULL) {
- target = curr->target;
- target->smp = 1;
- target->head = head;
- curr = curr->next;
- }
-
- if (target && target->rtos)
- retval = rtos_smp_init(head->target);
-
- return retval;
-}
-
-
-static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
- if (goi.argc < 3) {
- Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
- " [ ...]");
- return JIM_ERR;
- }
- return target_create(&goi);
-}
-
-static const struct command_registration target_subcommand_handlers[] = {
- {
- .name = "init",
- .mode = COMMAND_CONFIG,
- .handler = handle_target_init_command,
- .help = "initialize targets",
- },
- {
- .name = "create",
- /* REVISIT this should be COMMAND_CONFIG ... */
- .mode = COMMAND_ANY,
- .jim_handler = jim_target_create,
- .usage = "name type '-chain-position' name [options ...]",
- .help = "Creates and selects a new target",
- },
- {
- .name = "current",
- .mode = COMMAND_ANY,
- .jim_handler = jim_target_current,
- .help = "Returns the currently selected target",
- },
- {
- .name = "types",
- .mode = COMMAND_ANY,
- .jim_handler = jim_target_types,
- .help = "Returns the available target types as "
- "a list of strings",
- },
- {
- .name = "names",
- .mode = COMMAND_ANY,
- .jim_handler = jim_target_names,
- .help = "Returns the names of all targets as a list of strings",
- },
- {
- .name = "smp",
- .mode = COMMAND_ANY,
- .jim_handler = jim_target_smp,
- .usage = "targetname1 targetname2 ...",
- .help = "gather several target in a smp list"
- },
-
- COMMAND_REGISTRATION_DONE
-};
-
-struct FastLoad {
- uint32_t address;
- uint8_t *data;
- int length;
-
-};
-
-static int fastload_num;
-static struct FastLoad *fastload;
-
-static void free_fastload(void)
-{
- if (fastload != NULL) {
- int i;
- for (i = 0; i < fastload_num; i++) {
- if (fastload[i].data)
- free(fastload[i].data);
- }
- free(fastload);
- fastload = NULL;
- }
-}
-
-COMMAND_HANDLER(handle_fast_load_image_command)
-{
- uint8_t *buffer;
- size_t buf_cnt;
- uint32_t image_size;
- uint32_t min_address = 0;
- uint32_t max_address = 0xffffffff;
- int i;
-
- struct image image;
-
- int retval = CALL_COMMAND_HANDLER(parse_load_image_command_CMD_ARGV,
- &image, &min_address, &max_address);
- if (ERROR_OK != retval)
- return retval;
-
- struct duration bench;
- duration_start(&bench);
-
- retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL);
- if (retval != ERROR_OK)
- return retval;
-
- image_size = 0x0;
- retval = ERROR_OK;
- fastload_num = image.num_sections;
- fastload = malloc(sizeof(struct FastLoad)*image.num_sections);
- if (fastload == NULL) {
- command_print(CMD_CTX, "out of memory");
- image_close(&image);
- return ERROR_FAIL;
- }
- memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
- for (i = 0; i < image.num_sections; i++) {
- buffer = malloc(image.sections[i].size);
- if (buffer == NULL) {
- command_print(CMD_CTX, "error allocating buffer for section (%d bytes)",
- (int)(image.sections[i].size));
- retval = ERROR_FAIL;
- break;
- }
-
- retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);
- if (retval != ERROR_OK) {
- free(buffer);
- break;
- }
-
- uint32_t offset = 0;
- uint32_t length = buf_cnt;
-
- /* DANGER!!! beware of unsigned comparision here!!! */
-
- if ((image.sections[i].base_address + buf_cnt >= min_address) &&
- (image.sections[i].base_address < max_address)) {
- if (image.sections[i].base_address < min_address) {
- /* clip addresses below */
- offset += min_address-image.sections[i].base_address;
- length -= offset;
- }
-
- if (image.sections[i].base_address + buf_cnt > max_address)
- length -= (image.sections[i].base_address + buf_cnt)-max_address;
-
- fastload[i].address = image.sections[i].base_address + offset;
- fastload[i].data = malloc(length);
- if (fastload[i].data == NULL) {
- free(buffer);
- command_print(CMD_CTX, "error allocating buffer for section (%" PRIu32 " bytes)",
- length);
- retval = ERROR_FAIL;
- break;
- }
- memcpy(fastload[i].data, buffer + offset, length);
- fastload[i].length = length;
-
- image_size += length;
- command_print(CMD_CTX, "%u bytes written at address 0x%8.8x",
- (unsigned int)length,
- ((unsigned int)(image.sections[i].base_address + offset)));
- }
-
- free(buffer);
- }
-
- if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
- command_print(CMD_CTX, "Loaded %" PRIu32 " bytes "
- "in %fs (%0.3f KiB/s)", image_size,
- duration_elapsed(&bench), duration_kbps(&bench, image_size));
-
- command_print(CMD_CTX,
- "WARNING: image has not been loaded to target!"
- "You can issue a 'fast_load' to finish loading.");
- }
-
- image_close(&image);
-
- if (retval != ERROR_OK)
- free_fastload();
-
- return retval;
-}
-
-COMMAND_HANDLER(handle_fast_load_command)
-{
- if (CMD_ARGC > 0)
- return ERROR_COMMAND_SYNTAX_ERROR;
- if (fastload == NULL) {
- LOG_ERROR("No image in memory");
- return ERROR_FAIL;
- }
- int i;
- int ms = timeval_ms();
- int size = 0;
- int retval = ERROR_OK;
- for (i = 0; i < fastload_num; i++) {
- struct target *target = get_current_target(CMD_CTX);
- command_print(CMD_CTX, "Write to 0x%08x, length 0x%08x",
- (unsigned int)(fastload[i].address),
- (unsigned int)(fastload[i].length));
- retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data);
- if (retval != ERROR_OK)
- break;
- size += fastload[i].length;
- }
- if (retval == ERROR_OK) {
- int after = timeval_ms();
- command_print(CMD_CTX, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
- }
- return retval;
-}
-
-static const struct command_registration target_command_handlers[] = {
- {
- .name = "targets",
- .handler = handle_targets_command,
- .mode = COMMAND_ANY,
- .help = "change current default target (one parameter) "
- "or prints table of all targets (no parameters)",
- .usage = "[target]",
- },
- {
- .name = "target",
- .mode = COMMAND_CONFIG,
- .help = "configure target",
-
- .chain = target_subcommand_handlers,
- },
- COMMAND_REGISTRATION_DONE
-};
-
-int target_register_commands(struct command_context *cmd_ctx)
-{
- return register_commands(cmd_ctx, NULL, target_command_handlers);
-}
-
-static bool target_reset_nag = true;
-
-bool get_target_reset_nag(void)
-{
- return target_reset_nag;
-}
-
-COMMAND_HANDLER(handle_target_reset_nag)
-{
- return CALL_COMMAND_HANDLER(handle_command_parse_bool,
- &target_reset_nag, "Nag after each reset about options to improve "
- "performance");
-}
-
-COMMAND_HANDLER(handle_ps_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- char *display;
- if (target->state != TARGET_HALTED) {
- LOG_INFO("target not halted !!");
- return ERROR_OK;
- }
-
- if ((target->rtos) && (target->rtos->type)
- && (target->rtos->type->ps_command)) {
- display = target->rtos->type->ps_command(target);
- command_print(CMD_CTX, "%s", display);
- free(display);
- return ERROR_OK;
- } else {
- LOG_INFO("failed");
- return ERROR_TARGET_FAILURE;
- }
-}
-
-static void binprint(struct command_context *cmd_ctx, const char *text, const uint8_t *buf, int size)
-{
- if (text != NULL)
- command_print_sameline(cmd_ctx, "%s", text);
- for (int i = 0; i < size; i++)
- command_print_sameline(cmd_ctx, " %02x", buf[i]);
- command_print(cmd_ctx, " ");
-}
-
-COMMAND_HANDLER(handle_test_mem_access_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- uint32_t test_size;
- int retval = ERROR_OK;
-
- if (target->state != TARGET_HALTED) {
- LOG_INFO("target not halted !!");
- return ERROR_FAIL;
- }
-
- if (CMD_ARGC != 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], test_size);
-
- /* Test reads */
- size_t num_bytes = test_size + 4;
-
- struct working_area *wa = NULL;
- retval = target_alloc_working_area(target, num_bytes, &wa);
- if (retval != ERROR_OK) {
- LOG_ERROR("Not enough working area");
- return ERROR_FAIL;
- }
-
- uint8_t *test_pattern = malloc(num_bytes);
-
- for (size_t i = 0; i < num_bytes; i++)
- test_pattern[i] = rand();
-
- retval = target_write_memory(target, wa->address, 1, num_bytes, test_pattern);
- if (retval != ERROR_OK) {
- LOG_ERROR("Test pattern write failed");
- goto out;
- }
-
- for (int host_offset = 0; host_offset <= 1; host_offset++) {
- for (int size = 1; size <= 4; size *= 2) {
- for (int offset = 0; offset < 4; offset++) {
- uint32_t count = test_size / size;
- size_t host_bufsiz = (count + 2) * size + host_offset;
- uint8_t *read_ref = malloc(host_bufsiz);
- uint8_t *read_buf = malloc(host_bufsiz);
-
- for (size_t i = 0; i < host_bufsiz; i++) {
- read_ref[i] = rand();
- read_buf[i] = read_ref[i];
- }
- command_print_sameline(CMD_CTX,
- "Test read %" PRIu32 " x %d @ %d to %saligned buffer: ", count,
- size, offset, host_offset ? "un" : "");
-
- struct duration bench;
- duration_start(&bench);
-
- retval = target_read_memory(target, wa->address + offset, size, count,
- read_buf + size + host_offset);
-
- duration_measure(&bench);
-
- if (retval == ERROR_TARGET_UNALIGNED_ACCESS) {
- command_print(CMD_CTX, "Unsupported alignment");
- goto next;
- } else if (retval != ERROR_OK) {
- command_print(CMD_CTX, "Memory read failed");
- goto next;
- }
-
- /* replay on host */
- memcpy(read_ref + size + host_offset, test_pattern + offset, count * size);
-
- /* check result */
- int result = memcmp(read_ref, read_buf, host_bufsiz);
- if (result == 0) {
- command_print(CMD_CTX, "Pass in %fs (%0.3f KiB/s)",
- duration_elapsed(&bench),
- duration_kbps(&bench, count * size));
- } else {
- command_print(CMD_CTX, "Compare failed");
- binprint(CMD_CTX, "ref:", read_ref, host_bufsiz);
- binprint(CMD_CTX, "buf:", read_buf, host_bufsiz);
- }
-next:
- free(read_ref);
- free(read_buf);
- }
- }
- }
-
-out:
- free(test_pattern);
-
- if (wa != NULL)
- target_free_working_area(target, wa);
-
- /* Test writes */
- num_bytes = test_size + 4 + 4 + 4;
-
- retval = target_alloc_working_area(target, num_bytes, &wa);
- if (retval != ERROR_OK) {
- LOG_ERROR("Not enough working area");
- return ERROR_FAIL;
- }
-
- test_pattern = malloc(num_bytes);
-
- for (size_t i = 0; i < num_bytes; i++)
- test_pattern[i] = rand();
-
- for (int host_offset = 0; host_offset <= 1; host_offset++) {
- for (int size = 1; size <= 4; size *= 2) {
- for (int offset = 0; offset < 4; offset++) {
- uint32_t count = test_size / size;
- size_t host_bufsiz = count * size + host_offset;
- uint8_t *read_ref = malloc(num_bytes);
- uint8_t *read_buf = malloc(num_bytes);
- uint8_t *write_buf = malloc(host_bufsiz);
-
- for (size_t i = 0; i < host_bufsiz; i++)
- write_buf[i] = rand();
- command_print_sameline(CMD_CTX,
- "Test write %" PRIu32 " x %d @ %d from %saligned buffer: ", count,
- size, offset, host_offset ? "un" : "");
-
- retval = target_write_memory(target, wa->address, 1, num_bytes, test_pattern);
- if (retval != ERROR_OK) {
- command_print(CMD_CTX, "Test pattern write failed");
- goto nextw;
- }
-
- /* replay on host */
- memcpy(read_ref, test_pattern, num_bytes);
- memcpy(read_ref + size + offset, write_buf + host_offset, count * size);
-
- struct duration bench;
- duration_start(&bench);
-
- retval = target_write_memory(target, wa->address + size + offset, size, count,
- write_buf + host_offset);
-
- duration_measure(&bench);
-
- if (retval == ERROR_TARGET_UNALIGNED_ACCESS) {
- command_print(CMD_CTX, "Unsupported alignment");
- goto nextw;
- } else if (retval != ERROR_OK) {
- command_print(CMD_CTX, "Memory write failed");
- goto nextw;
- }
-
- /* read back */
- retval = target_read_memory(target, wa->address, 1, num_bytes, read_buf);
- if (retval != ERROR_OK) {
- command_print(CMD_CTX, "Test pattern write failed");
- goto nextw;
- }
-
- /* check result */
- int result = memcmp(read_ref, read_buf, num_bytes);
- if (result == 0) {
- command_print(CMD_CTX, "Pass in %fs (%0.3f KiB/s)",
- duration_elapsed(&bench),
- duration_kbps(&bench, count * size));
- } else {
- command_print(CMD_CTX, "Compare failed");
- binprint(CMD_CTX, "ref:", read_ref, num_bytes);
- binprint(CMD_CTX, "buf:", read_buf, num_bytes);
- }
-nextw:
- free(read_ref);
- free(read_buf);
- }
- }
- }
-
- free(test_pattern);
-
- if (wa != NULL)
- target_free_working_area(target, wa);
- return retval;
-}
-
-static const struct command_registration target_exec_command_handlers[] = {
- {
- .name = "fast_load_image",
- .handler = handle_fast_load_image_command,
- .mode = COMMAND_ANY,
- .help = "Load image into server memory for later use by "
- "fast_load; primarily for profiling",
- .usage = "filename address ['bin'|'ihex'|'elf'|'s19'] "
- "[min_address [max_length]]",
- },
- {
- .name = "fast_load",
- .handler = handle_fast_load_command,
- .mode = COMMAND_EXEC,
- .help = "loads active fast load image to current target "
- "- mainly for profiling purposes",
- .usage = "",
- },
- {
- .name = "profile",
- .handler = handle_profile_command,
- .mode = COMMAND_EXEC,
- .usage = "seconds filename [start end]",
- .help = "profiling samples the CPU PC",
- },
- /** @todo don't register virt2phys() unless target supports it */
- {
- .name = "virt2phys",
- .handler = handle_virt2phys_command,
- .mode = COMMAND_ANY,
- .help = "translate a virtual address into a physical address",
- .usage = "virtual_address",
- },
- {
- .name = "reg",
- .handler = handle_reg_command,
- .mode = COMMAND_EXEC,
- .help = "display (reread from target with \"force\") or set a register; "
- "with no arguments, displays all registers and their values",
- .usage = "[(register_number|register_name) [(value|'force')]]",
- },
- {
- .name = "poll",
- .handler = handle_poll_command,
- .mode = COMMAND_EXEC,
- .help = "poll target state; or reconfigure background polling",
- .usage = "['on'|'off']",
- },
- {
- .name = "wait_halt",
- .handler = handle_wait_halt_command,
- .mode = COMMAND_EXEC,
- .help = "wait up to the specified number of milliseconds "
- "(default 5000) for a previously requested halt",
- .usage = "[milliseconds]",
- },
- {
- .name = "halt",
- .handler = handle_halt_command,
- .mode = COMMAND_EXEC,
- .help = "request target to halt, then wait up to the specified"
- "number of milliseconds (default 5000) for it to complete",
- .usage = "[milliseconds]",
- },
- {
- .name = "resume",
- .handler = handle_resume_command,
- .mode = COMMAND_EXEC,
- .help = "resume target execution from current PC or address",
- .usage = "[address]",
- },
- {
- .name = "reset",
- .handler = handle_reset_command,
- .mode = COMMAND_EXEC,
- .usage = "[run|halt|init]",
- .help = "Reset all targets into the specified mode."
- "Default reset mode is run, if not given.",
- },
- {
- .name = "soft_reset_halt",
- .handler = handle_soft_reset_halt_command,
- .mode = COMMAND_EXEC,
- .usage = "",
- .help = "halt the target and do a soft reset",
- },
- {
- .name = "step",
- .handler = handle_step_command,
- .mode = COMMAND_EXEC,
- .help = "step one instruction from current PC or address",
- .usage = "[address]",
- },
- {
- .name = "mdw",
- .handler = handle_md_command,
- .mode = COMMAND_EXEC,
- .help = "display memory words",
- .usage = "['phys'] address [count]",
- },
- {
- .name = "mdh",
- .handler = handle_md_command,
- .mode = COMMAND_EXEC,
- .help = "display memory half-words",
- .usage = "['phys'] address [count]",
- },
- {
- .name = "mdb",
- .handler = handle_md_command,
- .mode = COMMAND_EXEC,
- .help = "display memory bytes",
- .usage = "['phys'] address [count]",
- },
- {
- .name = "mww",
- .handler = handle_mw_command,
- .mode = COMMAND_EXEC,
- .help = "write memory word",
- .usage = "['phys'] address value [count]",
- },
- {
- .name = "mwh",
- .handler = handle_mw_command,
- .mode = COMMAND_EXEC,
- .help = "write memory half-word",
- .usage = "['phys'] address value [count]",
- },
- {
- .name = "mwb",
- .handler = handle_mw_command,
- .mode = COMMAND_EXEC,
- .help = "write memory byte",
- .usage = "['phys'] address value [count]",
- },
- {
- .name = "bp",
- .handler = handle_bp_command,
- .mode = COMMAND_EXEC,
- .help = "list or set hardware or software breakpoint",
- .usage = " [] ['hw'|'hw_ctx']",
- },
- {
- .name = "rbp",
- .handler = handle_rbp_command,
- .mode = COMMAND_EXEC,
- .help = "remove breakpoint",
- .usage = "address",
- },
- {
- .name = "wp",
- .handler = handle_wp_command,
- .mode = COMMAND_EXEC,
- .help = "list (no params) or create watchpoints",
- .usage = "[address length [('r'|'w'|'a') value [mask]]]",
- },
- {
- .name = "rwp",
- .handler = handle_rwp_command,
- .mode = COMMAND_EXEC,
- .help = "remove watchpoint",
- .usage = "address",
- },
- {
- .name = "load_image",
- .handler = handle_load_image_command,
- .mode = COMMAND_EXEC,
- .usage = "filename address ['bin'|'ihex'|'elf'|'s19'] "
- "[min_address] [max_length]",
- },
- {
- .name = "dump_image",
- .handler = handle_dump_image_command,
- .mode = COMMAND_EXEC,
- .usage = "filename address size",
- },
- {
- .name = "verify_image",
- .handler = handle_verify_image_command,
- .mode = COMMAND_EXEC,
- .usage = "filename [offset [type]]",
- },
- {
- .name = "test_image",
- .handler = handle_test_image_command,
- .mode = COMMAND_EXEC,
- .usage = "filename [offset [type]]",
- },
- {
- .name = "mem2array",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_mem2array,
- .help = "read 8/16/32 bit memory and return as a TCL array "
- "for script processing",
- .usage = "arrayname bitwidth address count",
- },
- {
- .name = "array2mem",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_array2mem,
- .help = "convert a TCL array to memory locations "
- "and write the 8/16/32 bit values",
- .usage = "arrayname bitwidth address count",
- },
- {
- .name = "reset_nag",
- .handler = handle_target_reset_nag,
- .mode = COMMAND_ANY,
- .help = "Nag after each reset about options that could have been "
- "enabled to improve performance. ",
- .usage = "['enable'|'disable']",
- },
- {
- .name = "ps",
- .handler = handle_ps_command,
- .mode = COMMAND_EXEC,
- .help = "list all tasks ",
- .usage = " ",
- },
- {
- .name = "test_mem_access",
- .handler = handle_test_mem_access_command,
- .mode = COMMAND_EXEC,
- .help = "Test the target's memory access functions",
- .usage = "size",
- },
-
- COMMAND_REGISTRATION_DONE
-};
-static int target_register_user_commands(struct command_context *cmd_ctx)
-{
- int retval = ERROR_OK;
- retval = target_request_register_commands(cmd_ctx);
- if (retval != ERROR_OK)
- return retval;
-
- retval = trace_register_commands(cmd_ctx);
- if (retval != ERROR_OK)
- return retval;
-
-
- return register_commands(cmd_ctx, NULL, target_exec_command_handlers);
-}
+ Jim_GetOptInfo goi;
+
+ Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+ goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure");
+#if BUILD_RISCV == 1
+ int need_args = 1 + goi.isconfigure;
+ if (goi.argc < need_args) {
+ Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
+ goi.isconfigure
+ ? "missing: -option VALUE ..."
+ : "missing: -option ...");
+ return JIM_ERR;
+ }
+#else
+ if (goi.argc < 1) {
+ Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
+ "missing: -option ...");
+ return JIM_ERR;
+ }
+#endif
+ struct target *target = Jim_CmdPrivData(goi.interp);
+ return target_configure(&goi, target);
+ }
+
+ static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ const char *cmd_name = Jim_GetString(argv[0], NULL);
+
+ Jim_GetOptInfo goi;
+ Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+
+ if (goi.argc < 2 || goi.argc > 4) {
+ Jim_SetResultFormatted(goi.interp,
+ "usage: %s [phys] []", cmd_name);
+ return JIM_ERR;
+ }
+
+ target_write_fn fn;
+ fn = target_write_memory;
+
+ int e;
+ if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) {
+ /* consume it */
+ struct Jim_Obj *obj;
+ e = Jim_GetOpt_Obj(&goi, &obj);
+ if (e != JIM_OK)
+ return e;
+
+ fn = target_write_phys_memory;
+ }
+
+ jim_wide a;
+ e = Jim_GetOpt_Wide(&goi, &a);
+ if (e != JIM_OK)
+ return e;
+
+ jim_wide b;
+ e = Jim_GetOpt_Wide(&goi, &b);
+ if (e != JIM_OK)
+ return e;
+
+ jim_wide c = 1;
+ if (goi.argc == 1) {
+ e = Jim_GetOpt_Wide(&goi, &c);
+ if (e != JIM_OK)
+ return e;
+ }
+
+ /* all args must be consumed */
+ if (goi.argc != 0)
+ return JIM_ERR;
+
+ struct target *target = Jim_CmdPrivData(goi.interp);
+ unsigned data_size;
+ if (strcasecmp(cmd_name, "mww") == 0)
+ data_size = 4;
+ else if (strcasecmp(cmd_name, "mwh") == 0)
+ data_size = 2;
+ else if (strcasecmp(cmd_name, "mwb") == 0)
+ data_size = 1;
+ else {
+ LOG_ERROR("command '%s' unknown: ", cmd_name);
+ return JIM_ERR;
+ }
+
+ return (target_fill_mem(target, a, fn, data_size, b, c) == ERROR_OK) ? JIM_OK : JIM_ERR;
+ }
+
+ /**
+ * @brief Reads an array of words/halfwords/bytes from target memory starting at specified address.
+ *
+ * Usage: mdw [phys] [] - for 32 bit reads
+ * mdh [phys] [] - for 16 bit reads
+ * mdb [phys] [] - for 8 bit reads
+ *
+ * Count defaults to 1.
+ *
+ * Calls target_read_memory or target_read_phys_memory depending on
+ * the presence of the "phys" argument
+ * Reads the target memory in blocks of max. 32 bytes, and returns an array of ints formatted
+ * to int representation in base16.
+ * Also outputs read data in a human readable form using command_print
+ *
+ * @param phys if present target_read_phys_memory will be used instead of target_read_memory
+ * @param address address where to start the read. May be specified in decimal or hex using the standard "0x" prefix
+ * @param count optional count parameter to read an array of values. If not specified, defaults to 1.
+ * @returns: JIM_ERR on error or JIM_OK on success and sets the result string to an array of ascii formatted numbers
+ * on success, with [] number of elements.
+ *
+ * In case of little endian target:
+ * Example1: "mdw 0x00000000" returns "10123456"
+ * Exmaple2: "mdh 0x00000000 1" returns "3456"
+ * Example3: "mdb 0x00000000" returns "56"
+ * Example4: "mdh 0x00000000 2" returns "3456 1012"
+ * Example5: "mdb 0x00000000 3" returns "56 34 12"
+ **/
+ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ const char *cmd_name = Jim_GetString(argv[0], NULL);
+
+ Jim_GetOptInfo goi;
+ Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+
+ if ((goi.argc < 1) || (goi.argc > 3)) {
+ Jim_SetResultFormatted(goi.interp,
+ "usage: %s [phys] []", cmd_name);
+ return JIM_ERR;
+ }
+
+ int (*fn)(struct target *target,
+ target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+ fn = target_read_memory;
+
+ int e;
+ if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) {
+ /* consume it */
+ struct Jim_Obj *obj;
+ e = Jim_GetOpt_Obj(&goi, &obj);
+ if (e != JIM_OK)
+ return e;
+
+ fn = target_read_phys_memory;
+ }
+
+ /* Read address parameter */
+ jim_wide addr;
+ e = Jim_GetOpt_Wide(&goi, &addr);
+ if (e != JIM_OK)
+ return JIM_ERR;
+
+ /* If next parameter exists, read it out as the count parameter, if not, set it to 1 (default) */
+ jim_wide count;
+ if (goi.argc == 1) {
+ e = Jim_GetOpt_Wide(&goi, &count);
+ if (e != JIM_OK)
+ return JIM_ERR;
+ } else
+ count = 1;
+
+ /* all args must be consumed */
+ if (goi.argc != 0)
+ return JIM_ERR;
+
+ jim_wide dwidth = 1; /* shut up gcc */
+ if (strcasecmp(cmd_name, "mdw") == 0)
+ dwidth = 4;
+ else if (strcasecmp(cmd_name, "mdh") == 0)
+ dwidth = 2;
+ else if (strcasecmp(cmd_name, "mdb") == 0)
+ dwidth = 1;
+ else {
+ LOG_ERROR("command '%s' unknown: ", cmd_name);
+ return JIM_ERR;
+ }
+
+ /* convert count to "bytes" */
+ int bytes = count * dwidth;
+
+ struct target *target = Jim_CmdPrivData(goi.interp);
+ uint8_t target_buf[32];
+ jim_wide x, y, z;
+ while (bytes > 0) {
+ y = (bytes < 16) ? bytes : 16; /* y = min(bytes, 16); */
+
+ /* Try to read out next block */
+ e = fn(target, addr, dwidth, y / dwidth, target_buf);
+
+ if (e != ERROR_OK) {
+ Jim_SetResultFormatted(interp, "error reading target @ 0x%08lx", (long)addr);
+ return JIM_ERR;
+ }
+
+ command_print_sameline(NULL, "0x%08x ", (int)(addr));
+ switch (dwidth) {
+ case 4:
+ for (x = 0; x < 16 && x < y; x += 4) {
+ z = target_buffer_get_u32(target, &(target_buf[x]));
+ command_print_sameline(NULL, "%08x ", (int)(z));
+ }
+ for (; (x < 16) ; x += 4)
+ command_print_sameline(NULL, " ");
+ break;
+ case 2:
+ for (x = 0; x < 16 && x < y; x += 2) {
+ z = target_buffer_get_u16(target, &(target_buf[x]));
+ command_print_sameline(NULL, "%04x ", (int)(z));
+ }
+ for (; (x < 16) ; x += 2)
+ command_print_sameline(NULL, " ");
+ break;
+ case 1:
+ default:
+ for (x = 0 ; (x < 16) && (x < y) ; x += 1) {
+ z = target_buffer_get_u8(target, &(target_buf[x]));
+ command_print_sameline(NULL, "%02x ", (int)(z));
+ }
+ for (; (x < 16) ; x += 1)
+ command_print_sameline(NULL, " ");
+ break;
+ }
+ /* ascii-ify the bytes */
+ for (x = 0 ; x < y ; x++) {
+ if ((target_buf[x] >= 0x20) &&
+ (target_buf[x] <= 0x7e)) {
+ /* good */
+ } else {
+ /* smack it */
+ target_buf[x] = '.';
+ }
+ }
+ /* space pad */
+ while (x < 16) {
+ target_buf[x] = ' ';
+ x++;
+ }
+ /* terminate */
+ target_buf[16] = 0;
+ /* print - with a newline */
+ command_print_sameline(NULL, "%s\n", target_buf);
+ /* NEXT... */
+ bytes -= 16;
+ addr += 16;
+ }
+ return JIM_OK;
+ }
+
+ static int jim_target_mem2array(Jim_Interp *interp,
+ int argc, Jim_Obj *const *argv)
+ {
+ struct target *target = Jim_CmdPrivData(interp);
+ return target_mem2array(interp, target, argc - 1, argv + 1);
+ }
+
+ static int jim_target_array2mem(Jim_Interp *interp,
+ int argc, Jim_Obj *const *argv)
+ {
+ struct target *target = Jim_CmdPrivData(interp);
+ return target_array2mem(interp, target, argc - 1, argv + 1);
+ }
+
+ static int jim_target_tap_disabled(Jim_Interp *interp)
+ {
+ Jim_SetResultFormatted(interp, "[TAP is disabled]");
+ return JIM_ERR;
+ }
+
+ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ bool allow_defer = false;
+
+ Jim_GetOptInfo goi;
+ Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+ if (goi.argc > 1) {
+ const char *cmd_name = Jim_GetString(argv[0], NULL);
+ Jim_SetResultFormatted(goi.interp,
+ "usage: %s ['allow-defer']", cmd_name);
+ return JIM_ERR;
+ }
+ if (goi.argc > 0 &&
+ strcmp(Jim_GetString(argv[1], NULL), "allow-defer") == 0) {
+ /* consume it */
+ struct Jim_Obj *obj;
+ int e = Jim_GetOpt_Obj(&goi, &obj);
+ if (e != JIM_OK)
+ return e;
+ allow_defer = true;
+ }
+
+ struct target *target = Jim_CmdPrivData(interp);
+ if (!target->tap->enabled)
+ return jim_target_tap_disabled(interp);
+
+ if (allow_defer && target->defer_examine) {
+ LOG_INFO("Deferring arp_examine of %s", target_name(target));
+ LOG_INFO("Use arp_examine command to examine it manually!");
+ return JIM_OK;
+ }
+
+ int e = target->type->examine(target);
+ if (e != ERROR_OK)
+ return JIM_ERR;
+ return JIM_OK;
+ }
+
+ static int jim_target_was_examined(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+ {
+ struct target *target = Jim_CmdPrivData(interp);
+
+ Jim_SetResultBool(interp, target_was_examined(target));
+ return JIM_OK;
+ }
+
+ static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+ {
+ struct target *target = Jim_CmdPrivData(interp);
+
+ Jim_SetResultBool(interp, target->defer_examine);
+ return JIM_OK;
+ }
+
+ static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ if (argc != 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
+ return JIM_ERR;
+ }
+ struct target *target = Jim_CmdPrivData(interp);
+
+ if (target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT) != ERROR_OK)
+ return JIM_ERR;
+
+ return JIM_OK;
+ }
+
+ static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ if (argc != 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
+ return JIM_ERR;
+ }
+ struct target *target = Jim_CmdPrivData(interp);
+ if (!target->tap->enabled)
+ return jim_target_tap_disabled(interp);
+
+ int e;
+ if (!(target_was_examined(target)))
+ e = ERROR_TARGET_NOT_EXAMINED;
+ else
+ e = target->type->poll(target);
+ if (e != ERROR_OK)
+ return JIM_ERR;
+ return JIM_OK;
+ }
+
+ static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ Jim_GetOptInfo goi;
+ Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+
+ if (goi.argc != 2) {
+ Jim_WrongNumArgs(interp, 0, argv,
+ "([tT]|[fF]|assert|deassert) BOOL");
+ return JIM_ERR;
+ }
+
+ Jim_Nvp *n;
+ int e = Jim_GetOpt_Nvp(&goi, nvp_assert, &n);
+ if (e != JIM_OK) {
+ Jim_GetOpt_NvpUnknown(&goi, nvp_assert, 1);
+ return e;
+ }
+ /* the halt or not param */
+ jim_wide a;
+ e = Jim_GetOpt_Wide(&goi, &a);
+ if (e != JIM_OK)
+ return e;
+
+ struct target *target = Jim_CmdPrivData(goi.interp);
+ if (!target->tap->enabled)
+ return jim_target_tap_disabled(interp);
+
+ if (!target->type->assert_reset || !target->type->deassert_reset) {
+ Jim_SetResultFormatted(interp,
+ "No target-specific reset for %s",
+ target_name(target));
+ return JIM_ERR;
+ }
+
+ if (target->defer_examine)
+ target_reset_examined(target);
+
+ /* determine if we should halt or not. */
+ target->reset_halt = !!a;
+ /* When this happens - all workareas are invalid. */
+ target_free_all_working_areas_restore(target, 0);
+
+ /* do the assert */
+ if (n->value == NVP_ASSERT)
+ e = target->type->assert_reset(target);
+ else
+ e = target->type->deassert_reset(target);
+ return (e == ERROR_OK) ? JIM_OK : JIM_ERR;
+ }
+
+ static int jim_target_halt(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ if (argc != 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
+ return JIM_ERR;
+ }
+ struct target *target = Jim_CmdPrivData(interp);
+ if (!target->tap->enabled)
+ return jim_target_tap_disabled(interp);
+ int e = target->type->halt(target);
+ return (e == ERROR_OK) ? JIM_OK : JIM_ERR;
+ }
+
+ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ Jim_GetOptInfo goi;
+ Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+
+ /* params: statename timeoutmsecs */
+ if (goi.argc != 2) {
+ const char *cmd_name = Jim_GetString(argv[0], NULL);
+ Jim_SetResultFormatted(goi.interp,
+ "%s ", cmd_name);
+ return JIM_ERR;
+ }
+
+ Jim_Nvp *n;
+ int e = Jim_GetOpt_Nvp(&goi, nvp_target_state, &n);
+ if (e != JIM_OK) {
+ Jim_GetOpt_NvpUnknown(&goi, nvp_target_state, 1);
+ return e;
+ }
+ jim_wide a;
+ e = Jim_GetOpt_Wide(&goi, &a);
+ if (e != JIM_OK)
+ return e;
+ struct target *target = Jim_CmdPrivData(interp);
+ if (!target->tap->enabled)
+ return jim_target_tap_disabled(interp);
+
+ e = target_wait_state(target, n->value, a);
+ if (e != ERROR_OK) {
+ Jim_Obj *eObj = Jim_NewIntObj(interp, e);
+ Jim_SetResultFormatted(goi.interp,
+ "target: %s wait %s fails (%#s) %s",
+ target_name(target), n->name,
+ eObj, target_strerror_safe(e));
+ Jim_FreeNewObj(interp, eObj);
+ return JIM_ERR;
+ }
+ return JIM_OK;
+ }
+ /* List for human, Events defined for this target.
+ * scripts/programs should use 'name cget -event NAME'
+ */
+ static int jim_target_event_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx != NULL);
+
+ struct target *target = Jim_CmdPrivData(interp);
+ struct target_event_action *teap = target->event_action;
+ command_print(cmd_ctx, "Event actions for target (%d) %s\n",
+ target->target_number,
+ target_name(target));
+ command_print(cmd_ctx, "%-25s | Body", "Event");
+ command_print(cmd_ctx, "------------------------- | "
+ "----------------------------------------");
+ while (teap) {
+ Jim_Nvp *opt = Jim_Nvp_value2name_simple(nvp_target_event, teap->event);
+ command_print(cmd_ctx, "%-25s | %s",
+ opt->name, Jim_GetString(teap->body, NULL));
+ teap = teap->next;
+ }
+ command_print(cmd_ctx, "***END***");
+ return JIM_OK;
+ }
+ static int jim_target_current_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ if (argc != 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
+ return JIM_ERR;
+ }
+ struct target *target = Jim_CmdPrivData(interp);
+ Jim_SetResultString(interp, target_state_name(target), -1);
+ return JIM_OK;
+ }
+ static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ Jim_GetOptInfo goi;
+ Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+ if (goi.argc != 1) {
+ const char *cmd_name = Jim_GetString(argv[0], NULL);
+ Jim_SetResultFormatted(goi.interp, "%s ", cmd_name);
+ return JIM_ERR;
+ }
+ Jim_Nvp *n;
+ int e = Jim_GetOpt_Nvp(&goi, nvp_target_event, &n);
+ if (e != JIM_OK) {
+ Jim_GetOpt_NvpUnknown(&goi, nvp_target_event, 1);
+ return e;
+ }
+ struct target *target = Jim_CmdPrivData(interp);
+ target_handle_event(target, n->value);
+ return JIM_OK;
+ }
+
+ static const struct command_registration target_instance_command_handlers[] = {
+ {
+ .name = "configure",
+ .mode = COMMAND_CONFIG,
+ .jim_handler = jim_target_configure,
+ .help = "configure a new target for use",
+ .usage = "[target_attribute ...]",
+ },
+ {
+ .name = "cget",
+ .mode = COMMAND_ANY,
+ .jim_handler = jim_target_configure,
+ .help = "returns the specified target attribute",
+ .usage = "target_attribute",
+ },
+ {
+ .name = "mww",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_mw,
+ .help = "Write 32-bit word(s) to target memory",
+ .usage = "address data [count]",
+ },
+ {
+ .name = "mwh",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_mw,
+ .help = "Write 16-bit half-word(s) to target memory",
+ .usage = "address data [count]",
+ },
+ {
+ .name = "mwb",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_mw,
+ .help = "Write byte(s) to target memory",
+ .usage = "address data [count]",
+ },
+ {
+ .name = "mdw",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_md,
+ .help = "Display target memory as 32-bit words",
+ .usage = "address [count]",
+ },
+ {
+ .name = "mdh",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_md,
+ .help = "Display target memory as 16-bit half-words",
+ .usage = "address [count]",
+ },
+ {
+ .name = "mdb",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_md,
+ .help = "Display target memory as 8-bit bytes",
+ .usage = "address [count]",
+ },
+ {
+ .name = "array2mem",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_array2mem,
+ .help = "Writes Tcl array of 8/16/32 bit numbers "
+ "to target memory",
+ .usage = "arrayname bitwidth address count",
+ },
+ {
+ .name = "mem2array",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_mem2array,
+ .help = "Loads Tcl array of 8/16/32 bit numbers "
+ "from target memory",
+ .usage = "arrayname bitwidth address count",
+ },
+ {
+ .name = "eventlist",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_event_list,
+ .help = "displays a table of events defined for this target",
+ },
+ {
+ .name = "curstate",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_current_state,
+ .help = "displays the current state of this target",
+ },
+ {
+ .name = "arp_examine",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_examine,
+ .help = "used internally for reset processing",
+ .usage = "arp_examine ['allow-defer']",
+ },
+ {
+ .name = "was_examined",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_was_examined,
+ .help = "used internally for reset processing",
+ .usage = "was_examined",
+ },
+ {
+ .name = "examine_deferred",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_examine_deferred,
+ .help = "used internally for reset processing",
+ .usage = "examine_deferred",
+ },
+ {
+ .name = "arp_halt_gdb",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_halt_gdb,
+ .help = "used internally for reset processing to halt GDB",
+ },
+ {
+ .name = "arp_poll",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_poll,
+ .help = "used internally for reset processing",
+ },
+ {
+ .name = "arp_reset",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_reset,
+ .help = "used internally for reset processing",
+ },
+ {
+ .name = "arp_halt",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_halt,
+ .help = "used internally for reset processing",
+ },
+ {
+ .name = "arp_waitstate",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_wait_state,
+ .help = "used internally for reset processing",
+ },
+ {
+ .name = "invoke-event",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_target_invoke_event,
+ .help = "invoke handler for specified event",
+ .usage = "event_name",
+ },
+ COMMAND_REGISTRATION_DONE
+ };
+
+ static int target_create(Jim_GetOptInfo *goi)
+ {
+ Jim_Obj *new_cmd;
+ Jim_Cmd *cmd;
+ const char *cp;
+ int e;
+ int x;
+ struct target *target;
+ struct command_context *cmd_ctx;
+
+ cmd_ctx = current_command_context(goi->interp);
+ assert(cmd_ctx != NULL);
+
+ if (goi->argc < 3) {
+ Jim_WrongNumArgs(goi->interp, 1, goi->argv, "?name? ?type? ..options...");
+ return JIM_ERR;
+ }
+
+ /* COMMAND */
+ Jim_GetOpt_Obj(goi, &new_cmd);
+ /* does this command exist? */
+ cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
+ if (cmd) {
+ cp = Jim_GetString(new_cmd, NULL);
+ Jim_SetResultFormatted(goi->interp, "Command/target: %s Exists", cp);
+ return JIM_ERR;
+ }
+
+ /* TYPE */
+ e = Jim_GetOpt_String(goi, &cp, NULL);
+ if (e != JIM_OK)
+ return e;
+ struct transport *tr = get_current_transport();
+ if (tr->override_target) {
+ e = tr->override_target(&cp);
+ if (e != ERROR_OK) {
+ LOG_ERROR("The selected transport doesn't support this target");
+ return JIM_ERR;
+ }
+ LOG_INFO("The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD");
+ }
+ /* now does target type exist */
+ for (x = 0 ; target_types[x] ; x++) {
+ if (0 == strcmp(cp, target_types[x]->name)) {
+ /* found */
+ break;
+ }
+
+ /* check for deprecated name */
+ if (target_types[x]->deprecated_name) {
+ if (0 == strcmp(cp, target_types[x]->deprecated_name)) {
+ /* found */
+ LOG_WARNING("target name is deprecated use: \'%s\'", target_types[x]->name);
+ break;
+ }
+ }
+ }
+ if (target_types[x] == NULL) {
+ Jim_SetResultFormatted(goi->interp, "Unknown target type %s, try one of ", cp);
+ for (x = 0 ; target_types[x] ; x++) {
+ if (target_types[x + 1]) {
+ Jim_AppendStrings(goi->interp,
+ Jim_GetResult(goi->interp),
+ target_types[x]->name,
+ ", ", NULL);
+ } else {
+ Jim_AppendStrings(goi->interp,
+ Jim_GetResult(goi->interp),
+ " or ",
+ target_types[x]->name, NULL);
+ }
+ }
+ return JIM_ERR;
+ }
+
+ /* Create it */
+ target = calloc(1, sizeof(struct target));
+ /* set target number */
+ target->target_number = new_target_number();
+ cmd_ctx->current_target = target->target_number;
+
+ /* allocate memory for each unique target type */
+ target->type = calloc(1, sizeof(struct target_type));
+
+ memcpy(target->type, target_types[x], sizeof(struct target_type));
+
+ /* will be set by "-endian" */
+ target->endianness = TARGET_ENDIAN_UNKNOWN;
+
+ /* default to first core, override with -coreid */
+ target->coreid = 0;
+
+ target->working_area = 0x0;
+ target->working_area_size = 0x0;
+ target->working_areas = NULL;
+ target->backup_working_area = 0;
+
+ target->state = TARGET_UNKNOWN;
+ target->debug_reason = DBG_REASON_UNDEFINED;
+ target->reg_cache = NULL;
+ target->breakpoints = NULL;
+ target->watchpoints = NULL;
+ target->next = NULL;
+ target->arch_info = NULL;
+
+ target->display = 1;
+
+ target->halt_issued = false;
+
+ /* initialize trace information */
+ target->trace_info = calloc(1, sizeof(struct trace));
+
+ target->dbgmsg = NULL;
+ target->dbg_msg_enabled = 0;
+
+ target->endianness = TARGET_ENDIAN_UNKNOWN;
+
+ target->rtos = NULL;
+ target->rtos_auto_detect = false;
+
+ /* Do the rest as "configure" options */
+ goi->isconfigure = 1;
+ e = target_configure(goi, target);
+
+ if (target->tap == NULL) {
+ Jim_SetResultString(goi->interp, "-chain-position required when creating target", -1);
+ e = JIM_ERR;
+ }
+
+ if (e != JIM_OK) {
+ free(target->type);
+ free(target);
+ return e;
+ }
+
+ if (target->endianness == TARGET_ENDIAN_UNKNOWN) {
+ /* default endian to little if not specified */
+ target->endianness = TARGET_LITTLE_ENDIAN;
+ }
+
+ cp = Jim_GetString(new_cmd, NULL);
+ target->cmd_name = strdup(cp);
+
+ /* create the target specific commands */
+ if (target->type->commands) {
+ e = register_commands(cmd_ctx, NULL, target->type->commands);
+ if (ERROR_OK != e)
+ LOG_ERROR("unable to register '%s' commands", cp);
+ }
+ if (target->type->target_create)
+ (*(target->type->target_create))(target, goi->interp);
+
+ /* append to end of list */
+ {
+ struct target **tpp;
+ tpp = &(all_targets);
+ while (*tpp)
+ tpp = &((*tpp)->next);
+ *tpp = target;
+ }
+
+ /* now - create the new target name command */
+ const struct command_registration target_subcommands[] = {
+ {
+ .chain = target_instance_command_handlers,
+ },
+ {
+ .chain = target->type->commands,
+ },
+ COMMAND_REGISTRATION_DONE
+ };
+ const struct command_registration target_commands[] = {
+ {
+ .name = cp,
+ .mode = COMMAND_ANY,
+ .help = "target command group",
+ .usage = "",
+ .chain = target_subcommands,
+ },
+ COMMAND_REGISTRATION_DONE
+ };
+ e = register_commands(cmd_ctx, NULL, target_commands);
+ if (ERROR_OK != e)
+ return JIM_ERR;
+
+ struct command *c = command_find_in_context(cmd_ctx, cp);
+ assert(c);
+ command_set_handler_data(c, target);
+
+ return (ERROR_OK == e) ? JIM_OK : JIM_ERR;
+ }
+
+ static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ if (argc != 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
+ return JIM_ERR;
+ }
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx != NULL);
+
+ Jim_SetResultString(interp, target_name(get_current_target(cmd_ctx)), -1);
+ return JIM_OK;
+ }
+
+ static int jim_target_types(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ if (argc != 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
+ for (unsigned x = 0; NULL != target_types[x]; x++) {
+ Jim_ListAppendElement(interp, Jim_GetResult(interp),
+ Jim_NewStringObj(interp, target_types[x]->name, -1));
+ }
+ return JIM_OK;
+ }
+
+ static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ if (argc != 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
+ struct target *target = all_targets;
+ while (target) {
+ Jim_ListAppendElement(interp, Jim_GetResult(interp),
+ Jim_NewStringObj(interp, target_name(target), -1));
+ target = target->next;
+ }
+ return JIM_OK;
+ }
+
+ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ int i;
+ const char *targetname;
+ int retval, len;
+ struct target *target = (struct target *) NULL;
+ struct target_list *head, *curr, *new;
+ curr = (struct target_list *) NULL;
+ head = (struct target_list *) NULL;
+
+ retval = 0;
+ LOG_DEBUG("%d", argc);
+ /* argv[1] = target to associate in smp
+ * argv[2] = target to assoicate in smp
+ * argv[3] ...
+ */
+
+ for (i = 1; i < argc; i++) {
+
+ targetname = Jim_GetString(argv[i], &len);
+ target = get_target(targetname);
+ LOG_DEBUG("%s ", targetname);
+ if (target) {
+ new = malloc(sizeof(struct target_list));
+ new->target = target;
+ new->next = (struct target_list *)NULL;
+ if (head == (struct target_list *)NULL) {
+ head = new;
+ curr = head;
+ } else {
+ curr->next = new;
+ curr = new;
+ }
+ }
+ }
+ /* now parse the list of cpu and put the target in smp mode*/
+ curr = head;
+
+ while (curr != (struct target_list *)NULL) {
+ target = curr->target;
+ target->smp = 1;
+ target->head = head;
+ curr = curr->next;
+ }
+
+ if (target && target->rtos)
+ retval = rtos_smp_init(head->target);
+
+ return retval;
+ }
+
+
+ static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+ {
+ Jim_GetOptInfo goi;
+ Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+ if (goi.argc < 3) {
+ Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
+ " [ ...]");
+ return JIM_ERR;
+ }
+ return target_create(&goi);
+ }
+
+ static const struct command_registration target_subcommand_handlers[] = {
+ {
+ .name = "init",
+ .mode = COMMAND_CONFIG,
+ .handler = handle_target_init_command,
+ .help = "initialize targets",
+ },
+ {
+ .name = "create",
+ /* REVISIT this should be COMMAND_CONFIG ... */
+ .mode = COMMAND_ANY,
+ .jim_handler = jim_target_create,
+ .usage = "name type '-chain-position' name [options ...]",
+ .help = "Creates and selects a new target",
+ },
+ {
+ .name = "current",
+ .mode = COMMAND_ANY,
+ .jim_handler = jim_target_current,
+ .help = "Returns the currently selected target",
+ },
+ {
+ .name = "types",
+ .mode = COMMAND_ANY,
+ .jim_handler = jim_target_types,
+ .help = "Returns the available target types as "
+ "a list of strings",
+ },
+ {
+ .name = "names",
+ .mode = COMMAND_ANY,
+ .jim_handler = jim_target_names,
+ .help = "Returns the names of all targets as a list of strings",
+ },
+ {
+ .name = "smp",
+ .mode = COMMAND_ANY,
+ .jim_handler = jim_target_smp,
+ .usage = "targetname1 targetname2 ...",
+ .help = "gather several target in a smp list"
+ },
+
+ COMMAND_REGISTRATION_DONE
+ };
+
+ struct FastLoad {
+ target_addr_t address;
+ uint8_t *data;
+ int length;
+
+ };
+
+ static int fastload_num;
+ static struct FastLoad *fastload;
+
+ static void free_fastload(void)
+ {
+ if (fastload != NULL) {
+ int i;
+ for (i = 0; i < fastload_num; i++) {
+ if (fastload[i].data)
+ free(fastload[i].data);
+ }
+ free(fastload);
+ fastload = NULL;
+ }
+ }
+
+ COMMAND_HANDLER(handle_fast_load_image_command)
+ {
+ uint8_t *buffer;
+ size_t buf_cnt;
+ uint32_t image_size;
+ target_addr_t min_address = 0;
+ target_addr_t max_address = -1;
+ int i;
+
+ struct image image;
+
+ int retval = CALL_COMMAND_HANDLER(parse_load_image_command_CMD_ARGV,
+ &image, &min_address, &max_address);
+ if (ERROR_OK != retval)
+ return retval;
+
+ struct duration bench;
+ duration_start(&bench);
+
+ retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL);
+ if (retval != ERROR_OK)
+ return retval;
+
+ image_size = 0x0;
+ retval = ERROR_OK;
+ fastload_num = image.num_sections;
+ fastload = malloc(sizeof(struct FastLoad)*image.num_sections);
+ if (fastload == NULL) {
+ command_print(CMD_CTX, "out of memory");
+ image_close(&image);
+ return ERROR_FAIL;
+ }
+ memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
+ for (i = 0; i < image.num_sections; i++) {
+ buffer = malloc(image.sections[i].size);
+ if (buffer == NULL) {
+ command_print(CMD_CTX, "error allocating buffer for section (%d bytes)",
+ (int)(image.sections[i].size));
+ retval = ERROR_FAIL;
+ break;
+ }
+
+ retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);
+ if (retval != ERROR_OK) {
+ free(buffer);
+ break;
+ }
+
+ uint32_t offset = 0;
+ uint32_t length = buf_cnt;
+
+ /* DANGER!!! beware of unsigned comparision here!!! */
+
+ if ((image.sections[i].base_address + buf_cnt >= min_address) &&
+ (image.sections[i].base_address < max_address)) {
+ if (image.sections[i].base_address < min_address) {
+ /* clip addresses below */
+ offset += min_address-image.sections[i].base_address;
+ length -= offset;
+ }
+
+ if (image.sections[i].base_address + buf_cnt > max_address)
+ length -= (image.sections[i].base_address + buf_cnt)-max_address;
+
+ fastload[i].address = image.sections[i].base_address + offset;
+ fastload[i].data = malloc(length);
+ if (fastload[i].data == NULL) {
+ free(buffer);
+ command_print(CMD_CTX, "error allocating buffer for section (%" PRIu32 " bytes)",
+ length);
+ retval = ERROR_FAIL;
+ break;
+ }
+ memcpy(fastload[i].data, buffer + offset, length);
+ fastload[i].length = length;
+
+ image_size += length;
+ command_print(CMD_CTX, "%u bytes written at address 0x%8.8x",
+ (unsigned int)length,
+ ((unsigned int)(image.sections[i].base_address + offset)));
+ }
+
+ free(buffer);
+ }
+
+ if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
+ command_print(CMD_CTX, "Loaded %" PRIu32 " bytes "
+ "in %fs (%0.3f KiB/s)", image_size,
+ duration_elapsed(&bench), duration_kbps(&bench, image_size));
+
+ command_print(CMD_CTX,
+ "WARNING: image has not been loaded to target!"
+ "You can issue a 'fast_load' to finish loading.");
+ }
+
+ image_close(&image);
+
+ if (retval != ERROR_OK)
+ free_fastload();
+
+ return retval;
+ }
+
+ COMMAND_HANDLER(handle_fast_load_command)
+ {
+ if (CMD_ARGC > 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ if (fastload == NULL) {
+ LOG_ERROR("No image in memory");
+ return ERROR_FAIL;
+ }
+ int i;
+ int64_t ms = timeval_ms();
+ int size = 0;
+ int retval = ERROR_OK;
+ for (i = 0; i < fastload_num; i++) {
+ struct target *target = get_current_target(CMD_CTX);
+ command_print(CMD_CTX, "Write to 0x%08x, length 0x%08x",
+ (unsigned int)(fastload[i].address),
+ (unsigned int)(fastload[i].length));
+ retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data);
+ if (retval != ERROR_OK)
+ break;
+ size += fastload[i].length;
+ }
+ if (retval == ERROR_OK) {
+ int64_t after = timeval_ms();
+ command_print(CMD_CTX, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
+ }
+ return retval;
+ }
+
+ static const struct command_registration target_command_handlers[] = {
+ {
+ .name = "targets",
+ .handler = handle_targets_command,
+ .mode = COMMAND_ANY,
+ .help = "change current default target (one parameter) "
+ "or prints table of all targets (no parameters)",
+ .usage = "[target]",
+ },
+ {
+ .name = "target",
+ .mode = COMMAND_CONFIG,
+ .help = "configure target",
+
+ .chain = target_subcommand_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+ };
+
+ int target_register_commands(struct command_context *cmd_ctx)
+ {
+ return register_commands(cmd_ctx, NULL, target_command_handlers);
+ }
+
+ static bool target_reset_nag = true;
+
+ bool get_target_reset_nag(void)
+ {
+ return target_reset_nag;
+ }
+
+ COMMAND_HANDLER(handle_target_reset_nag)
+ {
+ return CALL_COMMAND_HANDLER(handle_command_parse_bool,
+ &target_reset_nag, "Nag after each reset about options to improve "
+ "performance");
+ }
+
+ COMMAND_HANDLER(handle_ps_command)
+ {
+ struct target *target = get_current_target(CMD_CTX);
+ char *display;
+ if (target->state != TARGET_HALTED) {
+ LOG_INFO("target not halted !!");
+ return ERROR_OK;
+ }
+
+ if ((target->rtos) && (target->rtos->type)
+ && (target->rtos->type->ps_command)) {
+ display = target->rtos->type->ps_command(target);
+ command_print(CMD_CTX, "%s", display);
+ free(display);
+ return ERROR_OK;
+ } else {
+ LOG_INFO("failed");
+ return ERROR_TARGET_FAILURE;
+ }
+ }
+
+ static void binprint(struct command_context *cmd_ctx, const char *text, const uint8_t *buf, int size)
+ {
+ if (text != NULL)
+ command_print_sameline(cmd_ctx, "%s", text);
+ for (int i = 0; i < size; i++)
+ command_print_sameline(cmd_ctx, " %02x", buf[i]);
+ command_print(cmd_ctx, " ");
+ }
+
+ COMMAND_HANDLER(handle_test_mem_access_command)
+ {
+ struct target *target = get_current_target(CMD_CTX);
+ uint32_t test_size;
+ int retval = ERROR_OK;
+
+ if (target->state != TARGET_HALTED) {
+ LOG_INFO("target not halted !!");
+ return ERROR_FAIL;
+ }
+
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], test_size);
+
+ /* Test reads */
+ size_t num_bytes = test_size + 4;
+
+ struct working_area *wa = NULL;
+ retval = target_alloc_working_area(target, num_bytes, &wa);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Not enough working area");
+ return ERROR_FAIL;
+ }
+
+ uint8_t *test_pattern = malloc(num_bytes);
+
+ for (size_t i = 0; i < num_bytes; i++)
+ test_pattern[i] = rand();
+
+ retval = target_write_memory(target, wa->address, 1, num_bytes, test_pattern);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Test pattern write failed");
+ goto out;
+ }
+
+ for (int host_offset = 0; host_offset <= 1; host_offset++) {
+ for (int size = 1; size <= 4; size *= 2) {
+ for (int offset = 0; offset < 4; offset++) {
+ uint32_t count = test_size / size;
+ size_t host_bufsiz = (count + 2) * size + host_offset;
+ uint8_t *read_ref = malloc(host_bufsiz);
+ uint8_t *read_buf = malloc(host_bufsiz);
+
+ for (size_t i = 0; i < host_bufsiz; i++) {
+ read_ref[i] = rand();
+ read_buf[i] = read_ref[i];
+ }
+ command_print_sameline(CMD_CTX,
+ "Test read %" PRIu32 " x %d @ %d to %saligned buffer: ", count,
+ size, offset, host_offset ? "un" : "");
+
+ struct duration bench;
+ duration_start(&bench);
+
+ retval = target_read_memory(target, wa->address + offset, size, count,
+ read_buf + size + host_offset);
+
+ duration_measure(&bench);
+
+ if (retval == ERROR_TARGET_UNALIGNED_ACCESS) {
+ command_print(CMD_CTX, "Unsupported alignment");
+ goto next;
+ } else if (retval != ERROR_OK) {
+ command_print(CMD_CTX, "Memory read failed");
+ goto next;
+ }
+
+ /* replay on host */
+ memcpy(read_ref + size + host_offset, test_pattern + offset, count * size);
+
+ /* check result */
+ int result = memcmp(read_ref, read_buf, host_bufsiz);
+ if (result == 0) {
+ command_print(CMD_CTX, "Pass in %fs (%0.3f KiB/s)",
+ duration_elapsed(&bench),
+ duration_kbps(&bench, count * size));
+ } else {
+ command_print(CMD_CTX, "Compare failed");
+ binprint(CMD_CTX, "ref:", read_ref, host_bufsiz);
+ binprint(CMD_CTX, "buf:", read_buf, host_bufsiz);
+ }
+ next:
+ free(read_ref);
+ free(read_buf);
+ }
+ }
+ }
+
+ out:
+ free(test_pattern);
+
+ if (wa != NULL)
+ target_free_working_area(target, wa);
+
+ /* Test writes */
+ num_bytes = test_size + 4 + 4 + 4;
+
+ retval = target_alloc_working_area(target, num_bytes, &wa);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Not enough working area");
+ return ERROR_FAIL;
+ }
+
+ test_pattern = malloc(num_bytes);
+
+ for (size_t i = 0; i < num_bytes; i++)
+ test_pattern[i] = rand();
+
+ for (int host_offset = 0; host_offset <= 1; host_offset++) {
+ for (int size = 1; size <= 4; size *= 2) {
+ for (int offset = 0; offset < 4; offset++) {
+ uint32_t count = test_size / size;
+ size_t host_bufsiz = count * size + host_offset;
+ uint8_t *read_ref = malloc(num_bytes);
+ uint8_t *read_buf = malloc(num_bytes);
+ uint8_t *write_buf = malloc(host_bufsiz);
+
+ for (size_t i = 0; i < host_bufsiz; i++)
+ write_buf[i] = rand();
+ command_print_sameline(CMD_CTX,
+ "Test write %" PRIu32 " x %d @ %d from %saligned buffer: ", count,
+ size, offset, host_offset ? "un" : "");
+
+ retval = target_write_memory(target, wa->address, 1, num_bytes, test_pattern);
+ if (retval != ERROR_OK) {
+ command_print(CMD_CTX, "Test pattern write failed");
+ goto nextw;
+ }
+
+ /* replay on host */
+ memcpy(read_ref, test_pattern, num_bytes);
+ memcpy(read_ref + size + offset, write_buf + host_offset, count * size);
+
+ struct duration bench;
+ duration_start(&bench);
+
+ retval = target_write_memory(target, wa->address + size + offset, size, count,
+ write_buf + host_offset);
+
+ duration_measure(&bench);
+
+ if (retval == ERROR_TARGET_UNALIGNED_ACCESS) {
+ command_print(CMD_CTX, "Unsupported alignment");
+ goto nextw;
+ } else if (retval != ERROR_OK) {
+ command_print(CMD_CTX, "Memory write failed");
+ goto nextw;
+ }
+
+ /* read back */
+ retval = target_read_memory(target, wa->address, 1, num_bytes, read_buf);
+ if (retval != ERROR_OK) {
+ command_print(CMD_CTX, "Test pattern write failed");
+ goto nextw;
+ }
+
+ /* check result */
+ int result = memcmp(read_ref, read_buf, num_bytes);
+ if (result == 0) {
+ command_print(CMD_CTX, "Pass in %fs (%0.3f KiB/s)",
+ duration_elapsed(&bench),
+ duration_kbps(&bench, count * size));
+ } else {
+ command_print(CMD_CTX, "Compare failed");
+ binprint(CMD_CTX, "ref:", read_ref, num_bytes);
+ binprint(CMD_CTX, "buf:", read_buf, num_bytes);
+ }
+ nextw:
+ free(read_ref);
+ free(read_buf);
+ }
+ }
+ }
+
+ free(test_pattern);
+
+ if (wa != NULL)
+ target_free_working_area(target, wa);
+ return retval;
+ }
+
+ static const struct command_registration target_exec_command_handlers[] = {
+ {
+ .name = "fast_load_image",
+ .handler = handle_fast_load_image_command,
+ .mode = COMMAND_ANY,
+ .help = "Load image into server memory for later use by "
+ "fast_load; primarily for profiling",
+ .usage = "filename address ['bin'|'ihex'|'elf'|'s19'] "
+ "[min_address [max_length]]",
+ },
+ {
+ .name = "fast_load",
+ .handler = handle_fast_load_command,
+ .mode = COMMAND_EXEC,
+ .help = "loads active fast load image to current target "
+ "- mainly for profiling purposes",
+ .usage = "",
+ },
+ {
+ .name = "profile",
+ .handler = handle_profile_command,
+ .mode = COMMAND_EXEC,
+ .usage = "seconds filename [start end]",
+ .help = "profiling samples the CPU PC",
+ },
+ /** @todo don't register virt2phys() unless target supports it */
+ {
+ .name = "virt2phys",
+ .handler = handle_virt2phys_command,
+ .mode = COMMAND_ANY,
+ .help = "translate a virtual address into a physical address",
+ .usage = "virtual_address",
+ },
+ {
+ .name = "reg",
+ .handler = handle_reg_command,
+ .mode = COMMAND_EXEC,
+ .help = "display (reread from target with \"force\") or set a register; "
+ "with no arguments, displays all registers and their values",
+ .usage = "[(register_number|register_name) [(value|'force')]]",
+ },
+ {
+ .name = "poll",
+ .handler = handle_poll_command,
+ .mode = COMMAND_EXEC,
+ .help = "poll target state; or reconfigure background polling",
+ .usage = "['on'|'off']",
+ },
+ {
+ .name = "wait_halt",
+ .handler = handle_wait_halt_command,
+ .mode = COMMAND_EXEC,
+ .help = "wait up to the specified number of milliseconds "
+ "(default 5000) for a previously requested halt",
+ .usage = "[milliseconds]",
+ },
+ {
+ .name = "halt",
+ .handler = handle_halt_command,
+ .mode = COMMAND_EXEC,
+ .help = "request target to halt, then wait up to the specified"
+ "number of milliseconds (default 5000) for it to complete",
+ .usage = "[milliseconds]",
+ },
+ {
+ .name = "resume",
+ .handler = handle_resume_command,
+ .mode = COMMAND_EXEC,
+ .help = "resume target execution from current PC or address",
+ .usage = "[address]",
+ },
+ {
+ .name = "reset",
+ .handler = handle_reset_command,
+ .mode = COMMAND_EXEC,
+ .usage = "[run|halt|init]",
+ .help = "Reset all targets into the specified mode."
+ "Default reset mode is run, if not given.",
+ },
+ {
+ .name = "soft_reset_halt",
+ .handler = handle_soft_reset_halt_command,
+ .mode = COMMAND_EXEC,
+ .usage = "",
+ .help = "halt the target and do a soft reset",
+ },
+ {
+ .name = "step",
+ .handler = handle_step_command,
+ .mode = COMMAND_EXEC,
+ .help = "step one instruction from current PC or address",
+ .usage = "[address]",
+ },
+ {
+ .name = "mdd",
+ .handler = handle_md_command,
+ .mode = COMMAND_EXEC,
+ .help = "display memory words",
+ .usage = "['phys'] address [count]",
+ },
+ {
+ .name = "mdw",
+ .handler = handle_md_command,
+ .mode = COMMAND_EXEC,
+ .help = "display memory words",
+ .usage = "['phys'] address [count]",
+ },
+ {
+ .name = "mdh",
+ .handler = handle_md_command,
+ .mode = COMMAND_EXEC,
+ .help = "display memory half-words",
+ .usage = "['phys'] address [count]",
+ },
+ {
+ .name = "mdb",
+ .handler = handle_md_command,
+ .mode = COMMAND_EXEC,
+ .help = "display memory bytes",
+ .usage = "['phys'] address [count]",
+ },
+ {
+ .name = "mwd",
+ .handler = handle_mw_command,
+ .mode = COMMAND_EXEC,
+ .help = "write memory word",
+ .usage = "['phys'] address value [count]",
+ },
+ {
+ .name = "mww",
+ .handler = handle_mw_command,
+ .mode = COMMAND_EXEC,
+ .help = "write memory word",
+ .usage = "['phys'] address value [count]",
+ },
+ {
+ .name = "mwh",
+ .handler = handle_mw_command,
+ .mode = COMMAND_EXEC,
+ .help = "write memory half-word",
+ .usage = "['phys'] address value [count]",
+ },
+ {
+ .name = "mwb",
+ .handler = handle_mw_command,
+ .mode = COMMAND_EXEC,
+ .help = "write memory byte",
+ .usage = "['phys'] address value [count]",
+ },
+ {
+ .name = "bp",
+ .handler = handle_bp_command,
+ .mode = COMMAND_EXEC,
+ .help = "list or set hardware or software breakpoint",
+ .usage = " [] ['hw'|'hw_ctx']",
+ },
+ {
+ .name = "rbp",
+ .handler = handle_rbp_command,
+ .mode = COMMAND_EXEC,
+ .help = "remove breakpoint",
+ .usage = "address",
+ },
+ {
+ .name = "wp",
+ .handler = handle_wp_command,
+ .mode = COMMAND_EXEC,
+ .help = "list (no params) or create watchpoints",
+ .usage = "[address length [('r'|'w'|'a') value [mask]]]",
+ },
+ {
+ .name = "rwp",
+ .handler = handle_rwp_command,
+ .mode = COMMAND_EXEC,
+ .help = "remove watchpoint",
+ .usage = "address",
+ },
+ {
+ .name = "load_image",
+ .handler = handle_load_image_command,
+ .mode = COMMAND_EXEC,
+ .usage = "filename address ['bin'|'ihex'|'elf'|'s19'] "
+ "[min_address] [max_length]",
+ },
+ {
+ .name = "dump_image",
+ .handler = handle_dump_image_command,
+ .mode = COMMAND_EXEC,
+ .usage = "filename address size",
+ },
+ {
+ .name = "verify_image_checksum",
+ .handler = handle_verify_image_checksum_command,
+ .mode = COMMAND_EXEC,
+ .usage = "filename [offset [type]]",
+ },
+ {
+ .name = "verify_image",
+ .handler = handle_verify_image_command,
+ .mode = COMMAND_EXEC,
+ .usage = "filename [offset [type]]",
+ },
+ {
+ .name = "test_image",
+ .handler = handle_test_image_command,
+ .mode = COMMAND_EXEC,
+ .usage = "filename [offset [type]]",
+ },
+ {
+ .name = "mem2array",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_mem2array,
+ .help = "read 8/16/32 bit memory and return as a TCL array "
+ "for script processing",
+ .usage = "arrayname bitwidth address count",
+ },
+ {
+ .name = "array2mem",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_array2mem,
+ .help = "convert a TCL array to memory locations "
+ "and write the 8/16/32 bit values",
+ .usage = "arrayname bitwidth address count",
+ },
+ {
+ .name = "reset_nag",
+ .handler = handle_target_reset_nag,
+ .mode = COMMAND_ANY,
+ .help = "Nag after each reset about options that could have been "
+ "enabled to improve performance. ",
+ .usage = "['enable'|'disable']",
+ },
+ {
+ .name = "ps",
+ .handler = handle_ps_command,
+ .mode = COMMAND_EXEC,
+ .help = "list all tasks ",
+ .usage = " ",
+ },
+ {
+ .name = "test_mem_access",
+ .handler = handle_test_mem_access_command,
+ .mode = COMMAND_EXEC,
+ .help = "Test the target's memory access functions",
+ .usage = "size",
+ },
+
+ COMMAND_REGISTRATION_DONE
+ };
+ static int target_register_user_commands(struct command_context *cmd_ctx)
+ {
+ int retval = ERROR_OK;
+ retval = target_request_register_commands(cmd_ctx);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = trace_register_commands(cmd_ctx);
+ if (retval != ERROR_OK)
+ return retval;
+
+
+ return register_commands(cmd_ctx, NULL, target_exec_command_handlers);
+ }
diff --git a/src/target/target.h b/src/target/target.h
index 4faf3119f..53f9e2614 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -25,13 +25,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef TARGET_H
-#define TARGET_H
+#ifndef OPENOCD_TARGET_TARGET_H
+#define OPENOCD_TARGET_TARGET_H
#include
@@ -95,7 +93,7 @@ enum target_endianness {
};
struct working_area {
- uint32_t address;
+ target_addr_t address;
uint32_t size;
bool free;
uint8_t *backup;
@@ -127,11 +125,14 @@ enum target_register_class {
/* target_type.h contains the full definition of struct target_type */
struct target {
struct target_type *type; /* target type definition (name, access functions) */
- const char *cmd_name; /* tcl Name of target */
+ char *cmd_name; /* tcl Name of target */
int target_number; /* DO NOT USE! field to be removed in 2010 */
struct jtag_tap *tap; /* where on the jtag chain is this */
int32_t coreid; /* which device on the TAP? */
+ /** Should we defer examine to later */
+ bool defer_examine;
+
/**
* Indicates whether this target has been examined.
*
@@ -155,9 +156,9 @@ struct target {
uint32_t working_area; /* working area (initialised RAM). Evaluated
* upon first allocation from virtual/physical address. */
bool working_area_virt_spec; /* virtual address specified? */
- uint32_t working_area_virt; /* virtual address */
- bool working_area_phys_spec; /* virtual address specified? */
- uint32_t working_area_phys; /* physical address */
+ target_addr_t working_area_virt; /* virtual address */
+ bool working_area_phys_spec; /* physical address specified? */
+ target_addr_t working_area_phys; /* physical address */
uint32_t working_area_size; /* size in bytes */
uint32_t backup_working_area; /* whether the content of the working area has to be preserved */
struct working_area *working_areas;/* list of allocated working areas */
@@ -172,17 +173,23 @@ struct target {
struct debug_msg_receiver *dbgmsg; /* list of debug message receivers */
uint32_t dbg_msg_enabled; /* debug message status */
void *arch_info; /* architecture specific information */
+ void *private_config; /* pointer to target specific config data (for jim_configure hook) */
struct target *next; /* next target in list */
int display; /* display async info in telnet session. Do not display
* lots of halted/resumed info when stepping in debugger. */
bool halt_issued; /* did we transition to halted state? */
- long long halt_issued_time; /* Note time when halt was issued */
+ int64_t halt_issued_time; /* Note time when halt was issued */
bool dbgbase_set; /* By default the debug base is not set */
uint32_t dbgbase; /* Really a Cortex-A specific option, but there is no
* system in place to support target specific options
* currently. */
+
+ bool ctibase_set; /* By default the debug base is not set */
+ uint32_t ctibase; /* Really a Cortex-A specific option, but there is no
+ * system in place to support target specific options
+ * currently. */
struct rtos *rtos; /* Instance of Real Time Operating System support */
bool rtos_auto_detect; /* A flag that indicates that the RTOS has been specified as "auto"
* and must be detected when symbols are offered */
@@ -351,7 +358,7 @@ int target_unregister_trace_callback(
* yet it is possible to detect error conditions.
*/
int target_poll(struct target *target);
-int target_resume(struct target *target, int current, uint32_t address,
+int target_resume(struct target *target, int current, target_addr_t address,
int handle_breakpoints, int debug_execution);
int target_halt(struct target *target);
int target_call_event_callbacks(struct target *target, enum target_event event);
@@ -472,7 +479,7 @@ int target_get_gdb_reg_list(struct target *target,
* This routine is a wrapper for target->type->step.
*/
int target_step(struct target *target,
- int current, uint32_t address, int handle_breakpoints);
+ int current, target_addr_t address, int handle_breakpoints);
/**
* Run an algorithm on the @a target given.
*
@@ -525,9 +532,9 @@ int target_run_flash_async_algorithm(struct target *target,
* This routine is a wrapper for target->type->read_memory.
*/
int target_read_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+ target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);
int target_read_phys_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+ target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);
/**
* Write @a count items of @a size bytes to the memory of @a target at
* the @a address given. @a address must be aligned to @a size
@@ -546,9 +553,9 @@ int target_read_phys_memory(struct target *target,
* This routine is wrapper for target->type->write_memory.
*/
int target_write_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
+ target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
int target_write_phys_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
+ target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
/*
* Write to target memory using the virtual address.
@@ -575,13 +582,13 @@ int target_write_phys_memory(struct target *target,
* peripheral registers which do not support byte operations.
*/
int target_write_buffer(struct target *target,
- uint32_t address, uint32_t size, const uint8_t *buffer);
+ target_addr_t address, uint32_t size, const uint8_t *buffer);
int target_read_buffer(struct target *target,
- uint32_t address, uint32_t size, uint8_t *buffer);
+ target_addr_t address, uint32_t size, uint8_t *buffer);
int target_checksum_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t *crc);
+ target_addr_t address, uint32_t size, uint32_t *crc);
int target_blank_check_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t *blank);
+ target_addr_t address, uint32_t size, uint32_t *blank, uint8_t erased_value);
int target_wait_state(struct target *target, enum target_state state, int ms);
/**
@@ -657,14 +664,19 @@ void target_buffer_set_u64_array(struct target *target, uint8_t *buffer, uint32_
void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf);
void target_buffer_set_u16_array(struct target *target, uint8_t *buffer, uint32_t count, const uint16_t *srcbuf);
-int target_read_u64(struct target *target, uint64_t address, uint64_t *value);
-int target_read_u32(struct target *target, uint32_t address, uint32_t *value);
-int target_read_u16(struct target *target, uint32_t address, uint16_t *value);
-int target_read_u8(struct target *target, uint32_t address, uint8_t *value);
-int target_write_u64(struct target *target, uint64_t address, uint64_t value);
-int target_write_u32(struct target *target, uint32_t address, uint32_t value);
-int target_write_u16(struct target *target, uint32_t address, uint16_t value);
-int target_write_u8(struct target *target, uint32_t address, uint8_t value);
+int target_read_u64(struct target *target, target_addr_t address, uint64_t *value);
+int target_read_u32(struct target *target, target_addr_t address, uint32_t *value);
+int target_read_u16(struct target *target, target_addr_t address, uint16_t *value);
+int target_read_u8(struct target *target, target_addr_t address, uint8_t *value);
+int target_write_u64(struct target *target, target_addr_t address, uint64_t value);
+int target_write_u32(struct target *target, target_addr_t address, uint32_t value);
+int target_write_u16(struct target *target, target_addr_t address, uint16_t value);
+int target_write_u8(struct target *target, target_addr_t address, uint8_t value);
+
+int target_write_phys_u64(struct target *target, target_addr_t address, uint64_t value);
+int target_write_phys_u32(struct target *target, target_addr_t address, uint32_t value);
+int target_write_phys_u16(struct target *target, target_addr_t address, uint16_t value);
+int target_write_phys_u8(struct target *target, target_addr_t address, uint8_t value);
/* Issues USER() statements with target state information */
int target_arch_state(struct target *target);
@@ -685,4 +697,4 @@ void target_handle_event(struct target *t, enum target_event e);
extern bool get_target_reset_nag(void);
-#endif /* TARGET_H */
+#endif /* OPENOCD_TARGET_TARGET_H */
diff --git a/src/target/target_request.c b/src/target/target_request.c
index df2fc34ee..6ca204b50 100644
--- a/src/target/target_request.c
+++ b/src/target/target_request.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/target_request.h b/src/target/target_request.h
index 55ac0e9bf..1b1317338 100644
--- a/src/target/target_request.h
+++ b/src/target/target_request.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef TARGET_REQUEST_H
-#define TARGET_REQUEST_H
+#ifndef OPENOCD_TARGET_TARGET_REQUEST_H
+#define OPENOCD_TARGET_TARGET_REQUEST_H
struct target;
struct command_context;
@@ -54,4 +52,4 @@ int target_request_register_commands(struct command_context *cmd_ctx);
*/
bool target_got_message(void);
-#endif /* TARGET_REQUEST_H */
+#endif /* OPENOCD_TARGET_TARGET_REQUEST_H */
diff --git a/src/target/target_type.h b/src/target/target_type.h
index 234cdfb00..0960e6d59 100644
--- a/src/target/target_type.h
+++ b/src/target/target_type.h
@@ -19,13 +19,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef TARGET_TYPE_H
-#define TARGET_TYPE_H
+#ifndef OPENOCD_TARGET_TARGET_TYPE_H
+#define OPENOCD_TARGET_TARGET_TYPE_H
#include
@@ -55,11 +53,11 @@ struct target_type {
/* halt will log a warning, but return ERROR_OK if the target is already halted. */
int (*halt)(struct target *target);
- int (*resume)(struct target *target, int current, uint32_t address,
+ /* See target.c target_resume() for documentation. */
+ int (*resume)(struct target *target, int current, target_addr_t address,
int handle_breakpoints, int debug_execution);
- int (*step)(struct target *target, int current, uint32_t address,
+ int (*step)(struct target *target, int current, target_addr_t address,
int handle_breakpoints);
-
/* target reset control. assert reset can be invoked when OpenOCD and
* the target is out of sync.
*
@@ -113,27 +111,27 @@ struct target_type {
* Target memory read callback. Do @b not call this function
* directly, use target_read_memory() instead.
*/
- int (*read_memory)(struct target *target, uint32_t address,
+ int (*read_memory)(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer);
/**
* Target memory write callback. Do @b not call this function
* directly, use target_write_memory() instead.
*/
- int (*write_memory)(struct target *target, uint32_t address,
+ int (*write_memory)(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
/* Default implementation will do some fancy alignment to improve performance, target can override */
- int (*read_buffer)(struct target *target, uint32_t address,
+ int (*read_buffer)(struct target *target, target_addr_t address,
uint32_t size, uint8_t *buffer);
/* Default implementation will do some fancy alignment to improve performance, target can override */
- int (*write_buffer)(struct target *target, uint32_t address,
+ int (*write_buffer)(struct target *target, target_addr_t address,
uint32_t size, const uint8_t *buffer);
- int (*checksum_memory)(struct target *target, uint32_t address,
+ int (*checksum_memory)(struct target *target, target_addr_t address,
uint32_t count, uint32_t *checksum);
- int (*blank_check_memory)(struct target *target, uint32_t address,
- uint32_t count, uint32_t *blank);
+ int (*blank_check_memory)(struct target *target, target_addr_t address,
+ uint32_t count, uint32_t *blank, uint8_t erased_value);
/*
* target break-/watchpoint control
@@ -177,15 +175,15 @@ struct target_type {
*/
int (*run_algorithm)(struct target *target, int num_mem_params,
struct mem_param *mem_params, int num_reg_params,
- struct reg_param *reg_param, uint32_t entry_point,
- uint32_t exit_point, int timeout_ms, void *arch_info);
+ struct reg_param *reg_param, target_addr_t entry_point,
+ target_addr_t exit_point, int timeout_ms, void *arch_info);
int (*start_algorithm)(struct target *target, int num_mem_params,
struct mem_param *mem_params, int num_reg_params,
- struct reg_param *reg_param, uint32_t entry_point,
- uint32_t exit_point, void *arch_info);
+ struct reg_param *reg_param, target_addr_t entry_point,
+ target_addr_t exit_point, void *arch_info);
int (*wait_algorithm)(struct target *target, int num_mem_params,
struct mem_param *mem_params, int num_reg_params,
- struct reg_param *reg_param, uint32_t exit_point,
+ struct reg_param *reg_param, target_addr_t exit_point,
int timeout_ms, void *arch_info);
const struct command_registration *commands;
@@ -235,7 +233,7 @@ struct target_type {
/* translate from virtual to physical address. Default implementation is successful
* no-op(i.e. virtual==physical).
*/
- int (*virt2phys)(struct target *target, uint32_t address, uint32_t *physical);
+ int (*virt2phys)(struct target *target, target_addr_t address, target_addr_t *physical);
/* read directly from physical memory. caches are bypassed and untouched.
*
@@ -245,13 +243,13 @@ struct target_type {
*
* Default implementation is to call read_memory.
*/
- int (*read_phys_memory)(struct target *target, uint32_t phys_address,
+ int (*read_phys_memory)(struct target *target, target_addr_t phys_address,
uint32_t size, uint32_t count, uint8_t *buffer);
/*
* same as read_phys_memory, except that it writes...
*/
- int (*write_phys_memory)(struct target *target, uint32_t phys_address,
+ int (*write_phys_memory)(struct target *target, target_addr_t phys_address,
uint32_t size, uint32_t count, const uint8_t *buffer);
int (*mmu)(struct target *target, int *enabled);
@@ -278,4 +276,4 @@ struct target_type {
uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);
};
-#endif /* TARGET_TYPE_H */
+#endif /* OPENOCD_TARGET_TARGET_TYPE_H */
diff --git a/src/target/testee.c b/src/target/testee.c
index b95cb82bc..5b6ccedd8 100644
--- a/src/target/testee.c
+++ b/src/target/testee.c
@@ -12,9 +12,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/trace.c b/src/target/trace.c
index 9c2d3698c..63c477fbf 100644
--- a/src/target/trace.c
+++ b/src/target/trace.c
@@ -13,9 +13,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
diff --git a/src/target/trace.h b/src/target/trace.h
index bb9c33637..2966bbd94 100644
--- a/src/target/trace.h
+++ b/src/target/trace.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef TRACE_H
-#define TRACE_H
+#ifndef OPENOCD_TARGET_TRACE_H
+#define OPENOCD_TARGET_TRACE_H
struct target;
struct command_context;
@@ -58,4 +56,4 @@ int trace_register_commands(struct command_context *cmd_ctx);
#define ERROR_TRACE_IMAGE_UNAVAILABLE (-1500)
#define ERROR_TRACE_INSTRUCTION_UNAVAILABLE (-1501)
-#endif /* TRACE_H */
+#endif /* OPENOCD_TARGET_TRACE_H */
diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c
index 3a26f71d1..34f92eaca 100644
--- a/src/target/x86_32_common.c
+++ b/src/target/x86_32_common.c
@@ -18,8 +18,7 @@
* 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., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*
* Contact Information:
* Intel Corporation
@@ -49,8 +48,8 @@ static int read_mem(struct target *t, uint32_t size,
uint32_t addr, uint8_t *buf);
static int write_mem(struct target *t, uint32_t size,
uint32_t addr, const uint8_t *buf);
-static int calcaddr_pyhsfromlin(struct target *t, uint32_t addr,
- uint32_t *physaddr);
+static int calcaddr_physfromlin(struct target *t, target_addr_t addr,
+ target_addr_t *physaddr);
static int read_phys_mem(struct target *t, uint32_t phys_address,
uint32_t size, uint32_t count, uint8_t *buffer);
static int write_phys_mem(struct target *t, uint32_t phys_address,
@@ -114,7 +113,7 @@ int x86_32_common_mmu(struct target *t, int *enabled)
return ERROR_OK;
}
-int x86_32_common_virt2phys(struct target *t, uint32_t address, uint32_t *physical)
+int x86_32_common_virt2phys(struct target *t, target_addr_t address, target_addr_t *physical)
{
struct x86_32_common *x86_32 = target_to_x86_32(t);
@@ -135,8 +134,8 @@ int x86_32_common_virt2phys(struct target *t, uint32_t address, uint32_t *physic
} else {
/* target halted in protected mode */
- if (calcaddr_pyhsfromlin(t, address, physical) != ERROR_OK) {
- LOG_ERROR("%s failed to calculate physical address from 0x%08" PRIx32,
+ if (calcaddr_physfromlin(t, address, physical) != ERROR_OK) {
+ LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT,
__func__, address);
return ERROR_FAIL;
}
@@ -144,7 +143,7 @@ int x86_32_common_virt2phys(struct target *t, uint32_t address, uint32_t *physic
return ERROR_OK;
}
-int x86_32_common_read_phys_mem(struct target *t, uint32_t phys_address,
+int x86_32_common_read_phys_mem(struct target *t, target_addr_t phys_address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct x86_32_common *x86_32 = target_to_x86_32(t);
@@ -227,7 +226,7 @@ static int read_phys_mem(struct target *t, uint32_t phys_address,
return retval;
}
-int x86_32_common_write_phys_mem(struct target *t, uint32_t phys_address,
+int x86_32_common_write_phys_mem(struct target *t, target_addr_t phys_address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct x86_32_common *x86_32 = target_to_x86_32(t);
@@ -236,7 +235,7 @@ int x86_32_common_write_phys_mem(struct target *t, uint32_t phys_address,
check_not_halted(t);
if (!count || !buffer || !phys_address) {
- LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=0x%08" PRIx32,
+ LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=" TARGET_ADDR_FMT,
__func__, count, buffer, phys_address);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
@@ -445,7 +444,7 @@ static int write_mem(struct target *t, uint32_t size,
return retval;
}
-int calcaddr_pyhsfromlin(struct target *t, uint32_t addr, uint32_t *physaddr)
+int calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *physaddr)
{
uint8_t entry_buffer[8];
@@ -569,16 +568,16 @@ int calcaddr_pyhsfromlin(struct target *t, uint32_t addr, uint32_t *physaddr)
return ERROR_OK;
}
-int x86_32_common_read_memory(struct target *t, uint32_t addr,
+int x86_32_common_read_memory(struct target *t, target_addr_t addr,
uint32_t size, uint32_t count, uint8_t *buf)
{
int retval = ERROR_OK;
struct x86_32_common *x86_32 = target_to_x86_32(t);
- LOG_DEBUG("addr=0x%08" PRIx32 ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p",
+ LOG_DEBUG("addr=" TARGET_ADDR_FMT ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p",
addr, size, count, buf);
check_not_halted(t);
if (!count || !buf || !addr) {
- LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=0x%08" PRIx32,
+ LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=" TARGET_ADDR_FMT,
__func__, count, buf, addr);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
@@ -592,9 +591,10 @@ int x86_32_common_read_memory(struct target *t, uint32_t addr,
LOG_ERROR("%s could not disable paging", __func__);
return retval;
}
- uint32_t physaddr = 0;
- if (calcaddr_pyhsfromlin(t, addr, &physaddr) != ERROR_OK) {
- LOG_ERROR("%s failed to calculate physical address from 0x%08" PRIx32, __func__, addr);
+ target_addr_t physaddr = 0;
+ if (calcaddr_physfromlin(t, addr, &physaddr) != ERROR_OK) {
+ LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT,
+ __func__, addr);
retval = ERROR_FAIL;
}
/* TODO: !!! Watch out for page boundaries
@@ -604,7 +604,8 @@ int x86_32_common_read_memory(struct target *t, uint32_t addr,
if (retval == ERROR_OK
&& x86_32_common_read_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) {
- LOG_ERROR("%s failed to read memory from physical address 0x%08" PRIx32, __func__, physaddr);
+ LOG_ERROR("%s failed to read memory from physical address " TARGET_ADDR_FMT,
+ __func__, physaddr);
retval = ERROR_FAIL;
}
/* restore PG bit if it was cleared prior (regardless of retval) */
@@ -616,7 +617,8 @@ int x86_32_common_read_memory(struct target *t, uint32_t addr,
} else {
/* paging is off - linear address is physical address */
if (x86_32_common_read_phys_mem(t, addr, size, count, buf) != ERROR_OK) {
- LOG_ERROR("%s failed to read memory from address 0%08" PRIx32, __func__, addr);
+ LOG_ERROR("%s failed to read memory from address " TARGET_ADDR_FMT,
+ __func__, addr);
retval = ERROR_FAIL;
}
}
@@ -624,16 +626,16 @@ int x86_32_common_read_memory(struct target *t, uint32_t addr,
return retval;
}
-int x86_32_common_write_memory(struct target *t, uint32_t addr,
+int x86_32_common_write_memory(struct target *t, target_addr_t addr,
uint32_t size, uint32_t count, const uint8_t *buf)
{
int retval = ERROR_OK;
struct x86_32_common *x86_32 = target_to_x86_32(t);
- LOG_DEBUG("addr=0x%08" PRIx32 ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p",
+ LOG_DEBUG("addr=" TARGET_ADDR_FMT ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p",
addr, size, count, buf);
check_not_halted(t);
if (!count || !buf || !addr) {
- LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=0x%08" PRIx32,
+ LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=" TARGET_ADDR_FMT,
__func__, count, buf, addr);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
@@ -646,9 +648,9 @@ int x86_32_common_write_memory(struct target *t, uint32_t addr,
LOG_ERROR("%s could not disable paging", __func__);
return retval;
}
- uint32_t physaddr = 0;
- if (calcaddr_pyhsfromlin(t, addr, &physaddr) != ERROR_OK) {
- LOG_ERROR("%s failed to calculate physical address from 0x%08" PRIx32,
+ target_addr_t physaddr = 0;
+ if (calcaddr_physfromlin(t, addr, &physaddr) != ERROR_OK) {
+ LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT,
__func__, addr);
retval = ERROR_FAIL;
}
@@ -658,7 +660,7 @@ int x86_32_common_write_memory(struct target *t, uint32_t addr,
*/
if (retval == ERROR_OK
&& x86_32_common_write_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) {
- LOG_ERROR("%s failed to write memory to physical address 0x%08" PRIx32,
+ LOG_ERROR("%s failed to write memory to physical address " TARGET_ADDR_FMT,
__func__, physaddr);
retval = ERROR_FAIL;
}
@@ -672,7 +674,7 @@ int x86_32_common_write_memory(struct target *t, uint32_t addr,
/* paging is off - linear address is physical address */
if (x86_32_common_write_phys_mem(t, addr, size, count, buf) != ERROR_OK) {
- LOG_ERROR("%s failed to write memory to address 0x%08" PRIx32,
+ LOG_ERROR("%s failed to write memory to address " TARGET_ADDR_FMT,
__func__, addr);
retval = ERROR_FAIL;
}
@@ -853,7 +855,7 @@ int x86_32_common_remove_watchpoint(struct target *t, struct watchpoint *wp)
int x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp)
{
- LOG_DEBUG("type=%d, addr=0x%08" PRIx32, bp->type, bp->address);
+ LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
if (check_not_halted(t))
return ERROR_TARGET_NOT_HALTED;
/* set_breakpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
@@ -864,7 +866,7 @@ int x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp)
int x86_32_common_remove_breakpoint(struct target *t, struct breakpoint *bp)
{
- LOG_DEBUG("type=%d, addr=0x%08" PRIx32, bp->type, bp->address);
+ LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
if (check_not_halted(t))
return ERROR_TARGET_NOT_HALTED;
if (bp->set)
@@ -1004,7 +1006,7 @@ static int unset_hwbp(struct target *t, struct breakpoint *bp)
debug_reg_list[hwbp_num].used = 0;
debug_reg_list[hwbp_num].bp_value = 0;
- LOG_USER("%s hardware breakpoint %" PRIu32 " removed from 0x%08" PRIx32 " (hwreg=%d)",
+ LOG_USER("%s hardware breakpoint %" PRIu32 " removed from " TARGET_ADDR_FMT " (hwreg=%d)",
__func__, bp->unique_id, bp->address, hwbp_num);
return ERROR_OK;
}
@@ -1013,11 +1015,11 @@ static int set_swbp(struct target *t, struct breakpoint *bp)
{
struct x86_32_common *x86_32 = target_to_x86_32(t);
LOG_DEBUG("id %" PRIx32, bp->unique_id);
- uint32_t physaddr;
+ target_addr_t physaddr;
uint8_t opcode = SW_BP_OPCODE;
uint8_t readback;
- if (calcaddr_pyhsfromlin(t, bp->address, &physaddr) != ERROR_OK)
+ if (calcaddr_physfromlin(t, bp->address, &physaddr) != ERROR_OK)
return ERROR_FAIL;
if (read_phys_mem(t, physaddr, 1, 1, bp->orig_instr))
return ERROR_FAIL;
@@ -1033,7 +1035,7 @@ static int set_swbp(struct target *t, struct breakpoint *bp)
return ERROR_FAIL;
if (readback != SW_BP_OPCODE) {
- LOG_ERROR("%s software breakpoint error at 0x%08" PRIx32 ", check memory",
+ LOG_ERROR("%s software breakpoint error at " TARGET_ADDR_FMT ", check memory",
__func__, bp->address);
LOG_ERROR("%s readback=0x%02" PRIx8 " orig=0x%02" PRIx8 "",
__func__, readback, *bp->orig_instr);
@@ -1060,7 +1062,7 @@ static int set_swbp(struct target *t, struct breakpoint *bp)
addto = addto->next;
addto->next = new_patch;
}
- LOG_USER("%s software breakpoint %" PRIu32 " set at 0x%08" PRIx32,
+ LOG_USER("%s software breakpoint %" PRIu32 " set at " TARGET_ADDR_FMT,
__func__, bp->unique_id, bp->address);
return ERROR_OK;
}
@@ -1069,11 +1071,11 @@ static int unset_swbp(struct target *t, struct breakpoint *bp)
{
struct x86_32_common *x86_32 = target_to_x86_32(t);
LOG_DEBUG("id %" PRIx32, bp->unique_id);
- uint32_t physaddr;
+ target_addr_t physaddr;
uint8_t current_instr;
/* check that user program has not modified breakpoint instruction */
- if (calcaddr_pyhsfromlin(t, bp->address, &physaddr) != ERROR_OK)
+ if (calcaddr_physfromlin(t, bp->address, &physaddr) != ERROR_OK)
return ERROR_FAIL;
if (read_phys_mem(t, physaddr, 1, 1, ¤t_instr))
return ERROR_FAIL;
@@ -1082,7 +1084,7 @@ static int unset_swbp(struct target *t, struct breakpoint *bp)
if (write_phys_mem(t, physaddr, 1, 1, bp->orig_instr))
return ERROR_FAIL;
} else {
- LOG_ERROR("%s software breakpoint remove error at 0x%08" PRIx32 ", check memory",
+ LOG_ERROR("%s software breakpoint remove error at " TARGET_ADDR_FMT ", check memory",
__func__, bp->address);
LOG_ERROR("%s current=0x%02" PRIx8 " orig=0x%02" PRIx8 "",
__func__, current_instr, *bp->orig_instr);
@@ -1108,7 +1110,7 @@ static int unset_swbp(struct target *t, struct breakpoint *bp)
}
}
- LOG_USER("%s software breakpoint %" PRIu32 " removed from 0x%08" PRIx32,
+ LOG_USER("%s software breakpoint %" PRIu32 " removed from " TARGET_ADDR_FMT,
__func__, bp->unique_id, bp->address);
return ERROR_OK;
}
@@ -1117,7 +1119,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
{
int error = ERROR_OK;
struct x86_32_common *x86_32 = target_to_x86_32(t);
- LOG_DEBUG("type=%d, addr=0x%08" PRIx32, bp->type, bp->address);
+ LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
if (bp->set) {
LOG_ERROR("breakpoint already set");
return error;
@@ -1125,7 +1127,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
if (bp->type == BKPT_HARD) {
error = set_hwbp(t, bp);
if (error != ERROR_OK) {
- LOG_ERROR("%s error setting hardware breakpoint at 0x%08" PRIx32,
+ LOG_ERROR("%s error setting hardware breakpoint at " TARGET_ADDR_FMT,
__func__, bp->address);
return error;
}
@@ -1133,7 +1135,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
if (x86_32->sw_bpts_supported(t)) {
error = set_swbp(t, bp);
if (error != ERROR_OK) {
- LOG_ERROR("%s error setting software breakpoint at 0x%08" PRIx32,
+ LOG_ERROR("%s error setting software breakpoint at " TARGET_ADDR_FMT,
__func__, bp->address);
return error;
}
@@ -1148,7 +1150,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
static int unset_breakpoint(struct target *t, struct breakpoint *bp)
{
- LOG_DEBUG("type=%d, addr=0x%08" PRIx32, bp->type, bp->address);
+ LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
if (!bp->set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
@@ -1156,13 +1158,13 @@ static int unset_breakpoint(struct target *t, struct breakpoint *bp)
if (bp->type == BKPT_HARD) {
if (unset_hwbp(t, bp) != ERROR_OK) {
- LOG_ERROR("%s error removing hardware breakpoint at 0x%08" PRIx32,
+ LOG_ERROR("%s error removing hardware breakpoint at " TARGET_ADDR_FMT,
__func__, bp->address);
return ERROR_FAIL;
}
} else {
if (unset_swbp(t, bp) != ERROR_OK) {
- LOG_ERROR("%s error removing software breakpoint at 0x%08" PRIx32,
+ LOG_ERROR("%s error removing software breakpoint at " TARGET_ADDR_FMT,
__func__, bp->address);
return ERROR_FAIL;
}
@@ -1176,7 +1178,7 @@ static int set_watchpoint(struct target *t, struct watchpoint *wp)
struct x86_32_common *x86_32 = target_to_x86_32(t);
struct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;
int wp_num = 0;
- LOG_DEBUG("type=%d, addr=0x%08" PRIx32, wp->rw, wp->address);
+ LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, wp->rw, wp->address);
if (wp->set) {
LOG_ERROR("%s watchpoint already set", __func__);
@@ -1221,7 +1223,7 @@ static int set_watchpoint(struct target *t, struct watchpoint *wp)
wp->set = wp_num + 1;
debug_reg_list[wp_num].used = 1;
debug_reg_list[wp_num].bp_value = wp->address;
- LOG_USER("'%s' watchpoint %d set at 0x%08" PRIx32 " with length %" PRIu32 " (hwreg=%d)",
+ LOG_USER("'%s' watchpoint %d set at " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)",
wp->rw == WPT_READ ? "read" : wp->rw == WPT_WRITE ?
"write" : wp->rw == WPT_ACCESS ? "access" : "?",
wp->unique_id, wp->address, wp->length, wp_num);
@@ -1232,7 +1234,7 @@ static int unset_watchpoint(struct target *t, struct watchpoint *wp)
{
struct x86_32_common *x86_32 = target_to_x86_32(t);
struct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;
- LOG_DEBUG("type=%d, addr=0x%08" PRIx32, wp->rw, wp->address);
+ LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, wp->rw, wp->address);
if (!wp->set) {
LOG_WARNING("watchpoint not set");
return ERROR_OK;
@@ -1250,7 +1252,7 @@ static int unset_watchpoint(struct target *t, struct watchpoint *wp)
debug_reg_list[wp_num].bp_value = 0;
wp->set = 0;
- LOG_USER("'%s' watchpoint %d removed from 0x%08" PRIx32 " with length %" PRIu32 " (hwreg=%d)",
+ LOG_USER("'%s' watchpoint %d removed from " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)",
wp->rw == WPT_READ ? "read" : wp->rw == WPT_WRITE ?
"write" : wp->rw == WPT_ACCESS ? "access" : "?",
wp->unique_id, wp->address, wp->length, wp_num);
diff --git a/src/target/x86_32_common.h b/src/target/x86_32_common.h
index af57a5f7e..0aaa963d7 100644
--- a/src/target/x86_32_common.h
+++ b/src/target/x86_32_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2013 Intel Corporation.
+ * Copyright(c) 2013-2016 Intel Corporation.
*
* Adrian Burns (adrian.burns@intel.com)
* Thomas Faust (thomas.faust@intel.com)
@@ -18,8 +18,7 @@
* 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., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*
* Contact Information:
* Intel Corporation
@@ -30,8 +29,8 @@
* This is the interface to the x86 32 bit memory and breakpoint operations.
*/
-#ifndef X86_32_COMMON_H
-#define X86_32_COMMON_H
+#ifndef OPENOCD_TARGET_X86_32_COMMON_H
+#define OPENOCD_TARGET_X86_32_COMMON_H
#include
#include
@@ -196,6 +195,11 @@ enum {
WBINVD,
};
+enum x86_core_type {
+ LMT1,
+ LMT3_5
+};
+
struct swbp_mem_patch {
uint8_t orig_byte;
uint32_t swbp_unique_id;
@@ -209,6 +213,7 @@ struct swbp_mem_patch {
struct x86_32_common {
uint32_t common_magic;
void *arch_info;
+ enum x86_core_type core_type;
struct reg_cache *cache;
struct jtag_tap *curr_tap;
uint32_t stored_pc;
@@ -304,14 +309,14 @@ int x86_32_get_gdb_reg_list(struct target *t,
int x86_32_common_init_arch_info(struct target *target,
struct x86_32_common *x86_32);
int x86_32_common_mmu(struct target *t, int *enabled);
-int x86_32_common_virt2phys(struct target *t, uint32_t address, uint32_t *physical);
-int x86_32_common_read_phys_mem(struct target *t, uint32_t phys_address,
+int x86_32_common_virt2phys(struct target *t, target_addr_t address, target_addr_t *physical);
+int x86_32_common_read_phys_mem(struct target *t, target_addr_t phys_address,
uint32_t size, uint32_t count, uint8_t *buffer);
-int x86_32_common_write_phys_mem(struct target *t, uint32_t phys_address,
+int x86_32_common_write_phys_mem(struct target *t, target_addr_t phys_address,
uint32_t size, uint32_t count, const uint8_t *buffer);
-int x86_32_common_read_memory(struct target *t, uint32_t addr,
+int x86_32_common_read_memory(struct target *t, target_addr_t addr,
uint32_t size, uint32_t count, uint8_t *buf);
-int x86_32_common_write_memory(struct target *t, uint32_t addr,
+int x86_32_common_write_memory(struct target *t, target_addr_t addr,
uint32_t size, uint32_t count, const uint8_t *buf);
int x86_32_common_read_io(struct target *t, uint32_t addr,
uint32_t size, uint8_t *buf);
@@ -322,4 +327,4 @@ int x86_32_common_remove_breakpoint(struct target *t, struct breakpoint *bp);
int x86_32_common_add_watchpoint(struct target *t, struct watchpoint *wp);
int x86_32_common_remove_watchpoint(struct target *t, struct watchpoint *wp);
-#endif /* X86_32_COMMON_H */
+#endif /* OPENOCD_TARGET_X86_32_COMMON_H */
diff --git a/src/target/xscale.c b/src/target/xscale.c
index 82e41600e..8fe8a2cb9 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -19,9 +19,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -61,7 +59,7 @@
/* forward declarations */
static int xscale_resume(struct target *, int current,
- uint32_t address, int handle_breakpoints, int debug_execution);
+ target_addr_t address, int handle_breakpoints, int debug_execution);
static int xscale_debug_entry(struct target *);
static int xscale_restore_banked(struct target *);
static int xscale_get_reg(struct reg *reg);
@@ -75,7 +73,7 @@ static int xscale_read_trace(struct target *);
* mini-ICache, which is 2K of code writable only via JTAG.
*/
static const uint8_t xscale_debug_handler[] = {
-#include "xscale_debug.inc"
+#include "../../contrib/loaders/debug/xscale/debug_handler.inc"
};
static const char *const xscale_reg_list[] = {
@@ -1122,7 +1120,7 @@ static void xscale_free_trace_data(struct xscale_common *xscale)
}
static int xscale_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints, int debug_execution)
{
struct xscale_common *xscale = target_to_xscale(target);
struct arm *arm = &xscale->arm;
@@ -1167,7 +1165,8 @@ static int xscale_resume(struct target *target, int current,
enum trace_mode saved_trace_mode;
/* there's a breakpoint at the current PC, we have to step over it */
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+ LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT "",
+ breakpoint->address);
xscale_unset_breakpoint(target, breakpoint);
/* calculate PC of next instruction */
@@ -1224,7 +1223,8 @@ static int xscale_resume(struct target *target, int current,
LOG_DEBUG("disable single-step");
xscale_disable_single_step(target);
- LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+ LOG_DEBUG("set breakpoint at " TARGET_ADDR_FMT "",
+ breakpoint->address);
xscale_set_breakpoint(target, breakpoint);
}
}
@@ -1386,7 +1386,7 @@ static int xscale_step_inner(struct target *target, int current,
}
static int xscale_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
struct arm *arm = target_to_arm(target);
struct breakpoint *breakpoint = NULL;
@@ -1446,6 +1446,13 @@ static int xscale_assert_reset(struct target *target)
{
struct xscale_common *xscale = target_to_xscale(target);
+ /* TODO: apply hw reset signal in not examined state */
+ if (!(target_was_examined(target))) {
+ LOG_WARNING("Reset is not asserted because the target is not examined.");
+ LOG_WARNING("Use a reset button or power cycle the target.");
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
+
LOG_DEBUG("target->state: %s",
target_state_name(target));
@@ -1573,7 +1580,6 @@ static int xscale_deassert_reset(struct target *target)
address += buf_cnt;
}
- ;
retval = xscale_load_ic(target, 0x0,
xscale->low_vectors);
@@ -1774,7 +1780,7 @@ static int xscale_restore_banked(struct target *target)
return ERROR_OK;
}
-static int xscale_read_memory(struct target *target, uint32_t address,
+static int xscale_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct xscale_common *xscale = target_to_xscale(target);
@@ -1782,7 +1788,7 @@ static int xscale_read_memory(struct target *target, uint32_t address,
uint32_t i;
int retval;
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
address,
size,
count);
@@ -1860,7 +1866,7 @@ static int xscale_read_memory(struct target *target, uint32_t address,
return ERROR_OK;
}
-static int xscale_read_phys_memory(struct target *target, uint32_t address,
+static int xscale_read_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct xscale_common *xscale = target_to_xscale(target);
@@ -1875,13 +1881,13 @@ static int xscale_read_phys_memory(struct target *target, uint32_t address,
return ERROR_FAIL;
}
-static int xscale_write_memory(struct target *target, uint32_t address,
+static int xscale_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct xscale_common *xscale = target_to_xscale(target);
int retval;
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
address,
size,
count);
@@ -1959,7 +1965,7 @@ static int xscale_write_memory(struct target *target, uint32_t address,
return ERROR_OK;
}
-static int xscale_write_phys_memory(struct target *target, uint32_t address,
+static int xscale_write_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct xscale_common *xscale = target_to_xscale(target);
@@ -2663,7 +2669,7 @@ static int xscale_analyze_trace(struct target *target, struct command_context *c
struct xscale_common *xscale = target_to_xscale(target);
struct xscale_trace_data *trace_data = xscale->trace.data;
int i, retval;
- uint32_t breakpoint_pc;
+ uint32_t breakpoint_pc = 0;
struct arm_instruction instruction;
uint32_t current_pc = 0;/* initialized when address determined */
@@ -3089,7 +3095,7 @@ COMMAND_HANDLER(xscale_handle_cache_info_command)
}
static int xscale_virt2phys(struct target *target,
- uint32_t virtual, uint32_t *physical)
+ target_addr_t virtual, target_addr_t *physical)
{
struct xscale_common *xscale = target_to_xscale(target);
uint32_t cb;
@@ -3426,7 +3432,7 @@ COMMAND_HANDLER(xscale_handle_dump_trace_command)
struct target *target = get_current_target(CMD_CTX);
struct xscale_common *xscale = target_to_xscale(target);
struct xscale_trace_data *trace_data;
- struct fileio file;
+ struct fileio *file;
int retval;
retval = xscale_verify_pointer(CMD_CTX, xscale);
@@ -3454,19 +3460,19 @@ COMMAND_HANDLER(xscale_handle_dump_trace_command)
while (trace_data) {
int i;
- fileio_write_u32(&file, trace_data->chkpt0);
- fileio_write_u32(&file, trace_data->chkpt1);
- fileio_write_u32(&file, trace_data->last_instruction);
- fileio_write_u32(&file, trace_data->depth);
+ fileio_write_u32(file, trace_data->chkpt0);
+ fileio_write_u32(file, trace_data->chkpt1);
+ fileio_write_u32(file, trace_data->last_instruction);
+ fileio_write_u32(file, trace_data->depth);
for (i = 0; i < trace_data->depth; i++)
- fileio_write_u32(&file, trace_data->entries[i].data |
+ fileio_write_u32(file, trace_data->entries[i].data |
((trace_data->entries[i].type & 0xffff) << 16));
trace_data = trace_data->next;
}
- fileio_close(&file);
+ fileio_close(file);
return ERROR_OK;
}
diff --git a/src/target/xscale.h b/src/target/xscale.h
index a71ec3514..a86edb2fb 100644
--- a/src/target/xscale.h
+++ b/src/target/xscale.h
@@ -16,13 +16,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef XSCALE_H
-#define XSCALE_H
+#ifndef OPENOCD_TARGET_XSCALE_H
+#define OPENOCD_TARGET_XSCALE_H
#include "arm.h"
#include "armv4_5_mmu.h"
@@ -187,4 +185,4 @@ enum {
#define DCSR_TRAP_MASK \
(DCSR_TF | DCSR_TI | DCSR_TD | DCSR_TA | DCSR_TS | DCSR_TU | DCSR_TR)
-#endif /* XSCALE_H */
+#endif /* OPENOCD_TARGET_XSCALE_H */
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 7c6224a48..9076d9b68 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -1,11 +1,4 @@
-include $(top_srcdir)/common.mk
-
-#METASOURCES = AUTO
-noinst_LTLIBRARIES = libtransport.la
-libtransport_la_SOURCES = \
- transport.c
-
-noinst_HEADERS = \
- transport.h
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+noinst_LTLIBRARIES += %D%/libtransport.la
+%C%_libtransport_la_SOURCES = \
+ %D%/transport.c \
+ %D%/transport.h
diff --git a/src/transport/transport.c b/src/transport/transport.c
index c973e1c3a..708594712 100644
--- a/src/transport/transport.c
+++ b/src/transport/transport.c
@@ -12,8 +12,7 @@
* GNU 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*/
#ifdef HAVE_CONFIG_H
diff --git a/src/transport/transport.h b/src/transport/transport.h
index daf49604c..6c57067a3 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -13,12 +13,11 @@
* GNU 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see .
*/
-#ifndef TRANSPORT_H
-#define TRANSPORT_H
+#ifndef OPENOCD_TRANSPORT_TRANSPORT_H
+#define OPENOCD_TRANSPORT_TRANSPORT_H
#include "helper/command.h"
@@ -91,4 +90,4 @@ int allow_transports(struct command_context *ctx, const char * const *vector);
bool transports_are_declared(void);
-#endif
+#endif /* OPENOCD_TRANSPORT_TRANSPORT_H */
diff --git a/src/xsvf/Makefile.am b/src/xsvf/Makefile.am
index 1b9cfab00..61e6fb920 100644
--- a/src/xsvf/Makefile.am
+++ b/src/xsvf/Makefile.am
@@ -1,8 +1,2 @@
-include $(top_srcdir)/common.mk
-
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libxsvf.la
-noinst_HEADERS = xsvf.h
-libxsvf_la_SOURCES = xsvf.c
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+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 a6de82397..63c891511 100644
--- a/src/xsvf/xsvf.c
+++ b/src/xsvf/xsvf.c
@@ -22,9 +22,7 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
/* The specification for SVF is available here:
diff --git a/src/xsvf/xsvf.h b/src/xsvf/xsvf.h
index 3f35aea52..aa0f4f040 100644
--- a/src/xsvf/xsvf.h
+++ b/src/xsvf/xsvf.h
@@ -13,13 +13,11 @@
* GNU 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
-#ifndef XSVF_H
-#define XSVF_H
+#ifndef OPENOCD_XSVF_XSVF_H
+#define OPENOCD_XSVF_XSVF_H
#include
@@ -28,4 +26,4 @@ int xsvf_register_commands(struct command_context *cmd_ctx);
#define ERROR_XSVF_EOF (-200)
#define ERROR_XSVF_FAILED (-201)
-#endif /* XSVF_H */
+#endif /* OPENOCD_XSVF_XSVF_H */